aboutsummaryrefslogtreecommitdiffhomepage
path: root/Digitigrade/PolicyManager.php
blob: 24c2c7f5bf6a27aed1da24c6f7c98b232f291bc0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?php
namespace Digitigrade;

use Digitigrade\Model\Actor;
use Digitigrade\Model\FetchableModel;
use Digitigrade\Model\Interaction;
use Digitigrade\Model\Note;

class PolicyManager extends Singleton {
    /** @var Policy[] */
    private array $policies = [];

    public function register(Policy $policy) {
        $this->policies[] = $policy;
    }

    public function registerAll(Policy ...$policies) {
        foreach ($policies as $p) {
            $this->register($p);
        }
    }

    /**
     * Checks if an object is allowed by all policies and possibly alters it.
     * @param FetchableModel $object the object to check (may be modified in-place)
     * @return bool true if allowed, false if it should be dropped
     */
    public function check(FetchableModel $object): bool {
        return match ($object::class) {
            Actor::class => self::arrayAll($this->policies, fn(Policy $p) => $p->checkActor($object)),
            Interaction::class => self::arrayAll($this->policies, fn(Policy $p) => $p->checkInteraction($object)),
            Note::class => self::arrayAll($this->policies, fn(Policy $p) => $p->checkNote($object)),
            default => true
        };
    }

    private static function arrayAll(array $arr, callable $test): bool {
        // i would use array_all but that's php 8.4+ only which i don't have lol
        foreach ($arr as $item) {
            if (!$test($item)) {
                return false;
            }
        }
        return true;
    }
}