Source for file ObjectMixin.php
Documentation is available at ObjectMixin.php
6: * Copyright (c) 2004, 2009 David Grudl (http://davidgrudl.com)
8: * This source file is subject to the "Nette license" that is bundled
9: * with this package in the file license.txt.
11: * For more information please see https://nette.org
13: * @copyright Copyright (c) 2004, 2009 David Grudl
14: * @license https://nette.org/license Nette license
15: * @link https://nette.org
23: require_once dirname(__FILE__) .
'/compatibility.php';
25: require_once dirname(__FILE__) .
'/exceptions.php';
30: * Nette\Object behaviour mixin.
32: * @author David Grudl
33: * @copyright Copyright (c) 2004, 2009 David Grudl
38: /** @var array (method => array(type => callback)) */
39: private static $extMethods;
42: private static $methods;
47: * Static class - cannot be instantiated.
51: throw new LogicException("Cannot instantiate static class " .
get_class($this));
57: * Call to undefined method.
59: * @param string method name
60: * @param array arguments
62: * @throws MemberAccessException
64: public static function call($_this, $name, $args)
72: // event functionality
74: $rp =
new ReflectionProperty($class, $name);
75: if ($rp->isPublic() &&
!$rp->isStatic()) {
76: $list =
$_this->$name;
77: if (is_array($list) ||
$list instanceof
Traversable) {
78: foreach ($list as $handler) {
82: throw new InvalidStateException("Event handler '$textual' is not " .
($able ?
'callable.' :
'valid PHP callback.'));
92: if ($cb =
self::extensionMethod($class, $name)) {
103: * Adding method to class.
105: * @param string class name
106: * @param string method name
107: * @param mixed callback or closure
112: if (self::$extMethods ===
NULL ||
$name ===
NULL) { // for backwards compatibility
114: foreach ($list['user'] as $fce) {
117: self::$extMethods[$pair[1]][$pair[0]] =
$fce;
118: self::$extMethods[$pair[1]][''] =
NULL;
121: if ($name ===
NULL) return NULL;
125: $l =
& self::$extMethods[strtolower($name)];
127: if ($callback !==
NULL) { // works as setter
131: throw new InvalidArgumentException("Extension method handler '$textual' is not " .
($able ?
'callable.' :
'valid PHP callback.'));
133: $l[$class] =
$callback;
142: } elseif (isset($l[''][$class])) { // cached value
143: return $l[''][$class];
149: if (isset($l[$cl])) {
150: return $l[''][$class] =
$l[$cl];
156: if (isset($l[$cl])) {
157: return $l[''][$class] =
$l[$cl];
160: return $l[''][$class] =
FALSE;
166: * Returns property value.
168: * @param string property name
169: * @return mixed property value
170: * @throws MemberAccessException if the property is not defined.
172: public static function & get($_this, $name)
180: if (!isset(self::$methods[$class])) {
181: // get_class_methods returns ONLY PUBLIC methods of objects
182: // but returns static methods too (nothing doing...)
183: // and is much faster than reflection
184: // (works good since 5.0.4)
188: // property getter support
189: $name[0] =
$name[0] & "\xDF"; // case-sensitive checking, capitalize first character
191: if (isset(self::$methods[$class][$m])) {
193: // - uses &__get() because declaration should be forward compatible (e.g. with Nette\Web\Html)
194: // - doesn't call &$_this->$m because user could bypass property setter by: $x = & $obj->property; $x = 'new value';
195: $val =
$_this->$m();
200: if (isset(self::$methods[$class][$m])) {
201: $val =
$_this->$m();
205: $name =
func_get_arg(1);
212: * Sets value of a property.
214: * @param string property name
215: * @param mixed property value
217: * @throws MemberAccessException if the property is not defined or is read-only
219: public static function set($_this, $name, $value)
227: if (!isset(self::$methods[$class])) {
231: // property setter support
232: $name[0] =
$name[0] & "\xDF"; // case-sensitive checking, capitalize first character
233: if (isset(self::$methods[$class]['get' .
$name]) ||
isset(self::$methods[$class]['is' .
$name])) {
235: if (isset(self::$methods[$class][$m])) {
240: $name =
func_get_arg(1);
252: * Is property defined?
254: * @param string property name
257: public static function has($_this, $name)
264: if (!isset(self::$methods[$class])) {
268: $name[0] =
$name[0] & "\xDF";
269: return isset(self::$methods[$class]['get' .
$name]) ||
isset(self::$methods[$class]['is' .
$name]);