Parse and validate AT Protocol Lexicons with DTO generation for Laravel
at dev 2.8 kB view raw
1<?php 2 3namespace SocialDept\AtpSchema\Support; 4 5use Closure; 6 7class ExtensionManager 8{ 9 /** 10 * Registered hooks. 11 * 12 * @var array<string, array<Closure>> 13 */ 14 protected array $hooks = []; 15 16 /** 17 * Register a hook callback. 18 */ 19 public function hook(string $name, Closure $callback): self 20 { 21 if (! isset($this->hooks[$name])) { 22 $this->hooks[$name] = []; 23 } 24 25 $this->hooks[$name][] = $callback; 26 27 return $this; 28 } 29 30 /** 31 * Execute all hooks for a given name. 32 * 33 * @return array<mixed> 34 */ 35 public function execute(string $name, mixed ...$args): array 36 { 37 if (! isset($this->hooks[$name])) { 38 return []; 39 } 40 41 $results = []; 42 43 foreach ($this->hooks[$name] as $callback) { 44 $results[] = $callback(...$args); 45 } 46 47 return $results; 48 } 49 50 /** 51 * Execute hooks and return the first non-null result. 52 */ 53 public function executeUntil(string $name, mixed ...$args): mixed 54 { 55 if (! isset($this->hooks[$name])) { 56 return null; 57 } 58 59 foreach ($this->hooks[$name] as $callback) { 60 $result = $callback(...$args); 61 62 if ($result !== null) { 63 return $result; 64 } 65 } 66 67 return null; 68 } 69 70 /** 71 * Execute hooks with a value that can be modified by each hook. 72 */ 73 public function filter(string $name, mixed $value, mixed ...$args): mixed 74 { 75 if (! isset($this->hooks[$name])) { 76 return $value; 77 } 78 79 foreach ($this->hooks[$name] as $callback) { 80 $value = $callback($value, ...$args); 81 } 82 83 return $value; 84 } 85 86 /** 87 * Check if a hook has any callbacks registered. 88 */ 89 public function has(string $name): bool 90 { 91 return isset($this->hooks[$name]) && count($this->hooks[$name]) > 0; 92 } 93 94 /** 95 * Get all callbacks for a hook. 96 * 97 * @return array<Closure> 98 */ 99 public function get(string $name): array 100 { 101 return $this->hooks[$name] ?? []; 102 } 103 104 /** 105 * Remove all callbacks for a hook. 106 */ 107 public function remove(string $name): self 108 { 109 unset($this->hooks[$name]); 110 111 return $this; 112 } 113 114 /** 115 * Clear all hooks. 116 */ 117 public function clear(): self 118 { 119 $this->hooks = []; 120 121 return $this; 122 } 123 124 /** 125 * Get count of callbacks for a hook. 126 */ 127 public function count(string $name): int 128 { 129 return count($this->hooks[$name] ?? []); 130 } 131 132 /** 133 * Get all registered hook names. 134 * 135 * @return array<string> 136 */ 137 public function names(): array 138 { 139 return array_keys($this->hooks); 140 } 141}