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
    • Reflection
    • Security
    • Utils
  • none
  • Tracy
    • Bridges
      • Nette

Classes

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

Exceptions

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