1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10:
11:
12: namespace Nette;
13:
14: use Nette;
15:
16:
17:
18: 19: 20: 21: 22:
23: final class ObjectMixin
24: {
25:
26: private static $methods;
27:
28:
29:
30: 31: 32:
33: final public function __construct()
34: {
35: throw new \LogicException("Cannot instantiate static class " . get_class($this));
36: }
37:
38:
39:
40: 41: 42: 43: 44: 45: 46:
47: public static function call($_this, $name, $args)
48: {
49: $class = new Nette\Reflection\ClassReflection($_this);
50:
51: if ($name === '') {
52: throw new \MemberAccessException("Call to class '$class->name' method without name.");
53: }
54:
55:
56: if ($class->hasEventProperty($name)) {
57: if (is_array($list = $_this->$name) || $list instanceof \Traversable) {
58: foreach ($list as $handler) {
59: callback($handler)->invokeArgs($args);
60: }
61: }
62: return NULL;
63: }
64:
65:
66: if ($cb = $class->getExtensionMethod($name)) {
67: array_unshift($args, $_this);
68: return $cb->invokeArgs($args);
69: }
70:
71: throw new \MemberAccessException("Call to undefined method $class->name::$name().");
72: }
73:
74:
75:
76: 77: 78: 79: 80: 81:
82: public static function & get($_this, $name)
83: {
84: $class = get_class($_this);
85:
86: if ($name === '') {
87: throw new \MemberAccessException("Cannot read a class '$class' property without name.");
88: }
89:
90: if (!isset(self::$methods[$class])) {
91:
92:
93:
94:
95: self::$methods[$class] = array_flip(get_class_methods($class));
96: }
97:
98:
99: $name[0] = $name[0] & "\xDF";
100: $m = 'get' . $name;
101: if (isset(self::$methods[$class][$m])) {
102:
103:
104:
105: $val = $_this->$m();
106: return $val;
107: }
108:
109: $m = 'is' . $name;
110: if (isset(self::$methods[$class][$m])) {
111: $val = $_this->$m();
112: return $val;
113: }
114:
115: $name = func_get_arg(1);
116: throw new \MemberAccessException("Cannot read an undeclared property $class::\$$name.");
117: }
118:
119:
120:
121: 122: 123: 124: 125: 126: 127:
128: public static function set($_this, $name, $value)
129: {
130: $class = get_class($_this);
131:
132: if ($name === '') {
133: throw new \MemberAccessException("Cannot assign to a class '$class' property without name.");
134: }
135:
136: if (!isset(self::$methods[$class])) {
137: self::$methods[$class] = array_flip(get_class_methods($class));
138: }
139:
140:
141: $name[0] = $name[0] & "\xDF";
142: if (isset(self::$methods[$class]['get' . $name]) || isset(self::$methods[$class]['is' . $name])) {
143: $m = 'set' . $name;
144: if (isset(self::$methods[$class][$m])) {
145: $_this->$m($value);
146: return;
147:
148: } else {
149: $name = func_get_arg(1);
150: throw new \MemberAccessException("Cannot assign to a read-only property $class::\$$name.");
151: }
152: }
153:
154: $name = func_get_arg(1);
155: throw new \MemberAccessException("Cannot assign to an undeclared property $class::\$$name.");
156: }
157:
158:
159:
160: 161: 162: 163: 164:
165: public static function has($_this, $name)
166: {
167: if ($name === '') {
168: return FALSE;
169: }
170:
171: $class = get_class($_this);
172: if (!isset(self::$methods[$class])) {
173: self::$methods[$class] = array_flip(get_class_methods($class));
174: }
175:
176: $name[0] = $name[0] & "\xDF";
177: return isset(self::$methods[$class]['get' . $name]) || isset(self::$methods[$class]['is' . $name]);
178: }
179:
180: }
181: