1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13:
14:
15: 16: 17: 18: 19:
20: final class NObjectMixin
21: {
22:
23: private static $methods;
24:
25:
26:
27: 28: 29:
30: final public function __construct()
31: {
32: throw new LogicException("Cannot instantiate static class " . get_class($this));
33: }
34:
35:
36:
37: 38: 39: 40: 41: 42: 43:
44: public static function call($_this, $name, $args)
45: {
46: $class = new NClassReflection($_this);
47:
48: if ($name === '') {
49: throw new MemberAccessException("Call to class '$class->name' method without name.");
50: }
51:
52: 53: if ($class->hasEventProperty($name)) {
54: if (is_array($list = $_this->$name) || $list instanceof Traversable) {
55: foreach ($list as $handler) {
56: callback($handler)->invokeArgs($args);
57: }
58: }
59: return NULL;
60: }
61:
62: 63: if ($cb = $class->getExtensionMethod($name)) {
64: array_unshift($args, $_this);
65: return $cb->invokeArgs($args);
66: }
67:
68: throw new MemberAccessException("Call to undefined method $class->name::$name().");
69: }
70:
71:
72:
73: 74: 75: 76: 77: 78:
79: public static function & get($_this, $name)
80: {
81: $class = get_class($_this);
82:
83: if ($name === '') {
84: throw new MemberAccessException("Cannot read a class '$class' property without name.");
85: }
86:
87: if (!isset(self::$methods[$class])) {
88: 89: 90: 91: 92: self::$methods[$class] = array_flip(get_class_methods($class));
93: }
94:
95: 96: $name[0] = $name[0] & "\xDF"; 97: $m = 'get' . $name;
98: if (isset(self::$methods[$class][$m])) {
99: 100: 101: 102: $val = $_this->$m();
103: return $val;
104: }
105:
106: $m = 'is' . $name;
107: if (isset(self::$methods[$class][$m])) {
108: $val = $_this->$m();
109: return $val;
110: }
111:
112: $name = func_get_arg(1);
113: throw new MemberAccessException("Cannot read an undeclared property $class::\$$name.");
114: }
115:
116:
117:
118: 119: 120: 121: 122: 123: 124:
125: public static function set($_this, $name, $value)
126: {
127: $class = get_class($_this);
128:
129: if ($name === '') {
130: throw new MemberAccessException("Cannot write to a class '$class' property without name.");
131: }
132:
133: if (!isset(self::$methods[$class])) {
134: self::$methods[$class] = array_flip(get_class_methods($class));
135: }
136:
137: 138: $name[0] = $name[0] & "\xDF"; 139: if (isset(self::$methods[$class]['get' . $name]) || isset(self::$methods[$class]['is' . $name])) {
140: $m = 'set' . $name;
141: if (isset(self::$methods[$class][$m])) {
142: $_this->$m($value);
143: return;
144:
145: } else {
146: $name = func_get_arg(1);
147: throw new MemberAccessException("Cannot write to a read-only property $class::\$$name.");
148: }
149: }
150:
151: $name = func_get_arg(1);
152: throw new MemberAccessException("Cannot write to an undeclared 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: