policy = $policy; $this->model = $model; } public static function allow(PolicyDocument $policy, Model|null $model = null) { (new static($policy, $model))->applyCheck(); } public static function when(PolicyDocument $policy, Model|null $model = null): bool { return (new static($policy, $model))->applyCheck(false); } public function applyCheck($throwException = true): bool { $pass = false; foreach ($this->policy?->needs ?? [] as $condition) { $pass = $this->checkCondition($condition); if ($pass) break; } if (!$pass && $throwException) { abort(Response::HTTP_FORBIDDEN, 'this action is forbidden.'); } return $pass; } public function checkCondition($conditions): bool { $conditionsMatch = true; foreach ($conditions as $condition) { [$function, $param] = str_contains($condition, ":") ? explode(':', $condition) : [$condition, null]; $conditionsMatch = $conditionsMatch && call_user_func_array([static::class, $function], (empty($param) ? [] : [$param])); if (!$conditionsMatch) break; } return $conditionsMatch; } }