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