* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Config\Resource; use Symfony\Component\DependencyInjection\ServiceSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** * @author Nicolas Grekas */ class ReflectionClassResource implements SelfCheckingResourceInterface, \Serializable { private $files = array(); private $className; private $classReflector; private $excludedVendors = array(); private $hash; public function __construct(\ReflectionClass $classReflector, $excludedVendors = array()) { $this->className = $classReflector->name; $this->classReflector = $classReflector; $this->excludedVendors = $excludedVendors; } public function isFresh($timestamp) { if (null === $this->hash) { $this->hash = $this->computeHash(); $this->loadFiles($this->classReflector); } foreach ($this->files as $file => $v) { if (false === $filemtime = @filemtime($file)) { return false; } if ($filemtime > $timestamp) { return $this->hash === $this->computeHash(); } } return true; } public function __toString() { return 'reflection.'.$this->className; } public function serialize() { if (null === $this->hash) { $this->hash = $this->computeHash(); $this->loadFiles($this->classReflector); } return serialize(array($this->files, $this->className, $this->hash)); } public function unserialize($serialized) { list($this->files, $this->className, $this->hash) = unserialize($serialized); } private function loadFiles(\ReflectionClass $class) { foreach ($class->getInterfaces() as $v) { $this->loadFiles($v); } do { $file = $class->getFileName(); if (false !== $file && file_exists($file)) { foreach ($this->excludedVendors as $vendor) { if (0 === strpos($file, $vendor) && false !== strpbrk(substr($file, strlen($vendor), 1), '/'.DIRECTORY_SEPARATOR)) { $file = false; break; } } if ($file) { $this->files[$file] = null; } } foreach ($class->getTraits() as $v) { $this->loadFiles($v); } } while ($class = $class->getParentClass()); } private function computeHash() { if (null === $this->classReflector) { try { $this->classReflector = new \ReflectionClass($this->className); } catch (\ReflectionException $e) { // the class does not exist anymore return false; } } $hash = hash_init('md5'); foreach ($this->generateSignature($this->classReflector) as $info) { hash_update($hash, $info); } return hash_final($hash); } private function generateSignature(\ReflectionClass $class) { yield $class->getDocComment(); yield (int) $class->isFinal(); yield (int) $class->isAbstract(); if ($class->isTrait()) { yield print_r(class_uses($class->name), true); } else { yield print_r(class_parents($class->name), true); yield print_r(class_implements($class->name), true); yield print_r($class->getConstants(), true); } if (!$class->isInterface()) { $defaults = $class->getDefaultProperties(); foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC | \ReflectionProperty::IS_PROTECTED) as $p) { yield $p->getDocComment().$p; // yield print_r($defaults[$p->name], true); } } if (defined('HHVM_VERSION')) { foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED) as $m) { // workaround HHVM bug with variadics, see https://github.com/facebook/hhvm/issues/5762 yield preg_replace('/^ @@.*/m', '', new ReflectionMethodHhvmWrapper($m->class, $m->name)); } } else { foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED) as $m) { yield preg_replace('/^ @@.*/m', '', $m); $defaults = array(); foreach ($m->getParameters() as $p) { $defaults[$p->name] = $p->isDefaultValueAvailable() ? $p->getDefaultValue() : null; } yield print_r($defaults, true); } } if ($class->isAbstract() || $class->isInterface() || $class->isTrait()) { return; } if (interface_exists(EventSubscriberInterface::class, false) && $class->isSubclassOf(EventSubscriberInterface::class)) { yield EventSubscriberInterface::class; yield print_r(\call_user_func(array($class->name, 'getSubscribedEvents')), true); } if (interface_exists(ServiceSubscriberInterface::class, false) && $class->isSubclassOf(ServiceSubscriberInterface::class)) { yield ServiceSubscriberInterface::class; yield print_r(\call_user_func(array($class->name, 'getSubscribedServices')), true); } } } /** * @internal */ class ReflectionMethodHhvmWrapper extends \ReflectionMethod { public function getParameters() { $params = array(); foreach (parent::getParameters() as $i => $p) { $params[] = new ReflectionParameterHhvmWrapper(array($this->class, $this->name), $i); } return $params; } } /** * @internal */ class ReflectionParameterHhvmWrapper extends \ReflectionParameter { public function getDefaultValue() { return array($this->isVariadic(), $this->isDefaultValueAvailable() ? parent::getDefaultValue() : null); } } __halt_compiler();----SIGNATURE:----sMlcb2NYD7plEzYVgVgJTLLgX1g4e66qfyMcpTp/Jx2oNBaEXhT2eSj8uPZOGS6qLGceeF7Wk3dwgPBqhuvAAYpx7+f9t5WZJoy6Hd0bjxRhps/5STVY4t7zT3fWwTXX6nhqGH/GJaquy1gey1MtSFw1pcD7C83JDwnwCh+cajyFSM6/qMifAlYcKcXQI0E63xEcLhkU5JgnlGBAO0pdK76flkbYBYLgvsI6GvpW4g/m93euVlJvzfey3AZraf7HPeyiXruS8HnWySZobUAB6cZq/u7cR/vyDK3T+zFmIIOLyD01K6JuIi3KVwsCBgixBHhNfu0cZMnjjvWt6T8MSqKNV+Ce99aJseNWmvHz/+uXdcKBWnrtZU16t1LU/7UhU3ad4jt6AFlDYVBaK1L6QKsacEYADgd3rE4Jx8pMMPABk5eCNmqaWCiN20aYz+mDyfMqEiy9o6gg3Xj9AiOnwSKvR+eM4K+Wf7UfPxQx8TV3vHYjqgUv0mEoSJBwcv93O2k05yz1XDbHWyLu1dg41Ld1mEOI/vDq30wjrslczZnoqdzsSk94FJfhAsQaaoTLlIl82YGETuL3pj0fTagbDUVm93byBWfIta/Dgo5KdW+snVIEJOoEedjP0Rk49Tc2RbsTWEnpV8r75JXPl6EJ8E/1nHvdrV0oS0dCrE4Gxyw=----ATTACHMENT:----NjE5ODE5OTk5Nzc5MTAxOSA3NTQ1NjA3MDkwMjUwNjkyIDM4NzA5NTQwMjk4MDA1MzQ=