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

  • Compiler
  • CompilerExtension
  • Container
  • ContainerBuilder
  • ContainerLoader
  • DependencyChecker
  • Helpers
  • PhpGenerator
  • PhpReflection
  • ServiceDefinition
  • Statement

Exceptions

  • MissingServiceException
  • ServiceCreationException
  • 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\DI;
  9: 
 10: use Nette;
 11: use Nette\Utils\Reflection;
 12: use ReflectionClass;
 13: use ReflectionMethod;
 14: 
 15: 
 16: /**
 17:  * Cache dependencies checker.
 18:  */
 19: class DependencyChecker
 20: {
 21:     use Nette\SmartObject;
 22: 
 23:     const VERSION = 1;
 24: 
 25:     /** @var array of ReflectionClass|\ReflectionFunctionAbstract|string */
 26:     private $dependencies = [];
 27: 
 28: 
 29:     /**
 30:      * Adds dependencies to the list.
 31:      * @return static
 32:      */
 33:     public function add(array $deps)
 34:     {
 35:         $this->dependencies = array_merge($this->dependencies, $deps);
 36:         return $this;
 37:     }
 38: 
 39: 
 40:     /**
 41:      * Exports dependencies.
 42:      * @return array
 43:      */
 44:     public function export()
 45:     {
 46:         $files = $phpFiles = $classes = $functions = [];
 47:         foreach ($this->dependencies as $dep) {
 48:             if (is_string($dep)) {
 49:                 $files[] = $dep;
 50: 
 51:             } elseif ($dep instanceof ReflectionClass) {
 52:                 if (empty($classes[$name = $dep->getName()])) {
 53:                     $all = [$name] + class_parents($name) + class_implements($name);
 54:                     foreach ($all as &$item) {
 55:                         $all += class_uses($item);
 56:                         $phpFiles[] = (new ReflectionClass($item))->getFileName();
 57:                         $classes[$item] = true;
 58:                     }
 59:                 }
 60: 
 61:             } elseif ($dep instanceof \ReflectionFunctionAbstract) {
 62:                 $phpFiles[] = $dep->getFileName();
 63:                 $functions[] = Reflection::toString($dep);
 64: 
 65:             } else {
 66:                 throw new Nette\InvalidStateException('Unexpected dependency ' . gettype($dep));
 67:             }
 68:         }
 69: 
 70:         $classes = array_keys($classes);
 71:         $functions = array_unique($functions, SORT_REGULAR);
 72:         $hash = self::calculateHash($classes, $functions);
 73:         $files = @array_map('filemtime', array_combine($files, $files)); // @ - file may not exist
 74:         $phpFiles = @array_map('filemtime', array_combine($phpFiles, $phpFiles)); // @ - file may not exist
 75:         return [self::VERSION, $files, $phpFiles, $classes, $functions, $hash];
 76:     }
 77: 
 78: 
 79:     /**
 80:      * Are dependencies expired?
 81:      * @return bool
 82:      */
 83:     public static function isExpired($version, $files, &$phpFiles, $classes, $functions, $hash)
 84:     {
 85:         $current = @array_map('filemtime', array_combine($tmp = array_keys($files), $tmp)); // @ - files may not exist
 86:         $origPhpFiles = $phpFiles;
 87:         $phpFiles = @array_map('filemtime', array_combine($tmp = array_keys($phpFiles), $tmp)); // @ - files may not exist
 88:         return $version !== self::VERSION
 89:             || $files !== $current
 90:             || ($phpFiles !== $origPhpFiles && $hash !== self::calculateHash($classes, $functions));
 91:     }
 92: 
 93: 
 94:     private static function calculateHash($classes, $functions)
 95:     {
 96:         $hash = [];
 97:         foreach ($classes as $name) {
 98:             try {
 99:                 $class = new ReflectionClass($name);
100:             } catch (\ReflectionException $e) {
101:                 return;
102:             }
103:             $hash[] = [
104:                 $name,
105:                 Reflection::getUseStatements($class),
106:                 $class->isAbstract(),
107:                 get_parent_class($name),
108:                 class_implements($name),
109:                 class_uses($name),
110:             ];
111: 
112:             foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC) as $prop) {
113:                 if ($prop->getDeclaringClass() == $class) { // intentionally ==
114:                     $hash[] = [$name, $prop->getName(), $prop->getDocComment()];
115:                 }
116:             }
117:             foreach ($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
118:                 if ($method->getDeclaringClass() == $class) { // intentionally ==
119:                     $hash[] = [
120:                         $name,
121:                         $method->getName(),
122:                         $method->getDocComment(),
123:                         self::hashParameters($method),
124:                         PHP_VERSION_ID >= 70000 && $method->hasReturnType()
125:                             ? [(string) $method->getReturnType(), $method->getReturnType()->allowsNull()]
126:                             : null,
127:                     ];
128:                 }
129:             }
130:         }
131: 
132:         $flip = array_flip($classes);
133:         foreach ($functions as $name) {
134:             try {
135:                 $method = strpos($name, '::') ? new ReflectionMethod($name) : new \ReflectionFunction($name);
136:             } catch (\ReflectionException $e) {
137:                 return;
138:             }
139:             $class = $method instanceof ReflectionMethod ? $method->getDeclaringClass() : null;
140:             if ($class && isset($flip[$class->getName()])) {
141:                 continue;
142:             }
143:             $hash[] = [
144:                 $name,
145:                 $class ? Reflection::getUseStatements($method->getDeclaringClass()) : null,
146:                 $method->getDocComment(),
147:                 self::hashParameters($method),
148:                 PHP_VERSION_ID >= 70000 && $method->hasReturnType()
149:                     ? [(string) $method->getReturnType(), $method->getReturnType()->allowsNull()]
150:                     : null,
151:             ];
152:         }
153: 
154:         return md5(serialize($hash));
155:     }
156: 
157: 
158:     private static function hashParameters(\ReflectionFunctionAbstract $method)
159:     {
160:         $res = [];
161:         if (PHP_VERSION_ID < 70000 && $method->getNumberOfParameters() && $method->getFileName()) {
162:             $res[] = file($method->getFileName())[$method->getStartLine() - 1];
163:         }
164:         foreach ($method->getParameters() as $param) {
165:             $res[] = [
166:                 $param->getName(),
167:                 PHP_VERSION_ID >= 70000 ? [Reflection::getParameterType($param), $param->allowsNull()] : null,
168:                 $param->isVariadic(),
169:                 $param->isDefaultValueAvailable()
170:                     ? [Reflection::getParameterDefaultValue($param)]
171:                     : null,
172:             ];
173:         }
174:         return $res;
175:     }
176: }
177: 
Nette 2.4-20180918 API API documentation generated by ApiGen 2.8.0