I have a form with multiple fields a user can search by. How do I dynamically write the if condition based on the fields selected by user?
E.g. I have 3 fields as follows:
$categoryId = $_REQUEST['category_id'];
$locationId = $_REQUEST['location_id'];
$statusId = $_REQUEST['status_id'];
If the user selected category_id and location_id and status_id then my if statement would be should be as follows:
if (!empty($categoryId) && !empty($locationId) && !empty($statusId)) {
if (isInTaxonomy($recordId, $categoryId) && isInTaxonomy($recordId, $locationId) && isInTaxonomy($recordId, $statusId) {
// Do something
}
}
if the user selected category_id and location_id then my if statmeent would be as follows:
if (!empty($categoryId) && !empty($locationId)) {
if (isInTaxonomy($recordId, $categoryId) && isInTaxonomy($recordId, $locationId) {
// Do something
}
}
if the user only selected category_id then my if statmeent would be as follows:
if (!empty($categoryId)) {
if (isInTaxonomy($recordId, $categoryId)) {
// Do something
}
}
As you can see I'm having to implement every possible combination of fields a user can select to build all the different conditions.
I was thinking of doing something like the following but that just give me a string and I don't want to use eval to execute it:
$filter = [(!empty($categoryId) ? '(isInTaxonomy($recordId, $categoryId))' : ''),
(!empty($locationId) ? '(isInTaxonomy($recordId, $locationId))' : '')];
$condition = implode(' && ', array_filter($filter));
if (eval("return $condition;")) {
// Do something
}
Is there a way to dynamically generate all the condition using more concise code without having to resort to Eval?
I presume you can use the following approach - define available keys and iterate over them, while iterate - collect some data, for example like this:
$keys = ['category_id', 'location_id', 'status_id'];
$operationAllowed = true;
foreach ($keys as $key) {
if (!empty($_REQUEST[$key])) {
$operationAllowed = $operationAllowed && isInTaxonomy($recordId, $_REQUEST[$key]);
}
}
This evaluates to the same results:
$categoryId = $_REQUEST['category_id'];
$locationId = $_REQUEST['location_id'];
$statusId = $_REQUEST['status_id'];
if( (empty($categoryId) || isInTaxonomy($recordId, $categoryId)) &&
(empty($locationId) || isInTaxonomy($recordId, $locationId)) &&
(empty($statusId) || isInTaxonomy($recordId, $statusId))) {
// Do Something
}
It's separated by lines, each variable is a line. If the variable is empty, line evaluates to true
(without checking isInTaxonomy
), and goes on the next one, if variable is not empty, then the second condition is checked, isInTaxonomy
is evaluated, if it's true
, validation goes on to the next line, if it's false
, it stops.
Edit: you can also use this approach on a for loop
$args = ['category_id', 'location_id', 'status_id'];
$valid = true;
foreach ($args as $arg) {
$valid &= empty($_REQUEST[$arg]) || isInTaxonomy($recordId, $_REQUEST[$arg]);
}
if($valid) {
// Do Something
}
You could add them to an array and loop the array (or keep them in the array and loop there).
$categoryId = $_REQUEST['category_id'];
$locationId = $_REQUEST['location_id'];
$statusId = $_REQUEST['status_id'];
// This can be done in different ways, I kept your "style" since you may have other reasons to extract the values
$arr =[$categoryId, $locationId, $statusId];
$arr = array_filter($arr); // remove empty values
$return[] = false; // set 0 key to false. First iteration will overwrite it
foreach($arr as $key => $val){
if (isInTaxonomy($recordId, $val)) {
$return[$key] = true;
}
}
if(array_diff($return, [true])) {
// Don't do something (?)
}else{
// Do something
// (All is true)
}
Because I use array_filter then it will not test an empty value which will return false.
I rethought my code.
If all three is empty then my previous code would return true, which would be wrong (I guess).
So instead I start with false statement and add the true/false to an array then after the loop I see if I got any false return values with array_diff.
Array_diff will remove all true, if the return array has any values then at least one value in the loop was false.