1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13:
14:
15: 16: 17: 18: 19: 20:
21: final class ObjectMixin
22: {
23:
24: private static $methods;
25:
26:
27:
28: 29: 30:
31: final public function __construct()
32: {
33: throw new StaticClassException;
34: }
35:
36:
37:
38: 39: 40: 41: 42: 43: 44: 45:
46: public static function call($_this, $name, $args)
47: {
48: $class = new ClassReflection($_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: } elseif ($list !== NULL) {
61: throw new UnexpectedValueException("Property $class->name::$$name must be array or NULL, " . gettype($list) ." given.");
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: