,bool>>} */ public $getters; /** * @var array {record>>,concrete:map>>>>} */ public $acl; /** */ public function __construct( array $getters, array $acl ) { $this->getters = $getters; $this->acl = $acl; } } /** */ function make( array $getters, array $acl ) { return ( new struct_subject( $getters, $acl ) ); } /** */ function check( struct_subject $subject, string $action, $state = null ) : bool { $acl_section = ( $subject->acl['concrete'][$action] ?? $subject->acl['default'] ?? [] ); return \alveolata\list_\some( $acl_section, function (array $acl_section_sub) use ($subject, $state) : bool { return \alveolata\list_\every( $acl_section_sub, function (array $entry) use ($subject, $state) : bool { if (! array_key_exists($entry['type'], $subject->getters)) { throw (new \Exception('unhandled ACL check type: ' . $entry['type'])); } else { $getter = $subject->getters[$entry['type']]; return $getter($entry['parameters'] ?? null, $state); } } ); } ); } ?>