1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13:
14:
15: 16: 17: 18: 19: 20:
21: final class NObjectMixin
22: {
23:
24: private static $methods;
25:
26:
27:
28: 29: 30:
31: final public function __construct()
32: {
33: throw new NStaticClassException;
34: }
35:
36:
37:
38: 39: 40: 41: 42: 43: 44: 45:
46: public static function call($_this, $name, $args)
47: {
48: $class = new NClassReflection($_this);
49:
50: if ($name === '') {
51: throw new MemberAccessException("Call to class '$class->name' method without name.");
52: }
53:
54:
55: if ($class->hasEventProperty($name)) {
56: if (is_array($list = $_this->$name) || $list instanceof Traversable) {
57: foreach ($list as $handler) {
58: callback($handler)->invokeArgs($args);
59: }
60: }
61: return NULL;
62: }
63:
64:
65: if ($cb = $class->getExtensionMethod($name)) {
66: array_unshift($args, $_this);
67: return $cb->invokeArgs($args);
68: }
69:
70: throw new MemberAccessException("Call to undefined method $class->name::$name().");
71: }
72:
73:
74:
75: 76: 77: 78: 79: 80: 81: 82:
83: public static function callProperty($_this, $name, $args)
84: {
85: if (strlen($name) > 3) {
86: $op = substr($name, 0, 3);
87: $prop = strtolower($name[3]) . substr($name, 4);
88: if ($op === 'add' && property_exists($_this, $prop.'s')) {
89: $_this->{$prop.'s'}[] = $args[0];
90: return $_this;
91:
92: } elseif ($op === 'set' && property_exists($_this, $prop)) {
93: $_this->$prop = $args[0];
94: return $_this;
95:
96: } elseif ($op === 'get' && property_exists($_this, $prop)) {
97: return $_this->$prop;
98: }
99: }
100: self::call($_this, $name, $args);
101: }
102:
103:
104:
105: 106: 107: 108: 109: 110: 111: 112:
113: public static function callStatic($class, $name, $args)
114: {
115: throw new MemberAccessException("Call to undefined static method $class::$name().");
116: }
117:
118:
119:
120: 121: 122: 123: 124: 125: 126:
127: public static function & get($_this, $name)
128: {
129: $class = get_class($_this);
130:
131: if ($name === '') {
132: throw new MemberAccessException("Cannot read a class '$class' property without name.");
133: }
134:
135: if (!isset(self::$methods[$class])) {
136:
137:
138:
139:
140: self::$methods[$class] = array_flip(get_class_methods($class));
141: }
142:
143:
144: $name[0] = $name[0] & "\xDF";
145: $m = 'get' . $name;
146: if (isset(self::$methods[$class][$m])) {
147:
148:
149:
150: $val = $_this->$m();
151: return $val;
152: }
153:
154: $m = 'is' . $name;
155: if (isset(self::$methods[$class][$m])) {
156: $val = $_this->$m();
157: return $val;
158: }
159:
160: $type = isset(self::$methods[$class]['set' . $name]) ? 'a write-only' : 'an undeclared';
161: $name = func_get_arg(1);
162: throw new MemberAccessException("Cannot read $type property $class::\$$name.");
163: }
164:
165:
166:
167: 168: 169: 170: 171: 172: 173: 174:
175: public static function set($_this, $name, $value)
176: {
177: $class = get_class($_this);
178:
179: if ($name === '') {
180: throw new MemberAccessException("Cannot write to a class '$class' property without name.");
181: }
182:
183: if (!isset(self::$methods[$class])) {
184: self::$methods[$class] = array_flip(get_class_methods($class));
185: }
186:
187:
188: $name[0] = $name[0] & "\xDF";
189:
190: $m = 'set' . $name;
191: if (isset(self::$methods[$class][$m])) {
192: $_this->$m($value);
193: return;
194: }
195:
196: $type = isset(self::$methods[$class]['get' . $name]) || isset(self::$methods[$class]['is' . $name])
197: ? 'a read-only' : 'an undeclared';
198: $name = func_get_arg(1);
199: throw new MemberAccessException("Cannot write to $type property $class::\$$name.");
200: }
201:
202:
203:
204: 205: 206: 207: 208: 209: 210:
211: public static function remove($_this, $name)
212: {
213: $class = get_class($_this);
214: throw new MemberAccessException("Cannot unset the property $class::\$$name.");
215: }
216:
217:
218:
219: 220: 221: 222: 223: 224:
225: public static function has($_this, $name)
226: {
227: if ($name === '') {
228: return FALSE;
229: }
230:
231: $class = get_class($_this);
232: if (!isset(self::$methods[$class])) {
233: self::$methods[$class] = array_flip(get_class_methods($class));
234: }
235:
236: $name[0] = $name[0] & "\xDF";
237: return isset(self::$methods[$class]['get' . $name]) || isset(self::$methods[$class]['is' . $name]);
238: }
239:
240: }
241: