1: <?php
2:
3: namespace LaravelUi5\Core\Ui5;
4:
5: use LogicException;
6:
7: /**
8: * Base class for all configurable UI5 handlers and providers.
9: *
10: * Provides read-only, virtual properties for settings declared
11: * via #[Setting] attributes.
12: *
13: * Settings are injected once by the framework before execution
14: * and must not be mutated afterwards.
15: */
16: abstract class AbstractConfigurable
17: {
18: /** @var array<string, mixed> */
19: private array $__settings = [];
20:
21: /**
22: * Inject resolved settings.
23: *
24: * This method is intended to be called exactly once by the framework.
25: *
26: * @param array<string, mixed> $values
27: */
28: final public function injectSettings(array $values): void
29: {
30: if (!empty($this->__settings)) {
31: throw new LogicException(
32: sprintf(
33: 'Settings already injected on %s.',
34: static::class
35: )
36: );
37: }
38:
39: foreach ($values as $key => $value) {
40: // Prevent collision with real properties
41: if (property_exists($this, $key)) {
42: throw new LogicException(
43: sprintf(
44: 'Cannot inject setting "%s" on %s: property already exists.',
45: $key,
46: static::class
47: )
48: );
49: }
50:
51: $this->__settings[$key] = $value;
52: }
53: }
54:
55: /**
56: * Read-only access to injected settings.
57: *
58: * @param string $name
59: * @return mixed
60: */
61: final public function __get(string $name): mixed
62: {
63: if (array_key_exists($name, $this->__settings)) {
64: return $this->__settings[$name];
65: }
66:
67: throw new LogicException(
68: sprintf(
69: 'Undefined setting "%s" accessed on %s.',
70: $name,
71: static::class
72: )
73: );
74: }
75: }
76: