Namespaces

  • Latte
    • Loaders
    • Macros
    • Runtime
  • Nette
    • Application
      • Responses
      • Routers
      • UI
    • Bridges
      • ApplicationDI
      • ApplicationLatte
      • ApplicationTracy
      • CacheDI
      • CacheLatte
      • DatabaseDI
      • DatabaseTracy
      • DITracy
      • FormsDI
      • FormsLatte
      • Framework
      • HttpDI
      • HttpTracy
      • MailDI
      • ReflectionDI
      • SecurityDI
      • SecurityTracy
    • Caching
      • Storages
    • ComponentModel
    • Database
      • Conventions
      • Drivers
      • Table
    • DI
      • Config
        • Adapters
      • Extensions
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Loaders
    • Localization
    • Mail
    • Neon
    • PhpGenerator
      • Traits
    • Reflection
    • Security
    • Tokenizer
    • Utils
  • Tracy
    • Bridges
      • Nette
  • none

Classes

  • ArrayHash
  • ArrayList
  • Arrays
  • Callback
  • DateTime
  • FileSystem
  • Finder
  • Html
  • Image
  • Json
  • ObjectHelpers
  • ObjectMixin
  • Paginator
  • Random
  • Reflection
  • SafeStream
  • Strings
  • TokenIterator
  • Tokenizer
  • Validators

Interfaces

  • IHtmlString

Exceptions

  • AssertionException
  • ImageException
  • JsonException
  • RegexpException
  • TokenizerException
  • UnknownImageFileException
  • Overview
  • Namespace
  • Class
  • Tree
  • Deprecated
  • Other releases
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (https://nette.org)
  5:  * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
  6:  */
  7: 
  8: namespace Nette\Utils;
  9: 
 10: use Nette;
 11: use Nette\MemberAccessException;
 12: 
 13: 
 14: /**
 15:  * Nette\Object behaviour mixin.
 16:  * @deprecated
 17:  */
 18: class ObjectMixin
 19: {
 20:     use Nette\StaticClass;
 21: 
 22:     /** @var array [name => [type => callback]] used by extension methods */
 23:     private static $extMethods = [];
 24: 
 25: 
 26:     /********************* strictness ****************d*g**/
 27: 
 28: 
 29:     /**
 30:      * @deprecated  use ObjectHelpers::strictGet()
 31:      */
 32:     public static function strictGet($class, $name)
 33:     {
 34:         trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED);
 35:         ObjectHelpers::strictGet($class, $name);
 36:     }
 37: 
 38: 
 39:     /**
 40:      * @deprecated  use ObjectHelpers::strictSet()
 41:      */
 42:     public static function strictSet($class, $name)
 43:     {
 44:         trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED);
 45:         ObjectHelpers::strictSet($class, $name);
 46:     }
 47: 
 48: 
 49:     /**
 50:      * @deprecated  use ObjectHelpers::strictCall()
 51:      */
 52:     public static function strictCall($class, $method, $additionalMethods = [])
 53:     {
 54:         trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED);
 55:         ObjectHelpers::strictCall($class, $method, $additionalMethods);
 56:     }
 57: 
 58: 
 59:     /**
 60:      * @deprecated  use ObjectHelpers::strictStaticCall()
 61:      */
 62:     public static function strictStaticCall($class, $method)
 63:     {
 64:         trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED);
 65:         ObjectHelpers::strictStaticCall($class, $method);
 66:     }
 67: 
 68: 
 69:     /********************* Nette\Object ****************d*g**/
 70: 
 71: 
 72:     /**
 73:      * __call() implementation.
 74:      * @param  object
 75:      * @param  string
 76:      * @param  array
 77:      * @return mixed
 78:      * @throws MemberAccessException
 79:      */
 80:     public static function call($_this, $name, $args)
 81:     {
 82:         trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED);
 83:         $class = get_class($_this);
 84:         $isProp = ObjectHelpers::hasProperty($class, $name);
 85: 
 86:         if ($name === '') {
 87:             throw new MemberAccessException("Call to class '$class' method without name.");
 88: 
 89:         } elseif ($isProp === 'event') { // calling event handlers
 90:             if (is_array($_this->$name) || $_this->$name instanceof \Traversable) {
 91:                 foreach ($_this->$name as $handler) {
 92:                     Callback::invokeArgs($handler, $args);
 93:                 }
 94:             } elseif ($_this->$name !== null) {
 95:                 throw new Nette\UnexpectedValueException("Property $class::$$name must be array or null, " . gettype($_this->$name) . ' given.');
 96:             }
 97: 
 98:         } elseif ($isProp && $_this->$name instanceof \Closure) { // closure in property
 99:             return call_user_func_array($_this->$name, $args);
100: 
101:         } elseif (($methods = &self::getMethods($class)) && isset($methods[$name]) && is_array($methods[$name])) { // magic @methods
102:             list($op, $rp, $type) = $methods[$name];
103:             if (count($args) !== ($op === 'get' ? 0 : 1)) {
104:                 throw new Nette\InvalidArgumentException("$class::$name() expects " . ($op === 'get' ? 'no' : '1') . ' argument, ' . count($args) . ' given.');
105: 
106:             } elseif ($type && $args && !self::checkType($args[0], $type)) {
107:                 throw new Nette\InvalidArgumentException("Argument passed to $class::$name() must be $type, " . gettype($args[0]) . ' given.');
108:             }
109: 
110:             if ($op === 'get') {
111:                 return $rp->getValue($_this);
112:             } elseif ($op === 'set') {
113:                 $rp->setValue($_this, $args[0]);
114:             } elseif ($op === 'add') {
115:                 $val = $rp->getValue($_this);
116:                 $val[] = $args[0];
117:                 $rp->setValue($_this, $val);
118:             }
119:             return $_this;
120: 
121:         } elseif ($cb = self::getExtensionMethod($class, $name)) { // extension methods
122:             return Callback::invoke($cb, $_this, ...$args);
123: 
124:         } else {
125:             ObjectHelpers::strictCall($class, $name, array_keys(self::getExtensionMethods($class)));
126:         }
127:     }
128: 
129: 
130:     /**
131:      * __callStatic() implementation.
132:      * @param  string
133:      * @param  string
134:      * @param  array
135:      * @return void
136:      * @throws MemberAccessException
137:      */
138:     public static function callStatic($class, $method, $args)
139:     {
140:         trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED);
141:         self::strictStaticCall($class, $method);
142:     }
143: 
144: 
145:     /**
146:      * __get() implementation.
147:      * @param  object
148:      * @param  string  property name
149:      * @return mixed   property value
150:      * @throws MemberAccessException if the property is not defined.
151:      */
152:     public static function &get($_this, $name)
153:     {
154:         $class = get_class($_this);
155:         $uname = ucfirst($name);
156:         $methods = &self::getMethods($class);
157: 
158:         if ($name === '') {
159:             throw new MemberAccessException("Cannot read a class '$class' property without name.");
160: 
161:         } elseif (isset($methods[$m = 'get' . $uname]) || isset($methods[$m = 'is' . $uname])) { // property getter
162:             if ($methods[$m] === 0) {
163:                 $methods[$m] = (new \ReflectionMethod($class, $m))->returnsReference();
164:             }
165:             if ($methods[$m] === true) {
166:                 return $_this->$m();
167:             } else {
168:                 $val = $_this->$m();
169:                 return $val;
170:             }
171: 
172:         } elseif (isset($methods[$name])) { // public method as closure getter
173:             if (preg_match('#^(is|get|has)([A-Z]|$)#', $name) && !(new \ReflectionMethod($class, $name))->getNumberOfRequiredParameters()) {
174:                 trigger_error("Did you forget parentheses after $name" . self::getSource() . '?', E_USER_WARNING);
175:             }
176:             $val = Callback::closure($_this, $name);
177:             return $val;
178: 
179:         } elseif (isset($methods['set' . $uname])) { // property getter
180:             throw new MemberAccessException("Cannot read a write-only property $class::\$$name.");
181: 
182:         } else {
183:             ObjectHelpers::strictGet($class, $name);
184:         }
185:     }
186: 
187: 
188:     /**
189:      * __set() implementation.
190:      * @param  object
191:      * @param  string  property name
192:      * @param  mixed   property value
193:      * @return void
194:      * @throws MemberAccessException if the property is not defined or is read-only
195:      */
196:     public static function set($_this, $name, $value)
197:     {
198:         trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED);
199:         $class = get_class($_this);
200:         $uname = ucfirst($name);
201:         $methods = &self::getMethods($class);
202: 
203:         if ($name === '') {
204:             throw new MemberAccessException("Cannot write to a class '$class' property without name.");
205: 
206:         } elseif (ObjectHelpers::hasProperty($class, $name)) { // unsetted property
207:             $_this->$name = $value;
208: 
209:         } elseif (isset($methods[$m = 'set' . $uname])) { // property setter
210:             $_this->$m($value);
211: 
212:         } elseif (isset($methods['get' . $uname]) || isset($methods['is' . $uname])) { // property setter
213:             throw new MemberAccessException("Cannot write to a read-only property $class::\$$name.");
214: 
215:         } else {
216:             ObjectHelpers::strictSet($class, $name);
217:         }
218:     }
219: 
220: 
221:     /**
222:      * __unset() implementation.
223:      * @param  object
224:      * @param  string  property name
225:      * @return void
226:      * @throws MemberAccessException
227:      */
228:     public static function remove($_this, $name)
229:     {
230:         trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED);
231:         $class = get_class($_this);
232:         if (!ObjectHelpers::hasProperty($class, $name)) {
233:             throw new MemberAccessException("Cannot unset the property $class::\$$name.");
234:         }
235:     }
236: 
237: 
238:     /**
239:      * __isset() implementation.
240:      * @param  object
241:      * @param  string  property name
242:      * @return bool
243:      */
244:     public static function has($_this, $name)
245:     {
246:         trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED);
247:         $name = ucfirst($name);
248:         $methods = &self::getMethods(get_class($_this));
249:         return $name !== '' && (isset($methods['get' . $name]) || isset($methods['is' . $name]));
250:     }
251: 
252: 
253:     /********************* magic @properties ****************d*g**/
254: 
255: 
256:     /**
257:      * @deprecated  use ObjectHelpers::strictStaticCall()
258:      */
259:     public static function getMagicProperties($class)
260:     {
261:         trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED);
262:         return ObjectHelpers::getMagicProperties($class);
263:     }
264: 
265: 
266:     /** @internal */
267:     public static function getMagicProperty($class, $name)
268:     {
269:         $props = ObjectHelpers::getMagicProperties($class);
270:         return isset($props[$name]) ? $props[$name] : null;
271:     }
272: 
273: 
274:     /********************* magic @methods ****************d*g**/
275: 
276: 
277:     /**
278:      * Returns array of magic methods defined by annotation @method.
279:      * @return array
280:      */
281:     public static function getMagicMethods($class)
282:     {
283:         trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED);
284:         $rc = new \ReflectionClass($class);
285:         preg_match_all('~^
286:             [ \t*]*  @method  [ \t]+
287:             (?: [^\s(]+  [ \t]+ )?
288:             (set|get|is|add)  ([A-Z]\w*)
289:             (?: ([ \t]* \()  [ \t]* ([^)$\s]*)  )?
290:         ()~mx', (string) $rc->getDocComment(), $matches, PREG_SET_ORDER);
291: 
292:         $methods = [];
293:         foreach ($matches as list(, $op, $prop, $bracket, $type)) {
294:             if ($bracket !== '(') {
295:                 trigger_error("Bracket must be immediately after @method $op$prop() in class $class.", E_USER_WARNING);
296:             }
297:             $name = $op . $prop;
298:             $prop = strtolower($prop[0]) . substr($prop, 1) . ($op === 'add' ? 's' : '');
299:             if ($rc->hasProperty($prop) && ($rp = $rc->getProperty($prop)) && !$rp->isStatic()) {
300:                 $rp->setAccessible(true);
301:                 if ($op === 'get' || $op === 'is') {
302:                     $type = null;
303:                     $op = 'get';
304:                 } elseif (!$type && preg_match('#@var[ \t]+(\S+)' . ($op === 'add' ? '\[\]#' : '#'), (string) $rp->getDocComment(), $m)) {
305:                     $type = $m[1];
306:                 }
307:                 if ($rc->inNamespace() && preg_match('#^[A-Z]\w+(\[|\||\z)#', (string) $type)) {
308:                     $type = $rc->getNamespaceName() . '\\' . $type;
309:                 }
310:                 $methods[$name] = [$op, $rp, $type];
311:             }
312:         }
313:         return $methods;
314:     }
315: 
316: 
317:     /**
318:      * Finds whether a variable is of expected type and do non-data-loss conversion.
319:      * @return bool
320:      * @internal
321:      */
322:     public static function checkType(&$val, $type)
323:     {
324:         trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED);
325:         if (strpos($type, '|') !== false) {
326:             $found = null;
327:             foreach (explode('|', $type) as $type) {
328:                 $tmp = $val;
329:                 if (self::checkType($tmp, $type)) {
330:                     if ($val === $tmp) {
331:                         return true;
332:                     }
333:                     $found[] = $tmp;
334:                 }
335:             }
336:             if ($found) {
337:                 $val = $found[0];
338:                 return true;
339:             }
340:             return false;
341: 
342:         } elseif (substr($type, -2) === '[]') {
343:             if (!is_array($val)) {
344:                 return false;
345:             }
346:             $type = substr($type, 0, -2);
347:             $res = [];
348:             foreach ($val as $k => $v) {
349:                 if (!self::checkType($v, $type)) {
350:                     return false;
351:                 }
352:                 $res[$k] = $v;
353:             }
354:             $val = $res;
355:             return true;
356:         }
357: 
358:         switch (strtolower($type)) {
359:             case null:
360:             case 'mixed':
361:                 return true;
362:             case 'bool':
363:             case 'boolean':
364:                 return ($val === null || is_scalar($val)) && settype($val, 'bool');
365:             case 'string':
366:                 return ($val === null || is_scalar($val) || (is_object($val) && method_exists($val, '__toString'))) && settype($val, 'string');
367:             case 'int':
368:             case 'integer':
369:                 return ($val === null || is_bool($val) || is_numeric($val)) && ((float) (int) $val === (float) $val) && settype($val, 'int');
370:             case 'float':
371:                 return ($val === null || is_bool($val) || is_numeric($val)) && settype($val, 'float');
372:             case 'scalar':
373:             case 'array':
374:             case 'object':
375:             case 'callable':
376:             case 'resource':
377:             case 'null':
378:                 return call_user_func("is_$type", $val);
379:             default:
380:                 return $val instanceof $type;
381:         }
382:     }
383: 
384: 
385:     /********************* extension methods ****************d*g**/
386: 
387: 
388:     /**
389:      * Adds a method to class.
390:      * @param  string
391:      * @param  string
392:      * @param  mixed   callable
393:      * @return void
394:      */
395:     public static function setExtensionMethod($class, $name, $callback)
396:     {
397:         $name = strtolower($name);
398:         self::$extMethods[$name][$class] = Callback::check($callback);
399:         self::$extMethods[$name][''] = null;
400:     }
401: 
402: 
403:     /**
404:      * Returns extension method.
405:      * @param  string
406:      * @param  string
407:      * @return mixed
408:      */
409:     public static function getExtensionMethod($class, $name)
410:     {
411:         $list = &self::$extMethods[strtolower($name)];
412:         $cache = &$list[''][$class];
413:         if (isset($cache)) {
414:             return $cache;
415:         }
416: 
417:         foreach ([$class] + class_parents($class) + class_implements($class) as $cl) {
418:             if (isset($list[$cl])) {
419:                 return $cache = $list[$cl];
420:             }
421:         }
422:         return $cache = false;
423:     }
424: 
425: 
426:     /**
427:      * Returns extension methods.
428:      * @param  string
429:      * @return array
430:      */
431:     public static function getExtensionMethods($class)
432:     {
433:         trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED);
434:         $res = [];
435:         foreach (array_keys(self::$extMethods) as $name) {
436:             if ($cb = self::getExtensionMethod($class, $name)) {
437:                 $res[$name] = $cb;
438:             }
439:         }
440:         return $res;
441:     }
442: 
443: 
444:     /********************* utilities ****************d*g**/
445: 
446: 
447:     /**
448:      * @deprecated  use ObjectHelpers::getSuggestion()
449:      */
450:     public static function getSuggestion(array $possibilities, $value)
451:     {
452:         return ObjectHelpers::getSuggestion($possibilities, $value);
453:     }
454: 
455: 
456:     /**
457:      * @deprecated  use ObjectHelpers::hasProperty()
458:      */
459:     public static function hasProperty($class, $name)
460:     {
461:         trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED);
462:         return ObjectHelpers::hasProperty($class, $name);
463:     }
464: 
465: 
466:     /**
467:      * Returns array of public (static, non-static and magic) methods.
468:      * @return array
469:      * @internal
470:      */
471:     public static function &getMethods($class)
472:     {
473:         static $cache;
474:         if (!isset($cache[$class])) {
475:             $cache[$class] = array_fill_keys(get_class_methods($class), 0) + @self::getMagicMethods($class); // is deprecated
476:             if ($parent = get_parent_class($class)) {
477:                 $cache[$class] += self::getMethods($parent);
478:             }
479:         }
480:         return $cache[$class];
481:     }
482: 
483: 
484:     /** @internal */
485:     public static function getSource()
486:     {
487:         foreach (debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS) as $item) {
488:             if (isset($item['file']) && dirname($item['file']) !== __DIR__) {
489:                 return " in $item[file]:$item[line]";
490:             }
491:         }
492:     }
493: }
494: 
Nette 2.4-20180918 API API documentation generated by ApiGen 2.8.0