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: $type = isset(self::$methods[$class]['set' . $name]) ? 'a write-only' : 'an undeclared';
116: $name = func_get_arg(1);
117: throw new \MemberAccessException("Cannot read $type property $class::\$$name.");
118: }
119:
120:
121:
122: 123: 124: 125: 126: 127: 128:
129: public static function set($_this, $name, $value)
130: {
131: $class = get_class($_this);
132:
133: if ($name === '') {
134: throw new \MemberAccessException("Cannot write to a class '$class' property without name.");
135: }
136:
137: if (!isset(self::$methods[$class])) {
138: self::$methods[$class] = array_flip(get_class_methods($class));
139: }
140:
141: 142: $name[0] = $name[0] & "\xDF"; 143:
144: $m = 'set' . $name;
145: if (isset(self::$methods[$class][$m])) {
146: $_this->$m($value);
147: return;
148: }
149:
150: $type = isset(self::$methods[$class]['get' . $name]) || isset(self::$methods[$class]['is' . $name]) ? 'a read-only' : 'an undeclared';
151: $name = func_get_arg(1);
152: throw new \MemberAccessException("Cannot write to $type property $class::\$$name.");
153: }
154:
155:
156:
157: 158: 159: 160: 161:
162: public static function has($_this, $name)
163: {
164: if ($name === '') {
165: return FALSE;
166: }
167:
168: $class = get_class($_this);
169: if (!isset(self::$methods[$class])) {
170: self::$methods[$class] = array_flip(get_class_methods($class));
171: }
172:
173: $name[0] = $name[0] & "\xDF";
174: return isset(self::$methods[$class]['get' . $name]) || isset(self::$methods[$class]['is' . $name]);
175: }
176:
177: }
178: