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

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