1: <?php
2:
3: /**
4: * This file is part of the Nette Framework (http://nette.org)
5: *
6: * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
7: *
8: * For the full copyright and license information, please view
9: * the file license.txt that was distributed with this source code.
10: */
11:
12: namespace Nette;
13:
14: use Nette;
15:
16:
17: /**
18: * Nette\Object is the ultimate ancestor of all instantiable classes.
19: *
20: * It defines some handful methods and enhances object core of PHP:
21: * - access to undeclared members throws exceptions
22: * - support for conventional properties with getters and setters
23: * - support for event raising functionality
24: * - ability to add new methods to class (extension methods)
25: *
26: * Properties is a syntactic sugar which allows access public getter and setter
27: * methods as normal object variables. A property is defined by a getter method
28: * or setter method (no setter method means read-only property).
29: * <code>
30: * $val = $obj->label; // equivalent to $val = $obj->getLabel();
31: * $obj->label = 'Nette'; // equivalent to $obj->setLabel('Nette');
32: * </code>
33: * Property names are case-sensitive, and they are written in the camelCaps
34: * or PascalCaps.
35: *
36: * Event functionality is provided by declaration of property named 'on{Something}'
37: * Multiple handlers are allowed.
38: * <code>
39: * public $onClick; // declaration in class
40: * $this->onClick[] = 'callback'; // attaching event handler
41: * if (!empty($this->onClick)) ... // are there any handlers?
42: * $this->onClick($sender, $arg); // raises the event with arguments
43: * </code>
44: *
45: * Adding method to class (i.e. to all instances) works similar to JavaScript
46: * prototype property. The syntax for adding a new method is:
47: * <code>
48: * MyClass::extensionMethod('newMethod', function(MyClass $obj, $arg, ...) { ... });
49: * $obj = new MyClass;
50: * $obj->newMethod($x);
51: * </code>
52: *
53: * @author David Grudl
54: *
55: * @property-read Nette\Reflection\ClassType $reflection
56: */
57: abstract class Object
58: {
59:
60: /**
61: * Access to reflection.
62: * @return Nette\Reflection\ClassType
63: */
64: public static function getReflection()
65: {
66: return new Reflection\ClassType(get_called_class());
67: }
68:
69:
70: /**
71: * Call to undefined method.
72: * @param string method name
73: * @param array arguments
74: * @return mixed
75: * @throws MemberAccessException
76: */
77: public function __call($name, $args)
78: {
79: return ObjectMixin::call($this, $name, $args);
80: }
81:
82:
83: /**
84: * Call to undefined static method.
85: * @param string method name (in lower case!)
86: * @param array arguments
87: * @return mixed
88: * @throws MemberAccessException
89: */
90: public static function __callStatic($name, $args)
91: {
92: return ObjectMixin::callStatic(get_called_class(), $name, $args);
93: }
94:
95:
96: /**
97: * Adding method to class.
98: * @param string method name
99: * @param callable
100: * @return mixed
101: */
102: public static function extensionMethod($name, $callback = NULL)
103: {
104: if (strpos($name, '::') === FALSE) {
105: $class = get_called_class();
106: } else {
107: list($class, $name) = explode('::', $name);
108: }
109: $class = new Reflection\ClassType($class);
110: if ($callback === NULL) {
111: return $class->getExtensionMethod($name);
112: } else {
113: $class->setExtensionMethod($name, $callback);
114: }
115: }
116:
117:
118: /**
119: * Returns property value. Do not call directly.
120: * @param string property name
121: * @return mixed property value
122: * @throws MemberAccessException if the property is not defined.
123: */
124: public function &__get($name)
125: {
126: return ObjectMixin::get($this, $name);
127: }
128:
129:
130: /**
131: * Sets value of a property. Do not call directly.
132: * @param string property name
133: * @param mixed property value
134: * @return void
135: * @throws MemberAccessException if the property is not defined or is read-only
136: */
137: public function __set($name, $value)
138: {
139: return ObjectMixin::set($this, $name, $value);
140: }
141:
142:
143: /**
144: * Is property defined?
145: * @param string property name
146: * @return bool
147: */
148: public function __isset($name)
149: {
150: return ObjectMixin::has($this, $name);
151: }
152:
153:
154: /**
155: * Access to undeclared property.
156: * @param string property name
157: * @return void
158: * @throws MemberAccessException
159: */
160: public function __unset($name)
161: {
162: ObjectMixin::remove($this, $name);
163: }
164:
165: }
166: