Symfony validation - only part of array - php

I need help with symfony validator. It is possible validate only specific values in array? For example I have array:
'0' => [
'interestidKey' => true,
'anotherInterestedKey' => 'foo'
],
'error' => [
'errorMsg => 'not interest for me'
]
I need to validate this array with validator mainly value 0. I need know if array contains '0' key and inside if is key interestidKey with boolean value. I always use Collection for array but it not work in this case because ofc shows me an error that error does not contain interestidKey.
How can I fix this?

I'm not sure you will be able to do what you want with the shipped out of the box constraints. But you should be able to do what you want by writing your own: https://symfony.com/doc/current/validation/custom_constraint.html have a look at that and see if it can help you.
if you're validate you could do:
if(array_key_exists(0, $array)) {
if(array_key_exists("interestid", $array[0])) {
return true;
}
} else {
// do the error stuffs
}

You could just build a loop over your array, check for the key and if it is a numeric key (or not the error key) apply your validation to the children. That would look like this:
use Symfony\Component\Validator\Constraints as Assert;
...
$constraint = new Assert\Collection([
'fields' => [
// put any constraints for your objects here, keyed by field name
'interestidKey' => new Assert\Type('bool')
],
'allowExtraFields' => true // remove if you don't want to allow other fields than specified above
]);
$violations = [];
foreach($data as $key => $item) {
if ($key != 'error') {
$violations[$key] = $validator->validate($item, $constraint);
}
}

Related

How to check if NULL value exists in multidimesional array?

I have seen some methods to determine if some value exists in php multidimensional array but I am stuck at simple problem.
I have a following array.
$data = [
['name' => 'sagar', 'address' => 'kathmandu'],
['name' => 'sagar', 'address' => null ]
];
I want to check if null value exists anywhere inside 2 dimensional array and keys can be anything. Is there any builtin function or we have made our own or some methodology to check ?
If you have any idea, it would be extremely helpful.
$hasNull = false;
foreach ($data as $set) {
if ($hasNull = in_array(null, $set, true)) {
break;
}
}

how to make an array follow a strict form? [duplicate]

Is there a function out there to make sure that any given array conforms to a particular structure? What I mean is that is has particular key names, perhaps particular types for values, and whatever nested structure.
Right now I have a place where I want to make sure that the array getting past has certain keys, a couple holding a certain data type, and one sub-array with particular key names. I've done a lot of run-around because I was passing malformed arrays to it, and finally I'm at the point where I have a bunch of
if ( ! isset($arr['key1']) ) { .... }
if ( ! isset($arr['key2']) ) { .... }
if ( ! isset($arr['key3']) ) { .... }
I would have saved a lot of time and consternation if I could have checked that the array conformed to a particular structure beforehand. Ideally something like
$arrModel = array(
'key1' => NULL ,
'key2' => int ,
'key3' => array(
'key1' => NULL ,
'key2' => NULL ,
),
);
if ( ! validate_array( $arrModel, $arrCandidate ) ) { ... }
So, the question I'm asking is, does this already exists, or do I write this myself?
Convert array to JSON:
http://us.php.net/manual/en/function.json-encode.php
Then check against a JSON Schema:
http://json-schema.org/
http://jsonschemaphpv.sourceforge.net/
It doesn't exist built in.
Maybe try something like (untested):
array_diff(array_merge_recursive($arrCandidate, $arrModel), $arrModel)
You can use the Symfony Validation component
Installation:
composer require symfony/validator doctrine/annotations
Usage:
$myArray = [
'name' => ['first_name' => 'foo', 'last_name' => 'bar'],
'email' => 'foo#email.com'
];
$constraints = new Assert\Collection([
'name' => new Assert\Collection([
'first_name' => new Assert\Length(['min' => 101]),
'last_name' => new Assert\Length(['min' => 1]),
]),
'email' => new Assert\Email(),
]);
$validator = Validation::createValidator();
$violations = $validator->validate($myArray, $constraints);
For more details, see How to Validate Raw Values (Scalar Values and Arrays)
accepted answer make diff based on values, since it's about array structure you dont want to diff values. Insted you should use [array_diff_key()][1]
Function alone is not recursive. It will not work out of box on sample array from question.
Edit after years: Got into similar trouble whit recursive array functions, so there is mine array_diff_recursive, this does not solve original question because it compare values as well, but i believe it can be easily modified and someone can find it useful .
function array_diff_recursive(array $array1, array $array2){
return array_replace_recursive(
array_diff_recursive_one_way($array1, $array2),
array_diff_recursive_one_way($array2, $array1)
);
}//end array_diff_recursive()
function array_diff_recursive_one_way(array $array1, array $array2)
{
$ret = array();
foreach ($array1 as $key => $value) {
if (array_key_exists($key, $array2) === TRUE) {
if (is_array($value) === TRUE) {
$recurse = array_diff_recursive_one_way($value, $array2[$key]);
if (count($recurse) > 0) {
$ret[$key] = $recurse;
}
} elseif (in_array($value, $array2) === FALSE) {
$ret[$key] = $value;
}
} elseif (in_array($value, $array2) === FALSE) {
$ret[$key] = $value;
}
}
return $ret;
}//end array_diff_recursive_one_way()```
[1]: http://php.net/manual/en/function.array-diff-key.php
I know this is sort of an old post, sorry if my answer is not approppriate.
I'm in the process of writing a php package that does exactly what you are asking for, it's called Structure.
What you can do with the package is something like:
$arrayCheck = new \Structure\ArrayS();
$arrayCheck->setFormat(array("profile"=>"array"));
if ($arrayCheck->check($myArray)) {
//...
}
You can check it out here: http://github.com/3nr1c/structure
I came across a tool called Matchmaker on GitHub, which looks very comprehensive and has composer support and unit tests:
https://github.com/ptrofimov/matchmaker
You can include it into your project with
composer require ptrofimov/matchmaker.

laravel how to validate array index and values

I am submitting a single dimensional array of values to process on laravel 5.6
quantity[4]:11
quantity[2]:14
I have to validate both the index and the value, index should exits as stocks,id and value must be integer and minimum 1
I tried
public function rules()
{
$rules = [
'quantity.*' => 'exists:stocks,id',
'quantity' => 'required|integer|min:1',
];
return $rules;
}
but its validating only the values not index, please share your thoughts and comments.
I can not see anywhere we can validate array index with default Laravel validation. That why we need to write a custom one.
public function rules()
{
$rules = [
'quantity.*' => 'required|integer|min:1',
'quantity' => [
'required',
'min:1', // make sure the input array is not empty <= edited
'array',
function($attribute, $value, $fail) {
// index arr
$ids = array_keys($value);
// query to check if array keys is not valid
$stockCntWithinArrIDs = StockModelFullNameWhaterver::whereIn('id', $ids)->count();
if ($stockCntWithinArrIDs != count($ids))
return $fail($attribute.' is invalid.'); // -> "quantity is invalid"
}
],
];
return $rules;
}
The main point is compare stock count result when query whereIn (to reduce cost) their id with the array_keys of quantity. Because quantity's index is exists in stocks, $stockCntWithinArrIDs has to equal to count($ids), if not, there is at least one index is not as stocks id.
You can use foreach ($ids) then query the corresponding stock to see if my solution work. But PLEASE DO NOT use that solution on production env. :D
Hope this help!
Edited:
See: https://laravel.com/docs/5.6/validation#custom-validation-rules

Check POST Data - JSON Array

I´m trying to check the data of my JSON file. It works for strings in the json file, but how to handle it with arrays in the array?
What i send:
{
"info" : "test",
"data" : [
{
"startdate": "2018-01-01T10:00:00+0100",
"enddate": "2018-01-01T17:00:00+0100"
}
]
}
What i´ve yet:
$dataReq = array(
'info' => $request->get('info'),
'date' => $request->get('date'), // my array
);
foreach ($dataReq as $a => $value) {
if(empty($value)) {
return new View('The field \''.$a.'\' is required!');
}
}
But the function empty doenst work for arrays so far. It will return false, cause the array is there. How can i check the "startdate" key?
btw: i´m using symfony3(FOSRestBundle), php 7.0
You can check if the value is an array and filter null values from it, then test if it's empty.
$dataReq = array(
'info' => $request->get('info'),
'data' => $request->get('data'), // my array
);
foreach ($dataReq as $a => $value) {
if(is_array($value)) $value = array_filter($value);
if(empty($value)) {
return new View('The field \''.$a.'\' is required!');
}
}
array_filter() function's default behavior is to remove from array all values equal to null, 0, '' or false if no callback is passed.
Note: I assume you wanted to retrieve data and not date.
As commented by LBA, I also suggest to check the Symfony Validation component to deal with that instead.

How can I validate the structure of my PHP arrays?

Is there a function out there to make sure that any given array conforms to a particular structure? What I mean is that is has particular key names, perhaps particular types for values, and whatever nested structure.
Right now I have a place where I want to make sure that the array getting past has certain keys, a couple holding a certain data type, and one sub-array with particular key names. I've done a lot of run-around because I was passing malformed arrays to it, and finally I'm at the point where I have a bunch of
if ( ! isset($arr['key1']) ) { .... }
if ( ! isset($arr['key2']) ) { .... }
if ( ! isset($arr['key3']) ) { .... }
I would have saved a lot of time and consternation if I could have checked that the array conformed to a particular structure beforehand. Ideally something like
$arrModel = array(
'key1' => NULL ,
'key2' => int ,
'key3' => array(
'key1' => NULL ,
'key2' => NULL ,
),
);
if ( ! validate_array( $arrModel, $arrCandidate ) ) { ... }
So, the question I'm asking is, does this already exists, or do I write this myself?
Convert array to JSON:
http://us.php.net/manual/en/function.json-encode.php
Then check against a JSON Schema:
http://json-schema.org/
http://jsonschemaphpv.sourceforge.net/
It doesn't exist built in.
Maybe try something like (untested):
array_diff(array_merge_recursive($arrCandidate, $arrModel), $arrModel)
You can use the Symfony Validation component
Installation:
composer require symfony/validator doctrine/annotations
Usage:
$myArray = [
'name' => ['first_name' => 'foo', 'last_name' => 'bar'],
'email' => 'foo#email.com'
];
$constraints = new Assert\Collection([
'name' => new Assert\Collection([
'first_name' => new Assert\Length(['min' => 101]),
'last_name' => new Assert\Length(['min' => 1]),
]),
'email' => new Assert\Email(),
]);
$validator = Validation::createValidator();
$violations = $validator->validate($myArray, $constraints);
For more details, see How to Validate Raw Values (Scalar Values and Arrays)
accepted answer make diff based on values, since it's about array structure you dont want to diff values. Insted you should use [array_diff_key()][1]
Function alone is not recursive. It will not work out of box on sample array from question.
Edit after years: Got into similar trouble whit recursive array functions, so there is mine array_diff_recursive, this does not solve original question because it compare values as well, but i believe it can be easily modified and someone can find it useful .
function array_diff_recursive(array $array1, array $array2){
return array_replace_recursive(
array_diff_recursive_one_way($array1, $array2),
array_diff_recursive_one_way($array2, $array1)
);
}//end array_diff_recursive()
function array_diff_recursive_one_way(array $array1, array $array2)
{
$ret = array();
foreach ($array1 as $key => $value) {
if (array_key_exists($key, $array2) === TRUE) {
if (is_array($value) === TRUE) {
$recurse = array_diff_recursive_one_way($value, $array2[$key]);
if (count($recurse) > 0) {
$ret[$key] = $recurse;
}
} elseif (in_array($value, $array2) === FALSE) {
$ret[$key] = $value;
}
} elseif (in_array($value, $array2) === FALSE) {
$ret[$key] = $value;
}
}
return $ret;
}//end array_diff_recursive_one_way()```
[1]: http://php.net/manual/en/function.array-diff-key.php
I know this is sort of an old post, sorry if my answer is not approppriate.
I'm in the process of writing a php package that does exactly what you are asking for, it's called Structure.
What you can do with the package is something like:
$arrayCheck = new \Structure\ArrayS();
$arrayCheck->setFormat(array("profile"=>"array"));
if ($arrayCheck->check($myArray)) {
//...
}
You can check it out here: http://github.com/3nr1c/structure
I came across a tool called Matchmaker on GitHub, which looks very comprehensive and has composer support and unit tests:
https://github.com/ptrofimov/matchmaker
You can include it into your project with
composer require ptrofimov/matchmaker.

Categories