The FuelPHP ArrValidator package simplifies and automatizes the validation of arrays against simple rules. If an array's node doesn't comply with the rules, then a default value is set to that item.
- Latest Version: v1.0
- Released:
- Author: Axel Pardemann (http://axelitus.mx)
- FuelPHP Framework version v1.1
- Axel Pardemann - Lead Developer (http://dev.blogs.axelitus.mx)
You can find the GitHub Repository on https://github.com/axelitus/fuel-pkg-arrvalidator
- For Issues you can use GitHub's Issue Tracker
- If you have suggestions you can send an email to dev [at] axelitus [dot] mx
- If you have any fixes or new features you'd like to share please send them as Pull Requests on GitHub
The package installation is very easy. You can choose one of two methods described here.
Just download the source code located at axelitus' FuelPHP ArrValidator package at GitHub and place it in a folder named arrvalidator
inside the packages folder in FuelPHP.
Alternatively you can use git to clone the repository directly (this will make your life easier when updating the package):
git clone [email protected]:axelitus/fuel-pkg-arrvalidator arrvalidator
Waiting for release v1.1 to complete this...
The first thing you should do is load the package. This can be achieved manually by calling:
\Package::load('arrvalidator');
To load it automatically you should edit your app's config file (config.php
). Look for the always_load
key and under packages
and set an entry with the 'arrvalidator' string. It should look similar to this:
...
'always_load' => array(
'packages' => array(
'arrvalidator'
),
...
The configuration is done using the file arrvalidator.php
in the config directory (you are encouraged to copy this file to your app/config
folder and edit that file instead).
An example of the contents of a arrvalidator.php
config file:
return array(
'groups' => array(
'connections' => 'arrvalidator/connections/db, arrvalidator/connections/ldap',
'webservices' => array(
'arrvalidator/ws/google',
'arrvalidator/ws/amazon'
)
),
'auto_load' => array(
'validators' => array(
'arrvalidator/api/twitter',
'arrvalidator/api/facebook'
),
'groups' => array(
'connections',
'webservices'
)
)
);
The options in the config array are explained as follows:
You can define groups of validator description files. The group should be named and it can accept an array of strings or a comma-separated string of array validator description files.
Note: the validator description files are relative to the main config folder.
This sections holds what validators and groups of validators will be automatically loaded upon class initialization.
The validators that will be auto-loaded should be defined here. Every item (string) in the array is a validator description file to be loaded.
Note: the validator description files are relative to the main config folder.
The groups of validators that will be auto-loaded should be defined here. Every item (string) in the array is the name of a group of validators which has been defined in the groups
config entry.
The validator description files are config files that describe a validator that can be loaded from it. This files can contain a single validator description or multiple validators description. There are some rules/structure that must be followed:
This is the most common form of validator description, inside such a file there's only one description and it looks like this:
return array(
'name' => 'ldap',
'nodes' => array(
'connection.server' => array(
'default' => 'defaultserver.mydomain.com',
'rules' => array(
array(
'operator' => 'is_string'
),
array(
'operator' => '!empty'
)
)
),
'connection.port' => array(
'default' => 389,
'rules' => array(
array(
'operator' => 'is_numeric',
),
array(
'operator' => 'between',
'operand' => array(1, 65535)
)
)
)
)
);
For an array to be identified as a validator description (and to attempt to load it) there must exist one of the two sub-items. If one is found and the other not, then the non-existent one will be set to it's own default value.
This is the name of the validator. If you want a named validator (other than an empty string which will overwrite previously loaded non-named validator) then this must exist.
This are the nodes that belong to the validator to which the rules will be applied to. This are named arrays in which the key is corresponds to the key to be verified in the array that is validated.
Please refer to Node array structure.
The structure of the array that represents a node is as follows:
array(
'default' => mixed,
'rules' => array(
)
);
This is the default value that the item will take in the array that is being validated if the rules do not comply.
This specifies the rules to be applied to the item in the array that is being validated.
Please refer to Rule array structure.
The structure of the array that represents a rule is as follows:
array(
'operator' => string,
'operand' => mixed
);
The operator for this rule that will be applied to the value of the item in the array that is being validated. If this entry does not exist, an InvalidArgumentException
will be thrown. The following are the only valid operators (all of them are defined as constants in the class ArrValidator_Operator
, this list is to be read as [const_name] -> actual_value
):
- one-operand operators
- [IS_SET] -> 'isset'
- [NOT_IS_SET] -> '!isset'
- [IS_NULL] -> 'is_null'
- [NOT_IS_NULL] -> '!isnull'
- [IS_EMPTY] -> 'empty'
- [NOT_IS_EMPTY] -> '!empty'
- [IS_ARRAY] -> 'is_array'
- [NOT_IS_ARRAY] -> '!is_array'
- [IS_NUMERIC] -> 'is_numeric'
- [NOT_IS_NUMERIC] -> '!is_numeric'
- [IS_STRING] -> 'is_string'
- [NOT_IS_STRING] -> '!is_string'
- [IS_BOOL] -> 'is_bool'
- [NOT_IS_BOOL] -> '!is_bool'
- [IS_INT] -> 'is_int'
- [NOT_IS_INT] -> '!is_int'
- [IS_FLOAT] -> 'is_float'
- [NOT_IS_FLOAT] -> '!is_float'
- [IS_DOUBLE] -> 'is_double'
- [NOT_IS_DOUBLE] -> '!is_double'
- [IS_OBJECT] -> 'is_object'
- [NOT_IS_OBJECT] -> '!is_object'
- [IS_RESOURCE] -> 'is_resource'
- [NOT_IS_RESOURCE] -> '!is_resource'
- two-operand operators
- [EQUAL] -> '=='
- [IDENTICAL] -> '==='
- [NOT_EQUAL] -> '!='
- [NOT_EQUAL_ALIAS] -> '<>'
- [NOT_IDENTICAL] -> '==='
- [LESS_THAN] -> '<'
- [GREATER_THAN] -> '>'
- [LESS_THAN_OR_EQUAL] -> '<='
- [GREATER_THAN_OR_EQUAL] -> '>='
- [INSTANCE_OF] -> 'instanceof'
- [NOT_INSTANCE_OF] -> '!instanceof'
- [REGEX] -> 'regex'
- three-operand operators
- [BETWEEN] -> '<==>'
- [BETWEEN_ALIAS] -> 'between'
- [NOT_BETWEEN] -> '>==<'
- [NOT_BETWEEN_ALIAS] -> '!between'
The operand count needed for the operator to work includes the main operand (which is the actual value from the array that is being validated).
The additional operand(s) needed for the rule to be applied. From the list above, for the two-operand and three-operand operators this entry is needed. When just one operand is needed the operand value is to be given, if more than one operand is needed an array of operand values should be given.
A multiple validators description file follows the same rules as the single validator description file but instead of having only one description, it has an array of validator descriptions.
A multiple validator description file looks like this:
return array(
array(
'name' => 'ldap',
'nodes' => array(
'connection.server' => array(
'default' => 'defaultserver.mydomain.com',
'rules' => array(
array(
'operator' => 'is_string'
),
array(
'operator' => '!empty'
)
)
),
'connection.port' => array(
'default' => 389,
'rules' => array(
array(
'operator' => 'is_numeric',
),
array(
'operator' => 'between',
'operand' => array(1, 65535)
)
)
)
)
),
array(
'name' => 'db',
'nodes' => array(
'connection.server' => array(
'default' => 'dbserver.mydomain.com',
'rules' => array(
array(
'operator' => 'is_string'
),
array(
'operator' => '!empty'
)
)
),
'connection.port' => array(
'default' => 3366,
'rules' => array(
array(
'operator' => 'is_numeric',
),
array(
'operator' => 'between',
'operand' => array(1, 65535)
)
)
)
)
)
);
The most common methods are described here. Please refer to the doc-blocks in the actual code.
This is the main ArrValidator package class.
Contains a string for the current version of the package.
Description: Forges a new instance of ArrValidator
or gets the existing one. If the $overwrite
flag is set to true
, then the instance will be overwritten.
Static: Yes
Return: ArrValidator
the validator instance
$validator = ArrValidator::forge('FirstValidator');
// $validator2 will get the previously created $validator
$validator2 = ArrValidator::forge('FirstValidator');
// $validator3 will get a new validator named FirstValidator.
$validator3 = ArrValidator::forge('FirstValidator', true);
This is the status of variables after all three calls:
($validator = $validator2) != $validator3
The validator named FirstValidator is no longer the instance that $variable
and $variable2
hold, it was overwritten inside the ArrValidator
instances array with the last method call.
Description: Verifies if the named ArrValidator
instance already exists.
Static: Yes
Return: bool
if(ArrValidator::exists('FirstValidator'))
{
// do something if the validator already exists
}
Description: Gets an instance by name. If no instance is found by the given name, a new one will be forged.
Static: Yes
Return: ArrValidator
the validator instance
// Gets the previously created validator
$validator = ArrValidator::instance('FirstValidator');
// Gets a newly created validator
$validator2 = ArrValidator::instance('SecondValidator');
Description: Removes a loaded instance.
Static: Yes
Return: void
ArrValidator::remove('SecondValidator');
Description: Gets all the validator instances.
Static: Yes
Return: array
of ArrValidator
objects
$validators = ArrValidator::instances();
foreach($validators as $validator)
{
// do something with each validator
}
Description: Deletes all loaded instances.
Static: Yes
Return: void
ArrValidator::empty_instances();
Description: Forges an instance from an array representation. The name
item should not be ommited using this method or else you'll get a validator with an empty string as a name (and so it is identified by it in the instances array).
Please refer to the section Single Validator Description File where the validator array structure is described.
Static: Yes
Return: ArrValidator
the validator instance
$array = array(
'name' => 'ldap',
'nodes' => array(
'connection.server' => array(
'default' => 'defaultserver.mydomain.com',
'rules' => array(
array(
'operator' => 'is_string'
),
array(
'operator' => '!empty'
)
)
),
'connection.port' => array(
'default' => 389,
'rules' => array(
array(
'operator' => 'is_numeric',
),
array(
'operator' => 'between',
'operand' => array(1, 65535)
)
)
)
)
);
$validator = ArrValidator::from_array($array);
Description: Gets an array of all loaded ArrValidator
instances as their array structures.
Static: Yes
Return: array
of ArrValidator
object array structures
ArrValidator::forge('FirstValidator');
ArrValidator::forge('SecondValidator');
$array = ArrValidator::all_as_array();
$array_ommited = ArrValidator::all_as_array(true);
The variable $array
will contain:
array(
'FirstValidator' => array(
'name' => 'FirstValidator',
'nodes' => array()
),
'SecondValidator' => array(
'name' => 'SecondValidator',
'nodes' => array()
)
);
wheras the variable $array_ommited
will contain:
array(
'FirstValidator' => array(
'nodes' => array()
),
'SecondValidator' => array(
'nodes' => array()
)
);
Description: Loads multiple instances from an array of validator array structures. If the flag $empty_first
is set to true
, then the instances array will be emptied prior to the load process.
Note: The name
item inside a validator takes precedence to the validator's key name.
Static: Yes
Return: void
$mult_validators = array(
'FirstValidator' => array(
'name' => 'FirstValidatorPrecedence',
'nodes' => array()
),
'SecondValidator' => array(
'nodes' => array()
)
);
ArrValidator::multiple_from_array($mult_validators);
echo '<pre>';
var_dump(ArrValidator::instances());
echo '</pre>';
will output something like this:
array(2) {
["FirstValidatorPrecedence"]=>
object(ArrValidator\ArrValidator)#14 (2) {
["_name":protected]=>
string(24) "FirstValidatorPrecedence"
["_nodes":protected]=>
array(0) {
}
}
["SecondValidator"]=>
object(ArrValidator\ArrValidator)#15 (2) {
["_name":protected]=>
string(15) "SecondValidator"
["_nodes":protected]=>
array(0) {
}
}
}
Description: Loads a single or multiple validators from a file.
Please refer to the section Single Validator Description File where the validator array structure in files usage is described.
Static: Yes
Return: bool
ArrValidator::load_from_file('arrvalidator/ws/google');
ArrValidator::load_from_file('arrvalidator/ws/amazon', true);
Description: Loads a validators from a group (from the configuration file).
Static: Yes
Return: bool
ArrValidator::load_from_group('connections');
ArrValidator::load_from_group('webservices', true);
Description: Gets the validator's name.
Static: No
Return: string
$validator = ArrValidator::forge('FirstValidator');
echo $validator->get_name();
Description: Gets the validator's nodes.
Static: No
Return: array
of ArrValidator_Node
objects
$validator = ArrValidator::instance('GoogleWebService');
foreach($validator->get_nodes() as $node)
{
// do something with each validator node
}
Description: Adds a node if it does not exist. If the node already exists it will be returned. If the $overwrite
flag is set to true
, then the existing node will be overwritten.
Static: No
Return: ArrValidator_Node
the added or previously existing node
$validator = ArrValidator::forge('FirstValidator');
$node = $validator->add_node('connection.port', 389);
$rules = array(
array(
'operator' => 'is_string'
),
array(
'operator' => '!empty'
)
);
$node2 = $validator->add_node('connection.server', 'defaultserver.mydomain.com', true, $rules);
Description: Adds a node from an object if it does not exist. If the node already exists it will be returned. If the $overwrite
flag is set to true
, then the existing node will be overwritten.
Static: No
Return: ArrValidator_Node
the added or previously existing node
$validator = ArrValidator::forge('FirstValidator');
$node = $validator->add_node_object('connection.port', ArrValidator_Node::forge(389));
$node2_obj = ArrValidator_Node::forge('defaultserver.mydomain.com');
$rules = array(
array(
'operator' => 'is_string'
),
array(
'operator' => '!empty'
)
);
$node2_obj->add_rules($rules);
$node2 = $validator->add_node_object('connection.server', $node2_obj, true);
Description: Adds a node from an array if it does not exist. If the node already exists it will be returned. If the $overwrite
flag is set to true
, then the existing node will be overwritten.
Static: No
Return: ArrValidator_Node
the added or previously existing node
$validator = ArrValidator::forge('FirstValidator');
$node_arr = array(
'default' => 389,
'rules' => array(
)
);
$node = $validator->add_node_array('connection.port', $node_arr);
$node2_arr = array(
'default' => 'defaultserver.mydomain.com',
'rules' => array(
array(
'operator' => 'is_string'
),
array(
'operator' => '!empty'
),
),
);
$node2 = $validator->add_node_array('connection.server', $node2_arr, true);
Description: Verifies if the node already exists in the validator. This only checks if the key exists in the node's array.
Static: No
Return: bool
if(!$validator->has_node('connection.server'))
{
$rules = array(
array(
'operator' => 'is_string'
),
array(
'operator' => '!empty'
)
);
$validator->add_node('connection.server', 'defaultserver.mydomain.com')->add_rules($rules);
}
Description: Removes a node from the validator.
Static: No
Return: ArrValidator
this instance for chaining
$validator->remove_node('connection.server')->remove_node('connection.port');
Description: Adds an array of nodes to the validator. The array can contain ArrValidator_Node
objects or ArrValidator_Node
array structures. The nodes must be identified by a key name.
Static: No
Return: Arr_Validator
this instance for chaining
$validator = ArrValidator::forge('FirstValidator');
$nodes = array(
'connection.port' => array(
'default' => 389,
'rules' => array (
)
),
'connection.server' => array(
'default' => 'defaultserver.mydomain.com',
'rules' => array(
array(
'operator' => 'is_string',
),
array (
'operator' => '!empty',
)
)
)
);
$validator->add_nodes($nodes);
Description: Empties the validator node's array.
Static: No
Return: Arr_Validator
this instance for chaining
$validator->empty_nodes();
Description: Gets the instance's array structure.
Static: No
Return: array
the validator's array structure
$array = $validator->as_array();
$array2 = $validator->as_array(true);
The variable $array
will have something like this:
array(2) {
["name"]=>
string(14) "FirstValidator"
["nodes"]=>
array(2) {
["connection.port"]=>
array(2) {
["default"]=>
int(389)
["rules"]=>
array(0) {
}
}
["connection.server"]=>
array(2) {
["default"]=>
string(26) "defaultserver.mydomain.com"
["rules"]=>
array(2) {
[0]=>
array(1) {
["operator"]=>
string(9) "is_string"
}
[1]=>
array(1) {
["operator"]=>
string(6) "!empty"
}
}
}
}
}
The variable $array2
will have something like this:
array(2) {
["nodes"]=>
array(2) {
["connection.port"]=>
array(2) {
["default"]=>
int(389)
["rules"]=>
array(0) {
}
}
["connection.server"]=>
array(2) {
["default"]=>
string(26) "defaultserver.mydomain.com"
["rules"]=>
array(2) {
[0]=>
array(1) {
["operator"]=>
string(9) "is_string"
}
[1]=>
array(1) {
["operator"]=>
string(6) "!empty"
}
}
}
}
}
Description: Runs the validator. Every node will be checked against the given array and if the node's validation fails the node's default value will be set into the array. If the item is not found and the $force_item_set
flag is set to true
then the item will be created with the default value.
Static: No
Return: void
// Loads a validator with two nodes
// Node: connection.server; Rules: is string and not empty
// Node: connection.port; Rules: is_numeric between 1 and 5000
$validator = ArrValidator::load_from_file('arrvalidator/connections/db')
// Test case 1
$array = array(
'connection' => array(
'server' => '',
'port' => 0
)
);
$validator->run($array);
// Test case 2
$array2 = array(
'connection' => array(
'server' => 'configured_server.mydomain.com'
)
);
$validator->run($array2);
// Test case 3
$array3 = array(
'connection' => array(
'server' => 'default_server.mydomain.com',
'port' => 0
)
);
$validator->run($array3);
// Test case 4
$array4 = array(
'connection' => array(
'server' => 'default_server.mydomain.com',
'port' => '2000'
)
);
$validator->run($array4);
// Test case 5
$array5 = array(
'connection' => array(
'server' => 'default_server.mydomain.com',
'port' => 2000
)
);
$validator->run($array5);
For test case 1 the variable $array
will contain this:
array(1) {
["connection"]=>
array(2) {
["server"]=>
string(26) "defaultserver.mydomain.com"
["port"]=>
int(389)
}
}
For test case 2 the variable $array2
will contain this:
array(1) {
["connection"]=>
array(2) {
["server"]=>
string(30) "configured_server.mydomain.com"
["port"]=>
int(389)
}
}
For test case 3 the variable $array3
will contain this:
array(1) {
["connection"]=>
array(2) {
["server"]=>
string(27) "default_server.mydomain.com"
["port"]=>
int(389)
}
}
For test case 4 the variable $array4
will contain this:
array(1) {
["connection"]=>
array(2) {
["server"]=>
string(27) "default_server.mydomain.com"
["port"]=>
string(4) "2000"
}
}
For test case 5 the variable $array5
will contain this:
array(1) {
["connection"]=>
array(2) {
["server"]=>
string(27) "default_server.mydomain.com"
["port"]=>
int(2000)
}
}
To be written...
The first version has the basic functionality one would expect. New features will be evaluated and added as soon as possible. Please feel free to send feature requests through the Github repository.
Firstly I would like to thank the Fuel Development Team for their magnificent framework and spent time for making our lives easier. Great work, keep it up!
Special thanks for he ones that helped by commenting, discussing, suggesting, testing, brainstorming (if I missed someone please let me know, if you don't want to appear in this list also let me know):