Completed
Branch feature/pre-split (197e7e)
by Anton
03:26
created

BooleanRule::allows()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 19
c 0
b 0
f 0
cc 5
eloc 11
nc 5
nop 3
rs 8.8571
1
<?php
2
/**
3
 * Spiral Framework.
4
 *
5
 * @license   MIT
6
 * @author    Anton Titov (Wolfy-J)
7
 */
8
namespace Spiral\Security\Rules;
9
10
use Spiral\Security\ActorInterface;
11
use Spiral\Security\RuleInterface;
12
use Spiral\Security\RulesInterface;
13
14
/**
15
 * Provides ability to evaluate multiple sub rules using boolean joiner.
16
 *
17
 * Example:
18
 *
19
 * class AuthorOrModeratorRule extends BooleanRule
20
 * {
21
 *      const JOINER = self::BOOLEAN_OR;
22
 *      protected $rules= [AuthorRule::class, ModeratorRule::class];
23
 * }
24
 *
25
 */
26
abstract class BooleanRule implements RuleInterface
27
{
28
    const BOOLEAN_AND = 'and';
29
    const BOOLEAN_OR  = 'or';
30
31
    /**
32
     * How to process results on sub rules.
33
     */
34
    const JOINER = self::BOOLEAN_AND;
35
36
    /**
37
     * Rules repository.
38
     *
39
     * @var RulesInterface
40
     */
41
    private $repository = null;
42
43
    /**
44
     * Rule rule names.
45
     *
46
     * @var array
47
     */
48
    protected $rules = [];
49
50
    /**
51
     * @param RulesInterface $repository
52
     */
53
    public function __construct(RulesInterface $repository)
54
    {
55
        $this->repository = $repository;
56
    }
57
58
    /**
59
     * {@inheritdoc}
60
     */
61
    public function allows(ActorInterface $actor, string $permission, array $context): bool
62
    {
63
        $allowed = 0;
64
        foreach ($this->rules as $rule) {
65
            $rule = $this->repository->get($rule);
66
67
            if ($rule->allows($actor, $permission, $context)) {
68
                if (static::JOINER == self::BOOLEAN_OR) {
69
                    return true;
70
                }
71
72
                $allowed++;
73
            } elseif (static::JOINER == self::BOOLEAN_AND) {
74
                return false;
75
            }
76
        }
77
78
        return $allowed === count($this->rules);
79
    }
80
}