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:
48: public static function call($_this, $name, $args)
49: {
50: $class = new Nette\Reflection\ClassReflection($_this);
51:
52: if ($name === '') {
53: throw new \MemberAccessException("Call to class '$class->name' method without name.");
54: }
55:
56: 57: if ($class->hasEventProperty($name)) {
58: if (is_array($list = $_this->$name) || $list instanceof \Traversable) {
59: foreach ($list as $handler) {
60: callback($handler)->invokeArgs($args);
61: }
62: }
63: return NULL;
64: }
65:
66: 67: if ($cb = $class->getExtensionMethod($name)) {
68: array_unshift($args, $_this);
69: return $cb->invokeArgs($args);
70: }
71:
72: throw new \MemberAccessException("Call to undefined method $class->name::$name().");
73: }
74:
75:
76:
77: 78: 79: 80: 81: 82: 83: 84:
85: public static function callStatic($class, $name, $args)
86: {
87: throw new \MemberAccessException("Call to undefined static method $class::$name().");
88: }
89:
90:
91:
92: 93: 94: 95: 96: 97: 98:
99: public static function & get($_this, $name)
100: {
101: $class = get_class($_this);
102:
103: if ($name === '') {
104: throw new \MemberAccessException("Cannot read a class '$class' property without name.");
105: }
106:
107: if (!isset(self::$methods[$class])) {
108: 109: 110: 111: 112: self::$methods[$class] = array_flip(get_class_methods($class));
113: }
114:
115: 116: $name[0] = $name[0] & "\xDF"; 117: $m = 'get' . $name;
118: if (isset(self::$methods[$class][$m])) {
119: 120: 121: 122: $val = $_this->$m();
123: return $val;
124: }
125:
126: $m = 'is' . $name;
127: if (isset(self::$methods[$class][$m])) {
128: $val = $_this->$m();
129: return $val;
130: }
131:
132: $type = isset(self::$methods[$class]['set' . $name]) ? 'a write-only' : 'an undeclared';
133: $name = func_get_arg(1);
134: throw new \MemberAccessException("Cannot read $type property $class::\$$name.");
135: }
136:
137:
138:
139: 140: 141: 142: 143: 144: 145: 146:
147: public static function set($_this, $name, $value)
148: {
149: $class = get_class($_this);
150:
151: if ($name === '') {
152: throw new \MemberAccessException("Cannot write to a class '$class' property without name.");
153: }
154:
155: if (!isset(self::$methods[$class])) {
156: self::$methods[$class] = array_flip(get_class_methods($class));
157: }
158:
159: 160: $name[0] = $name[0] & "\xDF"; 161:
162: $m = 'set' . $name;
163: if (isset(self::$methods[$class][$m])) {
164: $_this->$m($value);
165: return;
166: }
167:
168: $type = isset(self::$methods[$class]['get' . $name]) || isset(self::$methods[$class]['is' . $name])
169: ? 'a read-only' : 'an undeclared';
170: $name = func_get_arg(1);
171: throw new \MemberAccessException("Cannot write to $type property $class::\$$name.");
172: }
173:
174:
175:
176: 177: 178: 179: 180: 181: 182:
183: public static function remove($_this, $name)
184: {
185: $class = get_class($_this);
186: throw new \MemberAccessException("Cannot unset the property $class::\$$name.");
187: }
188:
189:
190:
191: 192: 193: 194: 195: 196:
197: public static function has($_this, $name)
198: {
199: if ($name === '') {
200: return FALSE;
201: }
202:
203: $class = get_class($_this);
204: if (!isset(self::$methods[$class])) {
205: self::$methods[$class] = array_flip(get_class_methods($class));
206: }
207:
208: $name[0] = $name[0] & "\xDF";
209: return isset(self::$methods[$class]['get' . $name]) || isset(self::$methods[$class]['is' . $name]);
210: }
211:
212: }
213: