Skip to content

Instantly share code, notes, and snippets.

@rafi
Last active December 20, 2015 09:49
Show Gist options
  • Save rafi/6110931 to your computer and use it in GitHub Desktop.
Save rafi/6110931 to your computer and use it in GitHub Desktop.
⊕ Recursively compute conditions, supports $or (like Mongo) ⊕
<?php
/**
* Recursively compute conditions against existing data, supports $or (like Mongo)
* For example:
* {
* "$or": [
* { "foo": true },
* { "bar": true, "baz": true }
* ],
* "foobar": false
* }
*
* @param array $conditions
* @param array $extra_pairs
* @param array $data
* @return bool
*/
function valid_conditions(
array $conditions,
array $extra_pairs = [],
array $data = []
)
{
$bonafide = TRUE;
// Prepare an array of available macros from extra pairs and internal
$macros = array_merge([ '$or' ], array_keys($extra_pairs));
$macros = array_map('strtolower', $macros);
// Conditions start as an object: {}
foreach ($conditions as $condition => $and)
{
// Making sure it's an array (supporting a single value string)
$and = (array) $and;
// Process a macro if the condition is indeed matching one of them.
if (in_array(strtolower($condition), $macros))
{
$ok = FALSE;
if ($condition === '$or')
{
// OR conditions start as an array: []
foreach ($and as $or)
{
// Inside, each object represents an AND group: {}
// Recursively process them with OR operator
$ok = $ok ||
valid_conditions($or, $extra_pairs, $data);
}
}
else
{
// Fail if macro's value isn't in the allowed extra operands array
$ok = in_array($extra_pairs[$condition], $and);
}
$bonafide = $bonafide && $ok;
}
else
{
// Iterate through operands and fail accordingly
foreach ($and as $operand)
{
$bonafide = ($operand XOR isset($data[$condition]));
}
}
}
return $bonafide;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment