Namespaces

  • Nette
    • Application
      • Diagnostics
      • Responses
      • Routers
      • UI
    • Caching
      • Storages
    • ComponentModel
    • Config
      • Adapters
      • Extensions
    • Database
      • Diagnostics
      • Drivers
      • Reflection
      • Table
    • DI
      • Diagnostics
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Latte
      • Macros
    • Loaders
    • Localization
    • Mail
    • Reflection
    • Security
      • Diagnostics
    • Templating
    • Utils
      • PhpGenerator
  • NetteModule
  • None
  • PHP

Classes

  • ArrayHash
  • ArrayList
  • Callback
  • DateTime
  • Framework
  • FreezableObject
  • Image
  • Object
  • ObjectMixin

Interfaces

  • IFreezable

Exceptions

  • ArgumentOutOfRangeException
  • DeprecatedException
  • DirectoryNotFoundException
  • FatalErrorException
  • FileNotFoundException
  • InvalidArgumentException
  • InvalidStateException
  • IOException
  • MemberAccessException
  • NotImplementedException
  • NotSupportedException
  • OutOfRangeException
  • StaticClassException
  • UnexpectedValueException
  • UnknownImageFileException
  • Overview
  • Namespace
  • Class
  • Tree
  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: /**
 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 StaticClassException;
 36:     }
 37: 
 38: 
 39: 
 40:     /**
 41:      * Call to undefined method.
 42:      * @param  object
 43:      * @param  string  method name
 44:      * @param  array   arguments
 45:      * @return mixed
 46:      * @throws MemberAccessException
 47:      */
 48:     public static function call($_this, $name, $args)
 49:     {
 50:         $class = new Reflection\ClassType($_this);
 51: 
 52:         if ($name === '') {
 53:             throw new MemberAccessException("Call to class '$class->name' method without name.");
 54:         }
 55: 
 56:         // event functionality
 57:         if ($class->hasEventProperty($name)) {
 58:             if (is_array($list = $_this->$name) || $list instanceof \Traversable) {
 59:                 foreach ($list as $handler) {
 60:                     callback($handler)->invokeArgs($args);
 61:                 }
 62:             } elseif ($list !== NULL) {
 63:                 throw new UnexpectedValueException("Property $class->name::$$name must be array or NULL, " . gettype($list) ." given.");
 64:             }
 65:             return NULL;
 66:         }
 67: 
 68:         // extension methods
 69:         if ($cb = $class->getExtensionMethod($name)) {
 70:             array_unshift($args, $_this);
 71:             return $cb->invokeArgs($args);
 72:         }
 73: 
 74:         throw new MemberAccessException("Call to undefined method $class->name::$name().");
 75:     }
 76: 
 77: 
 78: 
 79:     /**
 80:      * Call to undefined method.
 81:      * @param  object
 82:      * @param  string  method name
 83:      * @param  array   arguments
 84:      * @return mixed
 85:      * @throws MemberAccessException
 86:      */
 87:     public static function callProperty($_this, $name, $args)
 88:     {
 89:         if (strlen($name) > 3) {
 90:             $op = substr($name, 0, 3);
 91:             $prop = strtolower($name[3]) . substr($name, 4);
 92:             if ($op === 'add' && property_exists($_this, $prop.'s')) {
 93:                 $_this->{$prop.'s'}[] = $args[0];
 94:                 return $_this;
 95: 
 96:             } elseif ($op === 'set' && property_exists($_this, $prop)) {
 97:                 $_this->$prop = $args[0];
 98:                 return $_this;
 99: 
100:             } elseif ($op === 'get' && property_exists($_this, $prop)) {
101:                 return $_this->$prop;
102:             }
103:         }
104:         self::call($_this, $name, $args);
105:     }
106: 
107: 
108: 
109:     /**
110:      * Call to undefined static method.
111:      * @param  string
112:      * @param  string  method name
113:      * @param  array   arguments
114:      * @return mixed
115:      * @throws MemberAccessException
116:      */
117:     public static function callStatic($class, $name, $args)
118:     {
119:         throw new MemberAccessException("Call to undefined static method $class::$name().");
120:     }
121: 
122: 
123: 
124:     /**
125:      * Returns property value.
126:      * @param  object
127:      * @param  string  property name
128:      * @return mixed   property value
129:      * @throws MemberAccessException if the property is not defined.
130:      */
131:     public static function & get($_this, $name)
132:     {
133:         $class = get_class($_this);
134: 
135:         if ($name === '') {
136:             throw new MemberAccessException("Cannot read a class '$class' property without name.");
137:         }
138: 
139:         if (!isset(self::$methods[$class])) {
140:             // get_class_methods returns ONLY PUBLIC methods of objects
141:             // but returns static methods too (nothing doing...)
142:             // and is much faster than reflection
143:             // (works good since 5.0.4)
144:             self::$methods[$class] = array_flip(get_class_methods($class));
145:         }
146: 
147:         // public method as closure getter
148:         if (isset(self::$methods[$class][$name])) {
149:             $val = function() use ($_this, $name) {
150:                 return call_user_func_array(array($_this, $name), func_get_args());
151:             };
152:             return $val;
153:         }
154: 
155:         // property getter support
156:         $name[0] = $name[0] & "\xDF"; // case-sensitive checking, capitalize first character
157:         $m = 'get' . $name;
158:         if (isset(self::$methods[$class][$m])) {
159:             // ampersands:
160:             // - uses &__get() because declaration should be forward compatible (e.g. with Nette\Utils\Html)
161:             // - doesn't call &$_this->$m because user could bypass property setter by: $x = & $obj->property; $x = 'new value';
162:             $val = $_this->$m();
163:             return $val;
164:         }
165: 
166:         $m = 'is' . $name;
167:         if (isset(self::$methods[$class][$m])) {
168:             $val = $_this->$m();
169:             return $val;
170:         }
171: 
172:         $type = isset(self::$methods[$class]['set' . $name]) ? 'a write-only' : 'an undeclared';
173:         $name = func_get_arg(1);
174:         throw new MemberAccessException("Cannot read $type property $class::\$$name.");
175:     }
176: 
177: 
178: 
179:     /**
180:      * Sets value of a property.
181:      * @param  object
182:      * @param  string  property name
183:      * @param  mixed   property value
184:      * @return void
185:      * @throws MemberAccessException if the property is not defined or is read-only
186:      */
187:     public static function set($_this, $name, $value)
188:     {
189:         $class = get_class($_this);
190: 
191:         if ($name === '') {
192:             throw new MemberAccessException("Cannot write to a class '$class' property without name.");
193:         }
194: 
195:         if (!isset(self::$methods[$class])) {
196:             self::$methods[$class] = array_flip(get_class_methods($class));
197:         }
198: 
199:         // property setter support
200:         $name[0] = $name[0] & "\xDF"; // case-sensitive checking, capitalize first character
201: 
202:         $m = 'set' . $name;
203:         if (isset(self::$methods[$class][$m])) {
204:             $_this->$m($value);
205:             return;
206:         }
207: 
208:         $type = isset(self::$methods[$class]['get' . $name]) || isset(self::$methods[$class]['is' . $name])
209:             ? 'a read-only' : 'an undeclared';
210:         $name = func_get_arg(1);
211:         throw new MemberAccessException("Cannot write to $type property $class::\$$name.");
212:     }
213: 
214: 
215: 
216:     /**
217:      * Throws exception.
218:      * @param  object
219:      * @param  string  property name
220:      * @return void
221:      * @throws MemberAccessException
222:      */
223:     public static function remove($_this, $name)
224:     {
225:         $class = get_class($_this);
226:         throw new MemberAccessException("Cannot unset the property $class::\$$name.");
227:     }
228: 
229: 
230: 
231:     /**
232:      * Is property defined?
233:      * @param  object
234:      * @param  string  property name
235:      * @return bool
236:      */
237:     public static function has($_this, $name)
238:     {
239:         if ($name === '') {
240:             return FALSE;
241:         }
242: 
243:         $class = get_class($_this);
244:         if (!isset(self::$methods[$class])) {
245:             self::$methods[$class] = array_flip(get_class_methods($class));
246:         }
247: 
248:         $name[0] = $name[0] & "\xDF";
249:         return isset(self::$methods[$class]['get' . $name]) || isset(self::$methods[$class]['is' . $name]);
250:     }
251: 
252: }
253: 
Nette Framework 2.0.4 API API documentation generated by ApiGen 2.7.0