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: $name[0] = $name[0] & "\xDF";
149: $m = 'get' . $name;
150: if (isset(self::$methods[$class][$m])) {
151:
152:
153:
154: $val = $_this->$m();
155: return $val;
156: }
157:
158: $m = 'is' . $name;
159: if (isset(self::$methods[$class][$m])) {
160: $val = $_this->$m();
161: return $val;
162: }
163:
164: $type = isset(self::$methods[$class]['set' . $name]) ? 'a write-only' : 'an undeclared';
165: $name = func_get_arg(1);
166: throw new MemberAccessException("Cannot read $type property $class::\$$name.");
167: }
168:
169:
170:
171: 172: 173: 174: 175: 176: 177: 178:
179: public static function set($_this, $name, $value)
180: {
181: $class = get_class($_this);
182:
183: if ($name === '') {
184: throw new MemberAccessException("Cannot write to a class '$class' property without name.");
185: }
186:
187: if (!isset(self::$methods[$class])) {
188: self::$methods[$class] = array_flip(get_class_methods($class));
189: }
190:
191:
192: $name[0] = $name[0] & "\xDF";
193:
194: $m = 'set' . $name;
195: if (isset(self::$methods[$class][$m])) {
196: $_this->$m($value);
197: return;
198: }
199:
200: $type = isset(self::$methods[$class]['get' . $name]) || isset(self::$methods[$class]['is' . $name])
201: ? 'a read-only' : 'an undeclared';
202: $name = func_get_arg(1);
203: throw new MemberAccessException("Cannot write to $type property $class::\$$name.");
204: }
205:
206:
207:
208: 209: 210: 211: 212: 213: 214:
215: public static function remove($_this, $name)
216: {
217: $class = get_class($_this);
218: throw new MemberAccessException("Cannot unset the property $class::\$$name.");
219: }
220:
221:
222:
223: 224: 225: 226: 227: 228:
229: public static function has($_this, $name)
230: {
231: if ($name === '') {
232: return FALSE;
233: }
234:
235: $class = get_class($_this);
236: if (!isset(self::$methods[$class])) {
237: self::$methods[$class] = array_flip(get_class_methods($class));
238: }
239:
240: $name[0] = $name[0] & "\xDF";
241: return isset(self::$methods[$class]['get' . $name]) || isset(self::$methods[$class]['is' . $name]);
242: }
243:
244: }
245: