Actualización

This commit is contained in:
Xes
2025-04-10 12:24:57 +02:00
parent 8969cc929d
commit 45420b6f0d
39760 changed files with 4303286 additions and 0 deletions

View File

@@ -0,0 +1,238 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Config\Resource;
/**
* ClassExistenceResource represents a class existence.
* Freshness is only evaluated against resource existence.
*
* The resource must be a fully-qualified class name.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class ClassExistenceResource implements SelfCheckingResourceInterface, \Serializable
{
private $resource;
private $exists;
private static $autoloadLevel = 0;
private static $autoloadedClass;
private static $existsCache = [];
/**
* @param string $resource The fully-qualified class name
* @param bool|null $exists Boolean when the existency check has already been done
*/
public function __construct($resource, $exists = null)
{
$this->resource = $resource;
if (null !== $exists) {
$this->exists = [(bool) $exists, null];
}
}
/**
* {@inheritdoc}
*/
public function __toString()
{
return $this->resource;
}
/**
* @return string The file path to the resource
*/
public function getResource()
{
return $this->resource;
}
/**
* {@inheritdoc}
*
* @throws \ReflectionException when a parent class/interface/trait is not found
*/
public function isFresh($timestamp)
{
$loaded = class_exists($this->resource, false) || interface_exists($this->resource, false) || trait_exists($this->resource, false);
if (null !== $exists = &self::$existsCache[$this->resource]) {
if ($loaded) {
$exists = [true, null];
} elseif (0 >= $timestamp && !$exists[0] && null !== $exists[1]) {
throw new \ReflectionException($exists[1]);
}
} elseif ([false, null] === $exists = [$loaded, null]) {
if (!self::$autoloadLevel++) {
spl_autoload_register(__CLASS__.'::throwOnRequiredClass');
}
$autoloadedClass = self::$autoloadedClass;
self::$autoloadedClass = ltrim($this->resource, '\\');
try {
$exists[0] = class_exists($this->resource) || interface_exists($this->resource, false) || trait_exists($this->resource, false);
} catch (\Exception $e) {
$exists[1] = $e->getMessage();
try {
self::throwOnRequiredClass($this->resource, $e);
} catch (\ReflectionException $e) {
if (0 >= $timestamp) {
throw $e;
}
}
} catch (\Throwable $e) {
$exists[1] = $e->getMessage();
throw $e;
} finally {
self::$autoloadedClass = $autoloadedClass;
if (!--self::$autoloadLevel) {
spl_autoload_unregister(__CLASS__.'::throwOnRequiredClass');
}
}
}
if (null === $this->exists) {
$this->exists = $exists;
}
return $this->exists[0] xor !$exists[0];
}
/**
* @internal
*/
public function serialize()
{
if (null === $this->exists) {
$this->isFresh(0);
}
return serialize([$this->resource, $this->exists]);
}
/**
* @internal
*/
public function unserialize($serialized)
{
list($this->resource, $this->exists) = unserialize($serialized);
if (\is_bool($this->exists)) {
$this->exists = [$this->exists, null];
}
}
/**
* Throws a reflection exception when the passed class does not exist but is required.
*
* A class is considered "not required" when it's loaded as part of a "class_exists" or similar check.
*
* This function can be used as an autoload function to throw a reflection
* exception if the class was not found by previous autoload functions.
*
* A previous exception can be passed. In this case, the class is considered as being
* required totally, so if it doesn't exist, a reflection exception is always thrown.
* If it exists, the previous exception is rethrown.
*
* @throws \ReflectionException
*
* @internal
*/
public static function throwOnRequiredClass($class, \Exception $previous = null)
{
// If the passed class is the resource being checked, we shouldn't throw.
if (null === $previous && self::$autoloadedClass === $class) {
return;
}
if (class_exists($class, false) || interface_exists($class, false) || trait_exists($class, false)) {
if (null !== $previous) {
throw $previous;
}
return;
}
if ($previous instanceof \ReflectionException) {
throw $previous;
}
$message = sprintf('Class "%s" not found.', $class);
if (self::$autoloadedClass !== $class) {
$message = substr_replace($message, sprintf(' while loading "%s"', self::$autoloadedClass), -1, 0);
}
if (null !== $previous) {
$message = $previous->getMessage();
}
$e = new \ReflectionException($message, 0, $previous);
if (null !== $previous) {
throw $e;
}
$trace = debug_backtrace();
$autoloadFrame = [
'function' => 'spl_autoload_call',
'args' => [$class],
];
if (\PHP_VERSION_ID >= 80000 && isset($trace[1])) {
$callerFrame = $trace[1];
$i = 2;
} elseif (false !== $i = array_search($autoloadFrame, $trace, true)) {
$callerFrame = $trace[++$i];
} else {
throw $e;
}
if (isset($callerFrame['function']) && !isset($callerFrame['class'])) {
switch ($callerFrame['function']) {
case 'get_class_methods':
case 'get_class_vars':
case 'get_parent_class':
case 'is_a':
case 'is_subclass_of':
case 'class_exists':
case 'class_implements':
case 'class_parents':
case 'trait_exists':
case 'defined':
case 'interface_exists':
case 'method_exists':
case 'property_exists':
case 'is_callable':
return;
}
$props = [
'file' => isset($callerFrame['file']) ? $callerFrame['file'] : null,
'line' => isset($callerFrame['line']) ? $callerFrame['line'] : null,
'trace' => \array_slice($trace, 1 + $i),
];
foreach ($props as $p => $v) {
if (null !== $v) {
$r = new \ReflectionProperty('Exception', $p);
$r->setAccessible(true);
$r->setValue($e, $v);
}
}
}
throw $e;
}
}

View File

@@ -0,0 +1,84 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Config\Resource;
/**
* ComposerResource tracks the PHP version and Composer dependencies.
*
* @author Nicolas Grekas <p@tchwork.com>
*/
class ComposerResource implements SelfCheckingResourceInterface, \Serializable
{
private $vendors;
private static $runtimeVendors;
public function __construct()
{
self::refresh();
$this->vendors = self::$runtimeVendors;
}
public function getVendors()
{
return array_keys($this->vendors);
}
/**
* {@inheritdoc}
*/
public function __toString()
{
return __CLASS__;
}
/**
* {@inheritdoc}
*/
public function isFresh($timestamp)
{
self::refresh();
return array_values(self::$runtimeVendors) === array_values($this->vendors);
}
/**
* @internal
*/
public function serialize()
{
return serialize($this->vendors);
}
/**
* @internal
*/
public function unserialize($serialized)
{
$this->vendors = unserialize($serialized);
}
private static function refresh()
{
self::$runtimeVendors = [];
foreach (get_declared_classes() as $class) {
if ('C' === $class[0] && 0 === strpos($class, 'ComposerAutoloaderInit')) {
$r = new \ReflectionClass($class);
$v = \dirname(\dirname($r->getFileName()));
if (file_exists($v.'/composer/installed.json')) {
self::$runtimeVendors[$v] = @filemtime($v.'/composer/installed.json');
}
}
}
}
}

View File

@@ -0,0 +1,122 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Config\Resource;
/**
* DirectoryResource represents a resources stored in a subdirectory tree.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class DirectoryResource implements SelfCheckingResourceInterface, \Serializable
{
private $resource;
private $pattern;
/**
* @param string $resource The file path to the resource
* @param string|null $pattern A pattern to restrict monitored files
*
* @throws \InvalidArgumentException
*/
public function __construct($resource, $pattern = null)
{
$this->resource = realpath($resource) ?: (file_exists($resource) ? $resource : false);
$this->pattern = $pattern;
if (false === $this->resource || !is_dir($this->resource)) {
throw new \InvalidArgumentException(sprintf('The directory "%s" does not exist.', $resource));
}
}
/**
* {@inheritdoc}
*/
public function __toString()
{
return md5(serialize([$this->resource, $this->pattern]));
}
/**
* @return string The file path to the resource
*/
public function getResource()
{
return $this->resource;
}
/**
* Returns the pattern to restrict monitored files.
*
* @return string|null
*/
public function getPattern()
{
return $this->pattern;
}
/**
* {@inheritdoc}
*/
public function isFresh($timestamp)
{
if (!is_dir($this->resource)) {
return false;
}
if ($timestamp < filemtime($this->resource)) {
return false;
}
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->resource), \RecursiveIteratorIterator::SELF_FIRST) as $file) {
// if regex filtering is enabled only check matching files
if ($this->pattern && $file->isFile() && !preg_match($this->pattern, $file->getBasename())) {
continue;
}
// always monitor directories for changes, except the .. entries
// (otherwise deleted files wouldn't get detected)
if ($file->isDir() && '/..' === substr($file, -3)) {
continue;
}
// for broken links
try {
$fileMTime = $file->getMTime();
} catch (\RuntimeException $e) {
continue;
}
// early return if a file's mtime exceeds the passed timestamp
if ($timestamp < $fileMTime) {
return false;
}
}
return true;
}
/**
* @internal
*/
public function serialize()
{
return serialize([$this->resource, $this->pattern]);
}
/**
* @internal
*/
public function unserialize($serialized)
{
list($this->resource, $this->pattern) = unserialize($serialized);
}
}

View File

@@ -0,0 +1,76 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Config\Resource;
/**
* FileExistenceResource represents a resource stored on the filesystem.
* Freshness is only evaluated against resource creation or deletion.
*
* The resource can be a file or a directory.
*
* @author Charles-Henri Bruyand <charleshenri.bruyand@gmail.com>
*/
class FileExistenceResource implements SelfCheckingResourceInterface, \Serializable
{
private $resource;
private $exists;
/**
* @param string $resource The file path to the resource
*/
public function __construct($resource)
{
$this->resource = (string) $resource;
$this->exists = file_exists($resource);
}
/**
* {@inheritdoc}
*/
public function __toString()
{
return $this->resource;
}
/**
* @return string The file path to the resource
*/
public function getResource()
{
return $this->resource;
}
/**
* {@inheritdoc}
*/
public function isFresh($timestamp)
{
return file_exists($this->resource) === $this->exists;
}
/**
* @internal
*/
public function serialize()
{
return serialize([$this->resource, $this->exists]);
}
/**
* @internal
*/
public function unserialize($serialized)
{
list($this->resource, $this->exists) = unserialize($serialized);
}
}

View File

@@ -0,0 +1,81 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Config\Resource;
/**
* FileResource represents a resource stored on the filesystem.
*
* The resource can be a file or a directory.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class FileResource implements SelfCheckingResourceInterface, \Serializable
{
/**
* @var string|false
*/
private $resource;
/**
* @param string $resource The file path to the resource
*
* @throws \InvalidArgumentException
*/
public function __construct($resource)
{
$this->resource = realpath($resource) ?: (file_exists($resource) ? $resource : false);
if (false === $this->resource) {
throw new \InvalidArgumentException(sprintf('The file "%s" does not exist.', $resource));
}
}
/**
* {@inheritdoc}
*/
public function __toString()
{
return $this->resource;
}
/**
* @return string The canonicalized, absolute path to the resource
*/
public function getResource()
{
return $this->resource;
}
/**
* {@inheritdoc}
*/
public function isFresh($timestamp)
{
return false !== ($filemtime = @filemtime($this->resource)) && $filemtime <= $timestamp;
}
/**
* @internal
*/
public function serialize()
{
return serialize($this->resource);
}
/**
* @internal
*/
public function unserialize($serialized)
{
$this->resource = unserialize($serialized);
}
}

View File

@@ -0,0 +1,159 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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\Finder\Finder;
use Symfony\Component\Finder\Glob;
/**
* GlobResource represents a set of resources stored on the filesystem.
*
* Only existence/removal is tracked (not mtimes.)
*
* @author Nicolas Grekas <p@tchwork.com>
*/
class GlobResource implements \IteratorAggregate, SelfCheckingResourceInterface, \Serializable
{
private $prefix;
private $pattern;
private $recursive;
private $hash;
/**
* @param string $prefix A directory prefix
* @param string $pattern A glob pattern
* @param bool $recursive Whether directories should be scanned recursively or not
*
* @throws \InvalidArgumentException
*/
public function __construct($prefix, $pattern, $recursive)
{
$this->prefix = realpath($prefix) ?: (file_exists($prefix) ? $prefix : false);
$this->pattern = $pattern;
$this->recursive = $recursive;
if (false === $this->prefix) {
throw new \InvalidArgumentException(sprintf('The path "%s" does not exist.', $prefix));
}
}
public function getPrefix()
{
return $this->prefix;
}
/**
* {@inheritdoc}
*/
public function __toString()
{
return 'glob.'.$this->prefix.$this->pattern.(int) $this->recursive;
}
/**
* {@inheritdoc}
*/
public function isFresh($timestamp)
{
$hash = $this->computeHash();
if (null === $this->hash) {
$this->hash = $hash;
}
return $this->hash === $hash;
}
/**
* @internal
*/
public function serialize()
{
if (null === $this->hash) {
$this->hash = $this->computeHash();
}
return serialize([$this->prefix, $this->pattern, $this->recursive, $this->hash]);
}
/**
* @internal
*/
public function unserialize($serialized)
{
list($this->prefix, $this->pattern, $this->recursive, $this->hash) = unserialize($serialized);
}
public function getIterator()
{
if (!file_exists($this->prefix) || (!$this->recursive && '' === $this->pattern)) {
return;
}
if (0 !== strpos($this->prefix, 'phar://') && false === strpos($this->pattern, '/**/') && (\defined('GLOB_BRACE') || false === strpos($this->pattern, '{'))) {
$paths = glob($this->prefix.$this->pattern, \GLOB_NOSORT | (\defined('GLOB_BRACE') ? \GLOB_BRACE : 0));
sort($paths);
foreach ($paths as $path) {
if ($this->recursive && is_dir($path)) {
$files = iterator_to_array(new \RecursiveIteratorIterator(
new \RecursiveCallbackFilterIterator(
new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS),
function (\SplFileInfo $file) { return '.' !== $file->getBasename()[0]; }
),
\RecursiveIteratorIterator::LEAVES_ONLY
));
uasort($files, function (\SplFileInfo $a, \SplFileInfo $b) {
return (string) $a > (string) $b ? 1 : -1;
});
foreach ($files as $path => $info) {
if ($info->isFile()) {
yield $path => $info;
}
}
} elseif (is_file($path)) {
yield $path => new \SplFileInfo($path);
}
}
return;
}
if (!class_exists(Finder::class)) {
throw new \LogicException(sprintf('Extended glob pattern "%s" cannot be used as the Finder component is not installed.', $this->pattern));
}
$finder = new Finder();
$regex = Glob::toRegex($this->pattern);
if ($this->recursive) {
$regex = substr_replace($regex, '(/|$)', -2, 1);
}
$prefixLen = \strlen($this->prefix);
foreach ($finder->followLinks()->sortByName()->in($this->prefix) as $path => $info) {
if (preg_match($regex, substr('\\' === \DIRECTORY_SEPARATOR ? str_replace('\\', '/', $path) : $path, $prefixLen)) && $info->isFile()) {
yield $path => $info;
}
}
}
private function computeHash()
{
$hash = hash_init('md5');
foreach ($this->getIterator() as $path => $info) {
hash_update($hash, $path."\n");
}
return hash_final($hash);
}
}

View File

@@ -0,0 +1,256 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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 <p@tchwork.com>
*/
class ReflectionClassResource implements SelfCheckingResourceInterface, \Serializable
{
private $files = [];
private $className;
private $classReflector;
private $excludedVendors = [];
private $hash;
public function __construct(\ReflectionClass $classReflector, $excludedVendors = [])
{
$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;
}
/**
* @internal
*/
public function serialize()
{
if (null === $this->hash) {
$this->hash = $this->computeHash();
$this->loadFiles($this->classReflector);
}
return serialize([$this->files, $this->className, $this->hash]);
}
/**
* @internal
*/
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();
yield $p->isDefault() ? '<default>' : '';
yield $p->isPublic() ? 'public' : 'protected';
yield $p->isStatic() ? 'static' : '';
yield '$'.$p->name;
yield print_r(isset($defaults[$p->name]) && !\is_object($defaults[$p->name]) ? $defaults[$p->name] : null, 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) {
$defaults = [];
$parametersWithUndefinedConstants = [];
foreach ($m->getParameters() as $p) {
if (!$p->isDefaultValueAvailable()) {
$defaults[$p->name] = null;
continue;
}
if (!$p->isDefaultValueConstant() || \defined($p->getDefaultValueConstantName())) {
$defaults[$p->name] = $p->getDefaultValue();
continue;
}
$defaults[$p->name] = $p->getDefaultValueConstantName();
$parametersWithUndefinedConstants[$p->name] = true;
}
if (!$parametersWithUndefinedConstants) {
yield preg_replace('/^ @@.*/m', '', $m);
} else {
$t = \PHP_VERSION_ID >= 70000 ? $m->getReturnType() : '';
$stack = [
$m->getDocComment(),
$m->getName(),
$m->isAbstract(),
$m->isFinal(),
$m->isStatic(),
$m->isPublic(),
$m->isPrivate(),
$m->isProtected(),
$m->returnsReference(),
$t instanceof \ReflectionNamedType ? ((string) $t->allowsNull()).$t->getName() : (string) $t,
];
foreach ($m->getParameters() as $p) {
if (!isset($parametersWithUndefinedConstants[$p->name])) {
$stack[] = (string) $p;
} else {
$t = \PHP_VERSION_ID >= 70000 ? $p->getType() : '';
$stack[] = $p->isOptional();
$stack[] = $t instanceof \ReflectionNamedType ? ((string) $t->allowsNull()).$t->getName() : (string) $t;
$stack[] = $p->isPassedByReference();
$stack[] = \PHP_VERSION_ID >= 50600 ? $p->isVariadic() : '';
$stack[] = $p->getName();
}
}
yield implode(',', $stack);
}
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([$class->name, 'getSubscribedEvents']), true);
}
if (interface_exists(ServiceSubscriberInterface::class, false) && $class->isSubclassOf(ServiceSubscriberInterface::class)) {
yield ServiceSubscriberInterface::class;
yield print_r(\call_user_func([$class->name, 'getSubscribedServices']), true);
}
}
}
/**
* @internal
*/
class ReflectionMethodHhvmWrapper extends \ReflectionMethod
{
public function getParameters()
{
$params = [];
foreach (parent::getParameters() as $i => $p) {
$params[] = new ReflectionParameterHhvmWrapper([$this->class, $this->name], $i);
}
return $params;
}
}
/**
* @internal
*/
class ReflectionParameterHhvmWrapper extends \ReflectionParameter
{
public function getDefaultValue()
{
return [$this->isVariadic(), $this->isDefaultValueAvailable() ? parent::getDefaultValue() : null];
}
}

View File

@@ -0,0 +1,33 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Config\Resource;
/**
* ResourceInterface is the interface that must be implemented by all Resource classes.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
interface ResourceInterface
{
/**
* Returns a string representation of the Resource.
*
* This method is necessary to allow for resource de-duplication, for example by means
* of array_unique(). The string returned need not have a particular meaning, but has
* to be identical for different ResourceInterface instances referring to the same
* resource; and it should be unlikely to collide with that of other, unrelated
* resource instances.
*
* @return string A string representation unique to the underlying Resource
*/
public function __toString();
}

View File

@@ -0,0 +1,36 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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\Config\ResourceCheckerInterface;
/**
* Resource checker for instances of SelfCheckingResourceInterface.
*
* As these resources perform the actual check themselves, we can provide
* this class as a standard way of validating them.
*
* @author Matthias Pigulla <mp@webfactory.de>
*/
class SelfCheckingResourceChecker implements ResourceCheckerInterface
{
public function supports(ResourceInterface $metadata)
{
return $metadata instanceof SelfCheckingResourceInterface;
}
public function isFresh(ResourceInterface $resource, $timestamp)
{
/* @var SelfCheckingResourceInterface $resource */
return $resource->isFresh($timestamp);
}
}

View File

@@ -0,0 +1,30 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Config\Resource;
/**
* Interface for Resources that can check for freshness autonomously,
* without special support from external services.
*
* @author Matthias Pigulla <mp@webfactory.de>
*/
interface SelfCheckingResourceInterface extends ResourceInterface
{
/**
* Returns true if the resource has not been updated since the given timestamp.
*
* @param int $timestamp The last time the resource was loaded
*
* @return bool True if the resource has not been updated, false otherwise
*/
public function isFresh($timestamp);
}