1: <?php declare(strict_types=1);
2:
3: namespace Salient\Core\Concern;
4:
5: use Salient\Contract\Core\Writable;
6: use Salient\Core\Introspector;
7:
8: /**
9: * Implements Writable
10: *
11: * - If `_set<Property>()` is defined, it is called instead of assigning
12: * `$value` to `<Property>`.
13: * - If `_unset<Property>()` is defined, it is called to unset `<Property>`
14: * instead of assigning `null`.
15: * - The existence of `_set<Property>()` makes `<Property>` writable, regardless
16: * of {@see Writable::getWritableProperties()}'s return value.
17: *
18: * @api
19: *
20: * @see Writable
21: */
22: trait HasWritableProperties
23: {
24: public static function getWritableProperties(): array
25: {
26: return [];
27: }
28:
29: /**
30: * @param mixed ...$params
31: */
32: private function setProperty(string $action, string $name, ...$params): void
33: {
34: Introspector::get(static::class)->getPropertyActionClosure($name, $action)($this, ...$params);
35: }
36:
37: /**
38: * @param mixed $value
39: */
40: final public function __set(string $name, $value): void
41: {
42: $this->setProperty('set', $name, $value);
43: }
44:
45: final public function __unset(string $name): void
46: {
47: $this->setProperty('unset', $name);
48: }
49: }
50: