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 StaticClassException;
36: }
37:
38:
39:
40: 41: 42: 43: 44: 45: 46: 47:
48: public static function call($_this, $name, $args)
49: {
50: $class = new Reflection\ClassType($_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: } elseif ($list !== NULL) {
63: throw new UnexpectedValueException("Property $class->name::$$name must be array or NULL, " . gettype($list) ." given.");
64: }
65: return NULL;
66: }
67:
68:
69: if ($cb = $class->getExtensionMethod($name)) {
70: array_unshift($args, $_this);
71: return $cb->invokeArgs($args);
72: }
73:
74: throw new MemberAccessException("Call to undefined method $class->name::$name().");
75: }
76:
77:
78:
79: 80: 81: 82: 83: 84: 85: 86:
87: public static function callProperty($_this, $name, $args)
88: {
89: if (strlen($name) > 3) {
90: $op = substr($name, 0, 3);
91: $prop = strtolower($name[3]) . substr($name, 4);
92: if ($op === 'add' && property_exists($_this, $prop.'s')) {
93: $_this->{$prop.'s'}[] = $args[0];
94: return $_this;
95:
96: } elseif ($op === 'set' && property_exists($_this, $prop)) {
97: $_this->$prop = $args[0];
98: return $_this;
99:
100: } elseif ($op === 'get' && property_exists($_this, $prop)) {
101: return $_this->$prop;
102: }
103: }
104: self::call($_this, $name, $args);
105: }
106:
107:
108:
109: 110: 111: 112: 113: 114: 115: 116:
117: public static function callStatic($class, $name, $args)
118: {
119: throw new MemberAccessException("Call to undefined static method $class::$name().");
120: }
121:
122:
123:
124: 125: 126: 127: 128: 129: 130:
131: public static function & get($_this, $name)
132: {
133: $class = get_class($_this);
134:
135: if ($name === '') {
136: throw new MemberAccessException("Cannot read a class '$class' property without name.");
137: }
138:
139: if (!isset(self::$methods[$class])) {
140:
141:
142:
143:
144: self::$methods[$class] = array_flip(get_class_methods($class));
145: }
146:
147:
148: if (isset(self::$methods[$class][$name])) {
149: $val = function() use ($_this, $name) {
150: return call_user_func_array(array($_this, $name), func_get_args());
151: };
152: return $val;
153: }
154:
155:
156: $name[0] = $name[0] & "\xDF";
157: $m = 'get' . $name;
158: if (isset(self::$methods[$class][$m])) {
159:
160:
161:
162: $val = $_this->$m();
163: return $val;
164: }
165:
166: $m = 'is' . $name;
167: if (isset(self::$methods[$class][$m])) {
168: $val = $_this->$m();
169: return $val;
170: }
171:
172: $type = isset(self::$methods[$class]['set' . $name]) ? 'a write-only' : 'an undeclared';
173: $name = func_get_arg(1);
174: throw new MemberAccessException("Cannot read $type property $class::\$$name.");
175: }
176:
177:
178:
179: 180: 181: 182: 183: 184: 185: 186:
187: public static function set($_this, $name, $value)
188: {
189: $class = get_class($_this);
190:
191: if ($name === '') {
192: throw new MemberAccessException("Cannot write to a class '$class' property without name.");
193: }
194:
195: if (!isset(self::$methods[$class])) {
196: self::$methods[$class] = array_flip(get_class_methods($class));
197: }
198:
199:
200: $name[0] = $name[0] & "\xDF";
201:
202: $m = 'set' . $name;
203: if (isset(self::$methods[$class][$m])) {
204: $_this->$m($value);
205: return;
206: }
207:
208: $type = isset(self::$methods[$class]['get' . $name]) || isset(self::$methods[$class]['is' . $name])
209: ? 'a read-only' : 'an undeclared';
210: $name = func_get_arg(1);
211: throw new MemberAccessException("Cannot write to $type property $class::\$$name.");
212: }
213:
214:
215:
216: 217: 218: 219: 220: 221: 222:
223: public static function remove($_this, $name)
224: {
225: $class = get_class($_this);
226: throw new MemberAccessException("Cannot unset the property $class::\$$name.");
227: }
228:
229:
230:
231: 232: 233: 234: 235: 236:
237: public static function has($_this, $name)
238: {
239: if ($name === '') {
240: return FALSE;
241: }
242:
243: $class = get_class($_this);
244: if (!isset(self::$methods[$class])) {
245: self::$methods[$class] = array_flip(get_class_methods($class));
246: }
247:
248: $name[0] = $name[0] & "\xDF";
249: return isset(self::$methods[$class]['get' . $name]) || isset(self::$methods[$class]['is' . $name]);
250: }
251:
252: }
253: