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: }
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 callProperty($_this, $name, $args)
86: {
87: if (strlen($name) > 3) {
88: $op = substr($name, 0, 3);
89: $prop = strtolower($name[3]) . substr($name, 4);
90: if ($op === 'add' && property_exists($_this, $prop.'s')) {
91: $_this->{$prop.'s'}[] = $args[0];
92: return $_this;
93:
94: } elseif ($op === 'set' && property_exists($_this, $prop)) {
95: $_this->$prop = $args[0];
96: return $_this;
97:
98: } elseif ($op === 'get' && property_exists($_this, $prop)) {
99: return $_this->$prop;
100: }
101: }
102: self::call($_this, $name, $args);
103: }
104:
105:
106:
107: 108: 109: 110: 111: 112: 113: 114:
115: public static function callStatic($class, $name, $args)
116: {
117: throw new MemberAccessException("Call to undefined static method $class::$name().");
118: }
119:
120:
121:
122: 123: 124: 125: 126: 127: 128:
129: public static function & get($_this, $name)
130: {
131: $class = get_class($_this);
132:
133: if ($name === '') {
134: throw new MemberAccessException("Cannot read a class '$class' property without name.");
135: }
136:
137: if (!isset(self::$methods[$class])) {
138:
139:
140:
141:
142: self::$methods[$class] = array_flip(get_class_methods($class));
143: }
144:
145:
146: $name[0] = $name[0] & "\xDF";
147: $m = 'get' . $name;
148: if (isset(self::$methods[$class][$m])) {
149:
150:
151:
152: $val = $_this->$m();
153: return $val;
154: }
155:
156: $m = 'is' . $name;
157: if (isset(self::$methods[$class][$m])) {
158: $val = $_this->$m();
159: return $val;
160: }
161:
162: $type = isset(self::$methods[$class]['set' . $name]) ? 'a write-only' : 'an undeclared';
163: $name = func_get_arg(1);
164: throw new MemberAccessException("Cannot read $type property $class::\$$name.");
165: }
166:
167:
168:
169: 170: 171: 172: 173: 174: 175: 176:
177: public static function set($_this, $name, $value)
178: {
179: $class = get_class($_this);
180:
181: if ($name === '') {
182: throw new MemberAccessException("Cannot write to a class '$class' property without name.");
183: }
184:
185: if (!isset(self::$methods[$class])) {
186: self::$methods[$class] = array_flip(get_class_methods($class));
187: }
188:
189:
190: $name[0] = $name[0] & "\xDF";
191:
192: $m = 'set' . $name;
193: if (isset(self::$methods[$class][$m])) {
194: $_this->$m($value);
195: return;
196: }
197:
198: $type = isset(self::$methods[$class]['get' . $name]) || isset(self::$methods[$class]['is' . $name])
199: ? 'a read-only' : 'an undeclared';
200: $name = func_get_arg(1);
201: throw new MemberAccessException("Cannot write to $type property $class::\$$name.");
202: }
203:
204:
205:
206: 207: 208: 209: 210: 211: 212:
213: public static function remove($_this, $name)
214: {
215: $class = get_class($_this);
216: throw new MemberAccessException("Cannot unset the property $class::\$$name.");
217: }
218:
219:
220:
221: 222: 223: 224: 225: 226:
227: public static function has($_this, $name)
228: {
229: if ($name === '') {
230: return FALSE;
231: }
232:
233: $class = get_class($_this);
234: if (!isset(self::$methods[$class])) {
235: self::$methods[$class] = array_flip(get_class_methods($class));
236: }
237:
238: $name[0] = $name[0] & "\xDF";
239: return isset(self::$methods[$class]['get' . $name]) || isset(self::$methods[$class]['is' . $name]);
240: }
241:
242: }
243: