private function isAuthorizedByRolesActionAndUri($rolesToCheck, $action, $uri)
{
if (!in_array("default", $rolesToCheck)) {
$rolesToCheck = array_merge(["default"], $rolesToCheck);
}
$ruleUri = $action . "." . $uri;
$uriParts = explode(".", $ruleUri);
$matchable = ["."];
$building = "";
foreach ($uriParts as $part) {
$building .= $part . ".";
$matchable[] = $building;
}
// remove the last dot for exact matches
$matchable[count($matchable) - 1] = substr($building, 0, strlen($building) - 1);
// flip the array so we can do intersections on the keys
$matchable = array_flip($matchable);
$matches = [];
foreach ($rolesToCheck as $role) {
if (isset($this->rules[$role])) {
// if there are identical matches - we use the
// most restrictive one - we have to set this before the merge, otherwise
// it will default the value to the first value
$m = array_intersect_key($this->rules[$role], $matchable);
$overlap = array_intersect_key($matches, $m);
foreach ($overlap as $k => $v) {
// if either is false - set both to false
if (!$matches[$k] || !$m[$k]) {
$matches[$k] = false;
$m[$k] = false;
}
}
$matches = array_merge($matches, $m);
}
}
// sort the list by length
$keys = array_map('strlen', array_keys($matches));
array_multisort($keys, SORT_DESC, $matches);
$allow = false;
// grab the top one
if (!empty($matches)) {
reset($matches);
$allow = current($matches);
}
return $allow;
}