1: <?php
2:
3: namespace Teto\Object;
4:
5: use function count;
6:
7: /**
8: * Typed property function for class
9: *
10: * @author USAMI Kenta <tadsan@zonu.me>
11: * @copyright 2016 Baguette HQ
12: * @license http://www.apache.org/licenses/LICENSE-2.0
13: */
14: trait TypedProperty
15: {
16: use TypeAssert;
17:
18: /**
19: * @var array
20: */
21: private $properties = [];
22:
23: /**
24: * Set property (magic method)
25: *
26: * @param string $name
27: * @param mixed $value
28: * @throws \OutOfRangeException If you set to undefined property
29: * @throws \InvalidArgumentException If differed from the defined type
30: * @throws \RangeException If differed from the defined length
31: * @see http://php.net/manual/language.oop5.magic.php
32: * @suppress PhanUndeclaredStaticProperty
33: */
34: public function __set($name, $value)
35: {
36: if (!isset(self::$property_types[$name])) {
37: throw new \OutOfRangeException("Unexpected key:'$name'");
38: }
39:
40: $type = TypeDefinition::parse(self::$property_types[$name]);
41:
42: if ($type->is_array) {
43: self::assertArrayOrObject($value);
44: $values = $value;
45: } else {
46: $values = [$value];
47: }
48:
49: foreach ($values as $v) {
50: self::assertValue($type->expected, $name, $v, $type->is_nullable);
51: }
52: if ($type->len !== null && count($value) !== $type->len) {
53: throw new \RangeException("Unexpected length:{$name} (expects {$type->len})");
54: }
55:
56: $this->properties[$name] = $value;
57: }
58:
59: /**
60: * Get property (magic method)
61: *
62: * @param string $name
63: * @return mixed
64: * @see http://php.net/manual/language.oop5.magic.php
65: * @suppress PhanUndeclaredStaticProperty
66: */
67: public function __get($name)
68: {
69: if (!isset(self::$property_types[$name])) {
70: throw new \OutOfRangeException("Unexpected key:'$name'");
71: }
72:
73: return isset($this->properties[$name]) ? $this->properties[$name] : null;
74: }
75:
76: /**
77: * @param string $name
78: * @return bool
79: * @see http://php.net/manual/language.oop5.magic.php
80: */
81: public function __isset($name)
82: {
83: return isset($this->properties[$name]);
84: }
85:
86: /**
87: * @param string $name
88: * @see http://php.net/manual/language.oop5.magic.php
89: * @suppress PhanUndeclaredStaticProperty
90: */
91: public function __unset($name)
92: {
93: if (isset(self::$property_types[$name])) {
94: $this->properties[$name] = null;
95: }
96: }
97:
98: /**
99: * @param array
100: * @suppress PhanUndeclaredStaticProperty
101: */
102: private function setProperties(array $properties)
103: {
104: foreach (self::$property_types as $name => $_) {
105: if (isset($properties[$name])) {
106: $this->$name = $properties[$name];
107: }
108: }
109: }
110: }
111: