public function getPolicy(Role $role, string $action)
    {
        $rules = $this->getRules();
        $pref_policy = $this->getACL()->getPreferredPolicy();

        $inherit = true;
        $ancestor_distance = null;
        $ancestor_policy = null;
        foreach ($rules as $rule)
        {
            // NOINHERIT-rules disable rule inheritance and do nothing else
            if ($rule->policy === Rule::NOINHERIT)
            {
                $inherit = false;
                continue;
            }

            // Always ignore INHERIT rules
            if ($rule->policy === Rule::INHERIT)
                continue;

            // If the action doesn't match, don't consider the rule
            // TODO: What about container actions?
            if ($rule->action !== $action)
                continue;

            // If the Rule applies to the specified Role, its answer is definitive
            if ($rule->role->is($role))
                return $rule->policy;

            // Find the closest matching parent
            if (($distance = $rule->role->isAncestorOf($role)) > 0)
            {
                // Always select the closest parent that has a defined rule.
                // When there are several conflicting rules, applying to the
                // same level of ancestry, select the preferred policy.
                if (
                    $ancestor_distance === null || 
                    $distance < $ancestor_distance || 
                    ($distance === $ancestor_distance && $rule->policy === $pref_policy)
                )
                {
                    $ancestor_policy = $rule;
                    $ancestor_distance = $distance;
                }
            }
        }

        if ($ancestor_policy !== null)
            return $ancestor_policy->policy;

        // This Entity doesn't have a defined policy for this action.
        // If inheritance is disabled, or the Entity does not have a parent (root),
        // return the default policy.
        if (!$inherit || empty($this->parents))
        {
            // Return default policy
            return Rule::UNDEFINED;
        }

        // Inherit from the parents
        $parents = $this->getParents();
        $policy = Rule::UNDEFINED;
        foreach ($parents as $parent)
        {
            $policy = $parent->getPolicy($role, $action);
            // If an Entity has multiple parents, just one of them needs to
            // allow the action to allow it on this Entity.
            if ($policy === $pref_policy)
                return $pref_policy;
        }

        // None of the parents have a preferred policy, so return the alternative
        return $policy;
    }
public function getPolicy(Role $role, string $action)
    {
        $rules = $this->getRules();
        $pref_policy = $this->getACL()->getPreferredPolicy();

        $inherit = true;
        $ancestor_distance = null;
        $ancestor_policy = null;
        foreach ($rules as $rule)
        {
            // NOINHERIT-rules disable rule inheritance and do nothing else
            if ($rule->policy === Rule::NOINHERIT)
            {
                $inherit = false;
                continue;
            }

            // Always ignore INHERIT rules
            if ($rule->policy === Rule::INHERIT)
                continue;

            // If the action doesn't match, don't consider the rule
            // TODO: What about container actions?
            if ($rule->action !== $action)
                continue;

            // If the Rule applies to the specified Role, its answer is definitive
            if ($rule->role->is($role))
                return $rule->policy;

            // Find the closest matching parent
            if (($distance = $rule->role->isAncestorOf($role)) > 0)
            {
                // Always select the closest parent that has a defined rule.
                // When there are several conflicting rules, applying to the
                // same level of ancestry, select the preferred policy.
                if (
                    $ancestor_distance === null || 
                    $distance < $ancestor_distance || 
                    ($distance === $ancestor_distance && $rule->policy === $pref_policy)
                )
                {
                    $ancestor_policy = $rule;
                    $ancestor_distance = $distance;
                }
            }
        }

        if ($ancestor_policy !== null)
            return $ancestor_policy->policy;

        // This Entity doesn't have a defined policy for this action.
        // If inheritance is disabled, or the Entity does not have a parent (root),
        // return the default policy.
        if (!$inherit || empty($this->parents))
        {
            // Return default policy
            return Rule::UNDEFINED;
        }

        // Inherit from the parents
        $parents = $this->getParents();
        $policy = Rule::UNDEFINED;
        foreach ($parents as $parent)
        {
            $policy = $parent->getPolicy($role, $action);
            // If an Entity has multiple parents, just one of them needs to
            // allow the action to allow it on this Entity.
            if ($policy === $pref_policy)
                return $pref_policy;
        }

        // None of the parents have a preferred policy, so return the alternative
        return $policy;
    }
public function getPolicy ( Role $ role , string $ action ) { $ rules = $ this -> getRules ( ) ; $ pref_policy = $ this -> getACL ( ) -> getPreferredPolicy ( ) ; $ inherit = true ; $ ancestor_distance = null ; $ ancestor_policy = null ; foreach ( $ rules as $ rule ) { // NOINHERIT-rules disable rule inheritance and do nothing else if ( $ rule -> policy === Rule :: NOINHERIT ) { $ inherit = false ; continue ; } // Always ignore INHERIT rules if ( $ rule -> policy === Rule :: INHERIT ) continue ; // If the action doesn't match, don't consider the rule // TODO: What about container actions? if ( $ rule -> action !== $ action ) continue ; // If the Rule applies to the specified Role, its answer is definitive if ( $ rule -> role -> is ( $ role ) ) return $ rule -> policy ; // Find the closest matching parent if ( ( $ distance = $ rule -> role -> isAncestorOf ( $ role ) ) > 0 ) { // Always select the closest parent that has a defined rule. // When there are several conflicting rules, applying to the // same level of ancestry, select the preferred policy. if ( $ ancestor_distance === null || $ distance < $ ancestor_distance || ( $ distance === $ ancestor_distance && $ rule -> policy === $ pref_policy ) ) { $ ancestor_policy = $ rule ; $ ancestor_distance = $ distance ; } } } if ( $ ancestor_policy !== null ) return $ ancestor_policy -> policy ; // This Entity doesn't have a defined policy for this action. // If inheritance is disabled, or the Entity does not have a parent (root), // return the default policy. if ( ! $ inherit || empty ( $ this -> parents ) ) { // Return default policy return Rule :: UNDEFINED ; } // Inherit from the parents $ parents = $ this -> getParents ( ) ; $ policy = Rule :: UNDEFINED ; foreach ( $ parents as $ parent ) { $ policy = $ parent -> getPolicy ( $ role , $ action ) ; // If an Entity has multiple parents, just one of them needs to // allow the action to allow it on this Entity. if ( $ policy === $ pref_policy ) return $ pref_policy ; } // None of the parents have a preferred policy, so return the alternative return $ policy ; }
Find the policy to the Role performing the action on this Entity.

@param $role Role The Role wanting to perform an action
@param $action string The action Role wishes to perform
@return integer The policy, either Rule::ALLOW or Rule::DENY.
Find the policy to the Role performing the action on this Entity .