Namespaces

  • Nette
    • Application
    • Caching
    • Collections
    • Config
    • Forms
    • IO
    • Loaders
    • Mail
    • Reflection
    • Security
    • Templates
    • Web
  • None
  • PHP

Classes

  • ArrayTools
  • Callback
  • Component
  • ComponentContainer
  • Configurator
  • DateTime
  • Debug
  • Environment
  • Framework
  • FreezableObject
  • GenericRecursiveIterator
  • Image
  • ImageMagick
  • InstanceFilterIterator
  • Object
  • ObjectMixin
  • Paginator
  • RecursiveComponentIterator
  • ServiceLocator
  • SmartCachingIterator
  • String
  • Tools

Interfaces

  • IComponent
  • IComponentContainer
  • IDebuggable
  • IServiceLocator
  • ITranslator

Exceptions

  • AmbiguousServiceException
  • Overview
  • Namespace
  • Class
  • Tree
  • Other releases
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (https://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: /**
 19:  * Nette\Object behaviour mixin.
 20:  *
 21:  * @author     David Grudl
 22:  */
 23: final class ObjectMixin
 24: {
 25:     /** @var array */
 26:     private static $methods;
 27: 
 28: 
 29: 
 30:     /**
 31:      * Static class - cannot be instantiated.
 32:      */
 33:     final public function __construct()
 34:     {
 35:         throw new \LogicException("Cannot instantiate static class " . get_class($this));
 36:     }
 37: 
 38: 
 39: 
 40:     /**
 41:      * Call to undefined method.
 42:      * @param  string  method name
 43:      * @param  array   arguments
 44:      * @return mixed
 45:      * @throws \MemberAccessException
 46:      */
 47:     public static function call($_this, $name, $args)
 48:     {
 49:         $class = new Nette\Reflection\ClassReflection($_this);
 50: 
 51:         if ($name === '') {
 52:             throw new \MemberAccessException("Call to class '$class->name' method without name.");
 53:         }
 54: 
 55:         // event functionality
 56:         if ($class->hasEventProperty($name)) {
 57:             if (is_array($list = $_this->$name) || $list instanceof \Traversable) {
 58:                 foreach ($list as $handler) {
 59:                     callback($handler)->invokeArgs($args);
 60:                 }
 61:             }
 62:             return NULL;
 63:         }
 64: 
 65:         // extension methods
 66:         if ($cb = $class->getExtensionMethod($name)) {
 67:             array_unshift($args, $_this);
 68:             return $cb->invokeArgs($args);
 69:         }
 70: 
 71:         throw new \MemberAccessException("Call to undefined method $class->name::$name().");
 72:     }
 73: 
 74: 
 75: 
 76:     /**
 77:      * Returns property value.
 78:      * @param  string  property name
 79:      * @return mixed   property value
 80:      * @throws \MemberAccessException if the property is not defined.
 81:      */
 82:     public static function & get($_this, $name)
 83:     {
 84:         $class = get_class($_this);
 85: 
 86:         if ($name === '') {
 87:             throw new \MemberAccessException("Cannot read a class '$class' property without name.");
 88:         }
 89: 
 90:         if (!isset(self::$methods[$class])) {
 91:             // get_class_methods returns ONLY PUBLIC methods of objects
 92:             // but returns static methods too (nothing doing...)
 93:             // and is much faster than reflection
 94:             // (works good since 5.0.4)
 95:             self::$methods[$class] = array_flip(get_class_methods($class));
 96:         }
 97: 
 98:         // property getter support
 99:         $name[0] = $name[0] & "\xDF"; // case-sensitive checking, capitalize first character
100:         $m = 'get' . $name;
101:         if (isset(self::$methods[$class][$m])) {
102:             // ampersands:
103:             // - uses &__get() because declaration should be forward compatible (e.g. with Nette\Web\Html)
104:             // - doesn't call &$_this->$m because user could bypass property setter by: $x = & $obj->property; $x = 'new value';
105:             $val = $_this->$m();
106:             return $val;
107:         }
108: 
109:         $m = 'is' . $name;
110:         if (isset(self::$methods[$class][$m])) {
111:             $val = $_this->$m();
112:             return $val;
113:         }
114: 
115:         $name = func_get_arg(1);
116:         throw new \MemberAccessException("Cannot read an undeclared property $class::\$$name.");
117:     }
118: 
119: 
120: 
121:     /**
122:      * Sets value of a property.
123:      * @param  string  property name
124:      * @param  mixed   property value
125:      * @return void
126:      * @throws \MemberAccessException if the property is not defined or is read-only
127:      */
128:     public static function set($_this, $name, $value)
129:     {
130:         $class = get_class($_this);
131: 
132:         if ($name === '') {
133:             throw new \MemberAccessException("Cannot assign to a class '$class' property without name.");
134:         }
135: 
136:         if (!isset(self::$methods[$class])) {
137:             self::$methods[$class] = array_flip(get_class_methods($class));
138:         }
139: 
140:         // property setter support
141:         $name[0] = $name[0] & "\xDF"; // case-sensitive checking, capitalize first character
142:         if (isset(self::$methods[$class]['get' . $name]) || isset(self::$methods[$class]['is' . $name])) {
143:             $m = 'set' . $name;
144:             if (isset(self::$methods[$class][$m])) {
145:                 $_this->$m($value);
146:                 return;
147: 
148:             } else {
149:                 $name = func_get_arg(1);
150:                 throw new \MemberAccessException("Cannot assign to a read-only property $class::\$$name.");
151:             }
152:         }
153: 
154:         $name = func_get_arg(1);
155:         throw new \MemberAccessException("Cannot assign to an undeclared property $class::\$$name.");
156:     }
157: 
158: 
159: 
160:     /**
161:      * Is property defined?
162:      * @param  string  property name
163:      * @return bool
164:      */
165:     public static function has($_this, $name)
166:     {
167:         if ($name === '') {
168:             return FALSE;
169:         }
170: 
171:         $class = get_class($_this);
172:         if (!isset(self::$methods[$class])) {
173:             self::$methods[$class] = array_flip(get_class_methods($class));
174:         }
175: 
176:         $name[0] = $name[0] & "\xDF";
177:         return isset(self::$methods[$class]['get' . $name]) || isset(self::$methods[$class]['is' . $name]);
178:     }
179: 
180: }
181: 
Nette Framework 0.9.7 API documentation generated by ApiGen 2.3.0