1: <?php
2:
3: namespace LaravelUi5\Core\Services;
4:
5: use LaravelUi5\Core\Attributes\Setting;
6: use LaravelUi5\Core\Contracts\SettingResolverInterface;
7: use LaravelUi5\Core\Exceptions\InvalidSettingException;
8: use LaravelUi5\Core\Ui5\AbstractConfigurable;
9: use ReflectionClass;
10:
11: readonly class SettingResolver implements SettingResolverInterface
12: {
13: public function resolve(object $target): void
14: {
15: if (!$target instanceof AbstractConfigurable) {
16: throw new InvalidSettingException(
17: sprintf(
18: 'Settings can only be injected into subclasses of %s, %s given.',
19: AbstractConfigurable::class,
20: $target::class
21: )
22: );
23: }
24:
25: $reflection = new ReflectionClass($target);
26: $attributes = $reflection->getAttributes(Setting::class);
27:
28: if ($attributes === []) {
29: // Nothing to inject – but still valid
30: return;
31: }
32:
33: $resolved = [];
34:
35: foreach ($attributes as $attribute) {
36: /** @var Setting $definition */
37: $definition = $attribute->newInstance();
38:
39: if (array_key_exists($definition->key, $resolved)) {
40: throw new InvalidSettingException(
41: sprintf(
42: 'Duplicate setting "%s" declared on %s.',
43: $definition->key,
44: $target::class
45: )
46: );
47: }
48:
49: // Core does not cast defaults.
50: $resolved[$definition->key] = $definition->default;
51: }
52:
53: $target->injectSettings($resolved);
54: }
55: }
56: