aboutsummaryrefslogtreecommitdiffhomepage
path: root/Digitigrade/PolicyManager.php
diff options
context:
space:
mode:
Diffstat (limited to 'Digitigrade/PolicyManager.php')
-rw-r--r--Digitigrade/PolicyManager.php46
1 files changed, 46 insertions, 0 deletions
diff --git a/Digitigrade/PolicyManager.php b/Digitigrade/PolicyManager.php
new file mode 100644
index 0000000..24c2c7f
--- /dev/null
+++ b/Digitigrade/PolicyManager.php
@@ -0,0 +1,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;
+ }
+} \ No newline at end of file