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
  • Environment
  • 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
  • Deprecated
  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 behaviour mixin.
 19:  *
 20:  * @author     David Grudl
 21:  */
 22: final class ObjectMixin
 23: {
 24:     /** @var array */
 25:     private static $methods;
 26: 
 27:     /** @var array */
 28:     private static $props;
 29: 
 30: 
 31:     /**
 32:      * Static class - cannot be instantiated.
 33:      */
 34:     final public function __construct()
 35:     {
 36:         throw new StaticClassException;
 37:     }
 38: 
 39: 
 40:     /**
 41:      * __call() implementation.
 42:      * @param  object
 43:      * @param  string
 44:      * @param  array
 45:      * @return mixed
 46:      * @throws MemberAccessException
 47:      */
 48:     public static function call($_this, $name, $args)
 49:     {
 50:         $class = get_class($_this);
 51:         $isProp = self::hasProperty($class, $name);
 52: 
 53:         if ($name === '') {
 54:             throw new MemberAccessException("Call to class '$class' method without name.");
 55: 
 56:         } elseif ($isProp === 'event') { // calling event handlers
 57:             if (is_array($_this->$name) || $_this->$name instanceof \Traversable) {
 58:                 foreach ($_this->$name as $handler) {
 59:                     Nette\Callback::create($handler)->invokeArgs($args);
 60:                 }
 61:             } elseif ($_this->$name !== NULL) {
 62:                 throw new UnexpectedValueException("Property $class::$$name must be array or NULL, " . gettype($_this->$name) ." given.");
 63:             }
 64: 
 65:         } elseif ($cb = Reflection\ClassType::from($_this)->getExtensionMethod($name)) { // extension methods
 66:             array_unshift($args, $_this);
 67:             return $cb->invokeArgs($args);
 68: 
 69:         } else {
 70:             throw new MemberAccessException("Call to undefined method $class::$name().");
 71:         }
 72:     }
 73: 
 74: 
 75:     /**
 76:      * __call() implementation for entities.
 77:      * @param  object
 78:      * @param  string
 79:      * @param  array
 80:      * @return mixed
 81:      * @throws MemberAccessException
 82:      */
 83:     public static function callProperty($_this, $name, $args)
 84:     {
 85:         if (strlen($name) > 3) {
 86:             $op = substr($name, 0, 3);
 87:             $prop = strtolower($name[3]) . substr($name, 4);
 88:             if ($op === 'add' && self::hasProperty(get_class($_this), $prop.'s')) {
 89:                 $_this->{$prop.'s'}[] = $args[0];
 90:                 return $_this;
 91: 
 92:             } elseif ($op === 'set' && self::hasProperty(get_class($_this), $prop)) {
 93:                 $_this->$prop = $args[0];
 94:                 return $_this;
 95: 
 96:             } elseif ($op === 'get' && self::hasProperty(get_class($_this), $prop)) {
 97:                 return $_this->$prop;
 98:             }
 99:         }
100:         return self::call($_this, $name, $args);
101:     }
102: 
103: 
104:     /**
105:      * __callStatic() implementation.
106:      * @param  string
107:      * @param  string
108:      * @param  array
109:      * @return void
110:      * @throws MemberAccessException
111:      */
112:     public static function callStatic($class, $method, $args)
113:     {
114:         throw new MemberAccessException("Call to undefined static method $class::$method().");
115:     }
116: 
117: 
118:     /**
119:      * __get() implementation.
120:      * @param  object
121:      * @param  string  property name
122:      * @return mixed   property value
123:      * @throws MemberAccessException if the property is not defined.
124:      */
125:     public static function & get($_this, $name)
126:     {
127:         $class = get_class($_this);
128:         $uname = ucfirst($name);
129: 
130:         if (!isset(self::$methods[$class])) {
131:             self::$methods[$class] = array_flip(get_class_methods($class)); // public (static and non-static) methods
132:         }
133: 
134:         if ($name === '') {
135:             throw new MemberAccessException("Cannot read a class '$class' property without name.");
136: 
137:         } elseif (isset(self::$methods[$class][$m = 'get' . $uname]) || isset(self::$methods[$class][$m = 'is' . $uname])) { // property getter
138:             $val = $_this->$m();
139:             return $val;
140: 
141:         } elseif (isset(self::$methods[$class][$name])) { // public method as closure getter
142:             $val = Callback::create($_this, $name);
143:             return $val;
144: 
145:         } else { // strict class
146:             $type = isset(self::$methods[$class]['set' . $uname]) ? 'a write-only' : 'an undeclared';
147:             throw new MemberAccessException("Cannot read $type property $class::\$$name.");
148:         }
149:     }
150: 
151: 
152:     /**
153:      * __set() implementation.
154:      * @param  object
155:      * @param  string  property name
156:      * @param  mixed   property value
157:      * @return void
158:      * @throws MemberAccessException if the property is not defined or is read-only
159:      */
160:     public static function set($_this, $name, $value)
161:     {
162:         $class = get_class($_this);
163:         $uname = ucfirst($name);
164: 
165:         if (!isset(self::$methods[$class])) {
166:             self::$methods[$class] = array_flip(get_class_methods($class));
167:         }
168: 
169:         if ($name === '') {
170:             throw new MemberAccessException("Cannot write to a class '$class' property without name.");
171: 
172:         } elseif (self::hasProperty($class, $name)) { // unsetted property
173:             $_this->$name = $value;
174: 
175:         } elseif (isset(self::$methods[$class][$m = 'set' . $uname])) { // property setter
176:             $_this->$m($value);
177: 
178:         } else { // strict class
179:             $type = isset(self::$methods[$class]['get' . $uname]) || isset(self::$methods[$class]['is' . $uname])
180:             ? 'a read-only' : 'an undeclared';
181:             throw new MemberAccessException("Cannot write to $type property $class::\$$name.");
182:         }
183:     }
184: 
185: 
186:     /**
187:      * __unset() implementation.
188:      * @param  object
189:      * @param  string  property name
190:      * @return void
191:      * @throws MemberAccessException
192:      */
193:     public static function remove($_this, $name)
194:     {
195:         $class = get_class($_this);
196:         if (!self::hasProperty($class, $name)) { // strict class
197:             throw new MemberAccessException("Cannot unset the property $class::\$$name.");
198:         }
199:     }
200: 
201: 
202:     /**
203:      * __isset() implementation.
204:      * @param  object
205:      * @param  string  property name
206:      * @return bool
207:      */
208:     public static function has($_this, $name)
209:     {
210:         $class = get_class($_this);
211:         $name = ucfirst($name);
212:         if (!isset(self::$methods[$class])) {
213:             self::$methods[$class] = array_flip(get_class_methods($class));
214:         }
215:         return $name !== '' && (isset(self::$methods[$class]['get' . $name]) || isset(self::$methods[$class]['is' . $name]));
216:     }
217: 
218: 
219:     /**
220:      * Checks if the public non-static property exists.
221:      * @return mixed
222:      */
223:     private static function hasProperty($class, $name)
224:     {
225:         $prop = & self::$props[$class][$name];
226:         if ($prop === NULL) {
227:             $prop = FALSE;
228:             try {
229:                 $rp = new \ReflectionProperty($class, $name);
230:                 if ($name === $rp->getName() && $rp->isPublic() && !$rp->isStatic()) {
231:                     $prop = preg_match('#^on[A-Z]#', $name) ? 'event' : TRUE;
232:                 }
233:             } catch (\ReflectionException $e) {}
234:         }
235:         return $prop;
236:     }
237: 
238: }
239: 
Nette Framework 2.0.11 API API documentation generated by ApiGen 2.8.0