Laravel AT Protocol Client (alpha & unstable)
1<?php
2
3namespace SocialDept\AtpClient\Concerns;
4
5use BadMethodCallException;
6use Closure;
7
8trait HasExtensions
9{
10 /**
11 * Registered domain client extensions.
12 *
13 * @var array<string, Closure>
14 */
15 protected static array $extensions = [];
16
17 /**
18 * Registered request client extensions for existing domains.
19 *
20 * @var array<string, array<string, Closure>>
21 */
22 protected static array $domainExtensions = [];
23
24 /**
25 * Resolved extension instances (lazy loading).
26 *
27 * @var array<string, object>
28 */
29 protected array $resolvedExtensions = [];
30
31 /**
32 * Register a domain client extension.
33 */
34 public static function extend(string $name, Closure $callback): void
35 {
36 static::$extensions[$name] = $callback;
37 }
38
39 /**
40 * Register a request client extension for an existing domain.
41 */
42 public static function extendDomain(string $domain, string $name, Closure $callback): void
43 {
44 static::$domainExtensions[$domain][$name] = $callback;
45 }
46
47 /**
48 * Check if an extension is registered.
49 */
50 public static function hasExtension(string $name): bool
51 {
52 return isset(static::$extensions[$name]);
53 }
54
55 /**
56 * Check if a domain extension is registered.
57 */
58 public static function hasDomainExtension(string $domain, string $name): bool
59 {
60 return isset(static::$domainExtensions[$domain][$name]);
61 }
62
63 /**
64 * Get domain extensions for a specific domain.
65 */
66 public static function getDomainExtensionsFor(string $domain): array
67 {
68 return static::$domainExtensions[$domain] ?? [];
69 }
70
71 /**
72 * Flush all registered extensions (useful for testing).
73 */
74 public static function flushExtensions(): void
75 {
76 static::$extensions = [];
77 static::$domainExtensions = [];
78 }
79
80 /**
81 * Resolve an extension instance.
82 */
83 protected function resolveExtension(string $name): object
84 {
85 if (! isset($this->resolvedExtensions[$name])) {
86 $this->resolvedExtensions[$name] = (static::$extensions[$name])($this);
87 }
88
89 return $this->resolvedExtensions[$name];
90 }
91
92 /**
93 * Magic getter for extension access.
94 */
95 public function __get(string $name): mixed
96 {
97 if (static::hasExtension($name)) {
98 return $this->resolveExtension($name);
99 }
100
101 throw new BadMethodCallException(
102 sprintf('Property [%s] does not exist on [%s].', $name, static::class)
103 );
104 }
105
106 /**
107 * Magic isset for extension checking.
108 */
109 public function __isset(string $name): bool
110 {
111 return static::hasExtension($name);
112 }
113
114 /**
115 * Get the root client instance.
116 *
117 * For root clients, this returns itself.
118 * Domain clients override this to return their parent.
119 */
120 public function root(): static
121 {
122 return $this;
123 }
124}