From 898203649f0301a38d11095a9b787d2349549004 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 29 Apr 2018 16:58:54 +0200 Subject: [PATCH] Added symfony/contracts: a set of abstractions extracted out of the components --- .github/build-packages.php | 2 +- .travis.yml | 4 +- composer.json | 4 +- phpunit.xml.dist | 3 + .../Doctrine/Form/Type/DoctrineType.php | 3 +- src/Symfony/Bridge/Doctrine/composer.json | 1 + src/Symfony/Bridge/Monolog/Logger.php | 11 ++- .../Monolog/Processor/DebugProcessor.php | 11 ++- src/Symfony/Bridge/Monolog/composer.json | 1 + .../FrameworkExtension.php | 4 +- .../Component/Cache/Adapter/ChainAdapter.php | 3 +- .../Cache/Adapter/TraceableAdapter.php | 3 +- .../Component/Cache/DoctrineProvider.php | 3 +- .../Component/Cache/ResettableInterface.php | 5 +- .../Component/Cache/Simple/ChainCache.php | 3 +- .../Component/Cache/Simple/TraceableCache.php | 3 +- .../Component/Cache/Traits/ProxyTrait.php | 4 +- src/Symfony/Component/Cache/composer.json | 3 +- .../Formatter/OutputFormatterStyleStack.php | 3 +- src/Symfony/Component/Console/composer.json | 1 + .../ResettableContainerInterface.php | 4 +- .../DependencyInjection/composer.json | 3 +- .../TraceableEventDispatcherInterface.php | 8 +-- .../Component/EventDispatcher/composer.json | 3 +- .../Component/ExpressionLanguage/Compiler.php | 4 +- .../ExpressionLanguage/composer.json | 3 +- .../DataCollector/DataCollectorInterface.php | 8 +-- .../DataCollector/EventDataCollector.php | 3 +- .../DependencyInjection/ServicesResetter.php | 4 +- .../HttpKernel/Profiler/Profiler.php | 3 +- .../Component/HttpKernel/composer.json | 1 + .../Token/Storage/TokenStorage.php | 8 ++- .../Component/Security/Core/composer.json | 3 +- src/Symfony/Component/Security/composer.json | 1 + src/Symfony/Component/Stopwatch/Stopwatch.php | 4 +- src/Symfony/Component/Stopwatch/composer.json | 3 +- .../Validator/TraceableValidator.php | 3 +- src/Symfony/Component/Validator/composer.json | 1 + src/Symfony/Contract/.gitignore | 3 + src/Symfony/Contract/CHANGELOG.md | 7 ++ src/Symfony/Contract/LICENSE | 19 ++++++ src/Symfony/Contract/README.md | 68 +++++++++++++++++++ .../Contract/Service/ResetInterface.php | 30 ++++++++ src/Symfony/Contract/composer.json | 33 +++++++++ src/Symfony/Contract/phpunit.xml.dist | 31 +++++++++ 45 files changed, 288 insertions(+), 45 deletions(-) create mode 100644 src/Symfony/Contract/.gitignore create mode 100644 src/Symfony/Contract/CHANGELOG.md create mode 100644 src/Symfony/Contract/LICENSE create mode 100644 src/Symfony/Contract/README.md create mode 100644 src/Symfony/Contract/Service/ResetInterface.php create mode 100644 src/Symfony/Contract/composer.json create mode 100644 src/Symfony/Contract/phpunit.xml.dist diff --git a/.github/build-packages.php b/.github/build-packages.php index b67a699609..7ab54f11e3 100644 --- a/.github/build-packages.php +++ b/.github/build-packages.php @@ -49,7 +49,7 @@ foreach ($dirs as $k => $dir) { $packages[$package->name][$package->version] = $package; - $versions = file_get_contents('https://packagist.org/p/'.$package->name.'.json'); + $versions = @file_get_contents('https://packagist.org/p/'.$package->name.'.json') ?: sprintf('{"packages":{"%s":{"dev-master":%s}}}', $package->name, file_get_contents($dir.'/composer.json')); $versions = json_decode($versions)->packages->{$package->name}; if ($package->version === str_replace('-dev', '.x-dev', $versions->{'dev-master'}->extra->{'branch-alias'}->{'dev-master'})) { diff --git a/.travis.yml b/.travis.yml index b76383fb1d..edf86a7e51 100644 --- a/.travis.yml +++ b/.travis.yml @@ -124,7 +124,7 @@ before_install: deps=skip skip=1 else - COMPONENTS=$(find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist -printf '%h\n') + COMPONENTS=$(find src/Symfony -mindepth 2 -type f -name phpunit.xml.dist -printf '%h\n') fi - | @@ -181,7 +181,7 @@ install: SYMFONY_VERSION=$(git ls-remote --heads | grep -o '/[1-9].*' | tail -n 1 | sed s/.//) && git fetch origin $SYMFONY_VERSION && git checkout -m FETCH_HEAD && - COMPONENTS=$(find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist -printf '%h\n') + COMPONENTS=$(find src/Symfony -mindepth 2 -type f -name phpunit.xml.dist -printf '%h\n') elif [[ ! $skip ]]; then SYMFONY_VERSION=$(cat composer.json | grep '^ *"dev-master". *"[1-9]' | grep -o '[0-9.]*') fi diff --git a/composer.json b/composer.json index aae26f83b5..a53a578f8a 100644 --- a/composer.json +++ b/composer.json @@ -37,6 +37,7 @@ "symfony/cache": "self.version", "symfony/config": "self.version", "symfony/console": "self.version", + "symfony/contracts": "1.0.0", "symfony/css-selector": "self.version", "symfony/dependency-injection": "self.version", "symfony/debug": "self.version", @@ -118,7 +119,8 @@ "Symfony\\Bridge\\ProxyManager\\": "src/Symfony/Bridge/ProxyManager/", "Symfony\\Bridge\\Twig\\": "src/Symfony/Bridge/Twig/", "Symfony\\Bundle\\": "src/Symfony/Bundle/", - "Symfony\\Component\\": "src/Symfony/Component/" + "Symfony\\Component\\": "src/Symfony/Component/", + "Symfony\\Contract\\": "src/Symfony/Contract/" }, "classmap": [ "src/Symfony/Component/Intl/Resources/stubs" diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 59ec772525..7b808fd674 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -26,6 +26,7 @@ ./src/Symfony/Bridge/*/Tests/ ./src/Symfony/Component/*/Tests/ ./src/Symfony/Component/*/*/Tests/ + ./src/Symfony/Contract/*/Tests/ ./src/Symfony/Bundle/*/Tests/ @@ -44,6 +45,7 @@ ./src/Symfony/Bridge/*/Tests ./src/Symfony/Component/*/Tests ./src/Symfony/Component/*/*/Tests + ./src/Symfony/Contract/*/Tests ./src/Symfony/Bundle/*/Tests ./src/Symfony/Bundle/*/Resources ./src/Symfony/Component/*/Resources @@ -52,6 +54,7 @@ ./src/Symfony/Bundle/*/vendor ./src/Symfony/Component/*/vendor ./src/Symfony/Component/*/*/vendor + ./src/Symfony/Contract/*/vendor diff --git a/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php b/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php index 25b0aefecf..acb4fa1225 100644 --- a/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php +++ b/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php @@ -24,8 +24,9 @@ use Symfony\Component\Form\Exception\RuntimeException; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\Options; use Symfony\Component\OptionsResolver\OptionsResolver; +use Symfony\Contract\Service\ResetInterface; -abstract class DoctrineType extends AbstractType +abstract class DoctrineType extends AbstractType implements ResetInterface { /** * @var ManagerRegistry diff --git a/src/Symfony/Bridge/Doctrine/composer.json b/src/Symfony/Bridge/Doctrine/composer.json index 0a9bec6d91..c73068995e 100644 --- a/src/Symfony/Bridge/Doctrine/composer.json +++ b/src/Symfony/Bridge/Doctrine/composer.json @@ -18,6 +18,7 @@ "require": { "php": "^7.1.3", "doctrine/common": "~2.4@stable", + "symfony/contracts": "^1.0", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0" }, diff --git a/src/Symfony/Bridge/Monolog/Logger.php b/src/Symfony/Bridge/Monolog/Logger.php index 2f60299881..f735ff0cf2 100644 --- a/src/Symfony/Bridge/Monolog/Logger.php +++ b/src/Symfony/Bridge/Monolog/Logger.php @@ -14,13 +14,14 @@ namespace Symfony\Bridge\Monolog; use Monolog\Logger as BaseLogger; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; +use Symfony\Contract\Service\ResetInterface; /** * Logger. * * @author Fabien Potencier */ -class Logger extends BaseLogger implements DebugLoggerInterface +class Logger extends BaseLogger implements DebugLoggerInterface, ResetInterface { /** * {@inheritdoc} @@ -56,6 +57,14 @@ class Logger extends BaseLogger implements DebugLoggerInterface } } + /** + * {@inheritdoc} + */ + public function reset() + { + $this->clear(); + } + /** * Returns a DebugLoggerInterface instance if one is registered with this logger. * diff --git a/src/Symfony/Bridge/Monolog/Processor/DebugProcessor.php b/src/Symfony/Bridge/Monolog/Processor/DebugProcessor.php index a6998517e7..fc44b39234 100644 --- a/src/Symfony/Bridge/Monolog/Processor/DebugProcessor.php +++ b/src/Symfony/Bridge/Monolog/Processor/DebugProcessor.php @@ -15,8 +15,9 @@ use Monolog\Logger; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; +use Symfony\Contract\Service\ResetInterface; -class DebugProcessor implements DebugLoggerInterface +class DebugProcessor implements DebugLoggerInterface, ResetInterface { private $records = array(); private $errorCount = array(); @@ -91,4 +92,12 @@ class DebugProcessor implements DebugLoggerInterface $this->records = array(); $this->errorCount = array(); } + + /** + * {@inheritdoc} + */ + public function reset() + { + $this->clear(); + } } diff --git a/src/Symfony/Bridge/Monolog/composer.json b/src/Symfony/Bridge/Monolog/composer.json index 9d0d6acf85..535c2d23bc 100644 --- a/src/Symfony/Bridge/Monolog/composer.json +++ b/src/Symfony/Bridge/Monolog/composer.json @@ -18,6 +18,7 @@ "require": { "php": "^7.1.3", "monolog/monolog": "~1.19", + "symfony/contracts": "^1.0", "symfony/http-kernel": "~3.4|~4.0" }, "require-dev": { diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 9e4be5e58e..17913847b4 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -25,7 +25,6 @@ use Symfony\Component\Cache\Adapter\AdapterInterface; use Symfony\Component\Cache\Adapter\ArrayAdapter; use Symfony\Component\Cache\Adapter\TagAwareAdapter; use Symfony\Component\Cache\Marshaller\DefaultMarshaller; -use Symfony\Component\Cache\ResettableInterface; use Symfony\Component\Config\FileLocator; use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\Config\Resource\DirectoryResource; @@ -95,6 +94,7 @@ use Symfony\Component\WebLink\HttpHeaderSerializer; use Symfony\Component\Workflow; use Symfony\Component\Yaml\Command\LintCommand as BaseYamlLintCommand; use Symfony\Component\Yaml\Yaml; +use Symfony\Contract\Service\ResetInterface; /** * FrameworkExtension. @@ -324,7 +324,7 @@ class FrameworkExtension extends Extension ->addTag('kernel.cache_warmer'); $container->registerForAutoconfiguration(EventSubscriberInterface::class) ->addTag('kernel.event_subscriber'); - $container->registerForAutoconfiguration(ResettableInterface::class) + $container->registerForAutoconfiguration(ResetInterface::class) ->addTag('kernel.reset', array('method' => 'reset')); $container->registerForAutoconfiguration(ProcessorInterface::class) ->addTag('monolog.processor'); diff --git a/src/Symfony/Component/Cache/Adapter/ChainAdapter.php b/src/Symfony/Component/Cache/Adapter/ChainAdapter.php index 57b6cafd09..f573afe1af 100644 --- a/src/Symfony/Component/Cache/Adapter/ChainAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/ChainAdapter.php @@ -19,6 +19,7 @@ use Symfony\Component\Cache\Exception\InvalidArgumentException; use Symfony\Component\Cache\PruneableInterface; use Symfony\Component\Cache\ResettableInterface; use Symfony\Component\Cache\Traits\GetTrait; +use Symfony\Contract\Service\ResetInterface; /** * Chains several adapters together. @@ -301,7 +302,7 @@ class ChainAdapter implements AdapterInterface, CacheInterface, PruneableInterfa public function reset() { foreach ($this->adapters as $adapter) { - if ($adapter instanceof ResettableInterface) { + if ($adapter instanceof ResetInterface) { $adapter->reset(); } } diff --git a/src/Symfony/Component/Cache/Adapter/TraceableAdapter.php b/src/Symfony/Component/Cache/Adapter/TraceableAdapter.php index 76db2f66d8..12ce429429 100644 --- a/src/Symfony/Component/Cache/Adapter/TraceableAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/TraceableAdapter.php @@ -16,6 +16,7 @@ use Symfony\Component\Cache\CacheInterface; use Symfony\Component\Cache\CacheItem; use Symfony\Component\Cache\PruneableInterface; use Symfony\Component\Cache\ResettableInterface; +use Symfony\Contract\Service\ResetInterface; /** * An adapter that collects data about all cache calls. @@ -225,7 +226,7 @@ class TraceableAdapter implements AdapterInterface, CacheInterface, PruneableInt */ public function reset() { - if (!$this->pool instanceof ResettableInterface) { + if (!$this->pool instanceof ResetInterface) { return; } $event = $this->start(__FUNCTION__); diff --git a/src/Symfony/Component/Cache/DoctrineProvider.php b/src/Symfony/Component/Cache/DoctrineProvider.php index cebe95fbc7..01ce9daf02 100644 --- a/src/Symfony/Component/Cache/DoctrineProvider.php +++ b/src/Symfony/Component/Cache/DoctrineProvider.php @@ -13,6 +13,7 @@ namespace Symfony\Component\Cache; use Doctrine\Common\Cache\CacheProvider; use Psr\Cache\CacheItemPoolInterface; +use Symfony\Contract\Service\ResetInterface; /** * @author Nicolas Grekas @@ -39,7 +40,7 @@ class DoctrineProvider extends CacheProvider implements PruneableInterface, Rese */ public function reset() { - if ($this->pool instanceof ResettableInterface) { + if ($this->pool instanceof ResetInterface) { $this->pool->reset(); } $this->setNamespace($this->getNamespace()); diff --git a/src/Symfony/Component/Cache/ResettableInterface.php b/src/Symfony/Component/Cache/ResettableInterface.php index 6be72861e7..79d0b54849 100644 --- a/src/Symfony/Component/Cache/ResettableInterface.php +++ b/src/Symfony/Component/Cache/ResettableInterface.php @@ -11,10 +11,11 @@ namespace Symfony\Component\Cache; +use Symfony\Contract\Service\ResetInterface; + /** * Resets a pool's local state. */ -interface ResettableInterface +interface ResettableInterface extends ResetInterface { - public function reset(); } diff --git a/src/Symfony/Component/Cache/Simple/ChainCache.php b/src/Symfony/Component/Cache/Simple/ChainCache.php index db97fc7de4..82032cde9e 100644 --- a/src/Symfony/Component/Cache/Simple/ChainCache.php +++ b/src/Symfony/Component/Cache/Simple/ChainCache.php @@ -15,6 +15,7 @@ use Psr\SimpleCache\CacheInterface; use Symfony\Component\Cache\Exception\InvalidArgumentException; use Symfony\Component\Cache\PruneableInterface; use Symfony\Component\Cache\ResettableInterface; +use Symfony\Contract\Service\ResetInterface; /** * Chains several caches together. @@ -244,7 +245,7 @@ class ChainCache implements CacheInterface, PruneableInterface, ResettableInterf public function reset() { foreach ($this->caches as $cache) { - if ($cache instanceof ResettableInterface) { + if ($cache instanceof ResetInterface) { $cache->reset(); } } diff --git a/src/Symfony/Component/Cache/Simple/TraceableCache.php b/src/Symfony/Component/Cache/Simple/TraceableCache.php index 181934eff5..d119a54961 100644 --- a/src/Symfony/Component/Cache/Simple/TraceableCache.php +++ b/src/Symfony/Component/Cache/Simple/TraceableCache.php @@ -14,6 +14,7 @@ namespace Symfony\Component\Cache\Simple; use Psr\SimpleCache\CacheInterface; use Symfony\Component\Cache\PruneableInterface; use Symfony\Component\Cache\ResettableInterface; +use Symfony\Contract\Service\ResetInterface; /** * An adapter that collects data about all cache calls. @@ -200,7 +201,7 @@ class TraceableCache implements CacheInterface, PruneableInterface, ResettableIn */ public function reset() { - if (!$this->pool instanceof ResettableInterface) { + if (!$this->pool instanceof ResetInterface) { return; } $event = $this->start(__FUNCTION__); diff --git a/src/Symfony/Component/Cache/Traits/ProxyTrait.php b/src/Symfony/Component/Cache/Traits/ProxyTrait.php index d9e085b9ea..dea3843189 100644 --- a/src/Symfony/Component/Cache/Traits/ProxyTrait.php +++ b/src/Symfony/Component/Cache/Traits/ProxyTrait.php @@ -12,7 +12,7 @@ namespace Symfony\Component\Cache\Traits; use Symfony\Component\Cache\PruneableInterface; -use Symfony\Component\Cache\ResettableInterface; +use Symfony\Contract\Service\ResetInterface; /** * @author Nicolas Grekas @@ -36,7 +36,7 @@ trait ProxyTrait */ public function reset() { - if ($this->pool instanceof ResettableInterface) { + if ($this->pool instanceof ResetInterface) { $this->pool->reset(); } } diff --git a/src/Symfony/Component/Cache/composer.json b/src/Symfony/Component/Cache/composer.json index b043aeb58b..e683ae21f6 100644 --- a/src/Symfony/Component/Cache/composer.json +++ b/src/Symfony/Component/Cache/composer.json @@ -23,7 +23,8 @@ "php": "^7.1.3", "psr/cache": "~1.0", "psr/log": "~1.0", - "psr/simple-cache": "^1.0" + "psr/simple-cache": "^1.0", + "symfony/contracts": "^1.0" }, "require-dev": { "cache/integration-tests": "dev-master", diff --git a/src/Symfony/Component/Console/Formatter/OutputFormatterStyleStack.php b/src/Symfony/Component/Console/Formatter/OutputFormatterStyleStack.php index bf0beb709e..63715f369b 100644 --- a/src/Symfony/Component/Console/Formatter/OutputFormatterStyleStack.php +++ b/src/Symfony/Component/Console/Formatter/OutputFormatterStyleStack.php @@ -12,11 +12,12 @@ namespace Symfony\Component\Console\Formatter; use Symfony\Component\Console\Exception\InvalidArgumentException; +use Symfony\Contract\Service\ResetInterface; /** * @author Jean-François Simon */ -class OutputFormatterStyleStack +class OutputFormatterStyleStack implements ResetInterface { /** * @var OutputFormatterStyleInterface[] diff --git a/src/Symfony/Component/Console/composer.json b/src/Symfony/Component/Console/composer.json index 48da2819ff..ca1a9269f3 100644 --- a/src/Symfony/Component/Console/composer.json +++ b/src/Symfony/Component/Console/composer.json @@ -17,6 +17,7 @@ ], "require": { "php": "^7.1.3", + "symfony/contracts": "^1.0", "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { diff --git a/src/Symfony/Component/DependencyInjection/ResettableContainerInterface.php b/src/Symfony/Component/DependencyInjection/ResettableContainerInterface.php index b74e676245..6fb1d2ae31 100644 --- a/src/Symfony/Component/DependencyInjection/ResettableContainerInterface.php +++ b/src/Symfony/Component/DependencyInjection/ResettableContainerInterface.php @@ -11,6 +11,8 @@ namespace Symfony\Component\DependencyInjection; +use Symfony\Contract\Service\ResetInterface; + /** * ResettableContainerInterface defines additional resetting functionality * for containers, allowing to release shared services when the container is @@ -18,7 +20,7 @@ namespace Symfony\Component\DependencyInjection; * * @author Christophe Coevoet */ -interface ResettableContainerInterface extends ContainerInterface +interface ResettableContainerInterface extends ContainerInterface, ResetInterface { /** * Resets shared services from the container. diff --git a/src/Symfony/Component/DependencyInjection/composer.json b/src/Symfony/Component/DependencyInjection/composer.json index bea3cd5b45..ec48d8ac55 100644 --- a/src/Symfony/Component/DependencyInjection/composer.json +++ b/src/Symfony/Component/DependencyInjection/composer.json @@ -17,7 +17,8 @@ ], "require": { "php": "^7.1.3", - "psr/container": "^1.0" + "psr/container": "^1.0", + "symfony/contracts": "^1.0" }, "require-dev": { "symfony/yaml": "~3.4|~4.0", diff --git a/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcherInterface.php b/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcherInterface.php index d716f1914f..9781bdbb61 100644 --- a/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcherInterface.php +++ b/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcherInterface.php @@ -12,13 +12,14 @@ namespace Symfony\Component\EventDispatcher\Debug; use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Contract\Service\ResetInterface; /** * @deprecated since Symfony 4.1 * * @author Fabien Potencier */ -interface TraceableEventDispatcherInterface extends EventDispatcherInterface +interface TraceableEventDispatcherInterface extends EventDispatcherInterface, ResetInterface { /** * Gets the called listeners. @@ -33,9 +34,4 @@ interface TraceableEventDispatcherInterface extends EventDispatcherInterface * @return array An array of not called listeners */ public function getNotCalledListeners(); - - /** - * Resets the trace. - */ - public function reset(); } diff --git a/src/Symfony/Component/EventDispatcher/composer.json b/src/Symfony/Component/EventDispatcher/composer.json index faad1204a8..6c75dfbb00 100644 --- a/src/Symfony/Component/EventDispatcher/composer.json +++ b/src/Symfony/Component/EventDispatcher/composer.json @@ -16,7 +16,8 @@ } ], "require": { - "php": "^7.1.3" + "php": "^7.1.3", + "symfony/contracts": "^1.0" }, "require-dev": { "symfony/dependency-injection": "~3.4|~4.0", diff --git a/src/Symfony/Component/ExpressionLanguage/Compiler.php b/src/Symfony/Component/ExpressionLanguage/Compiler.php index 66d106041f..ca99d4e5ea 100644 --- a/src/Symfony/Component/ExpressionLanguage/Compiler.php +++ b/src/Symfony/Component/ExpressionLanguage/Compiler.php @@ -11,12 +11,14 @@ namespace Symfony\Component\ExpressionLanguage; +use Symfony\Contract\Service\ResetInterface; + /** * Compiles a node to PHP code. * * @author Fabien Potencier */ -class Compiler +class Compiler implements ResetInterface { private $source; private $functions; diff --git a/src/Symfony/Component/ExpressionLanguage/composer.json b/src/Symfony/Component/ExpressionLanguage/composer.json index 489612428c..2e699629e8 100644 --- a/src/Symfony/Component/ExpressionLanguage/composer.json +++ b/src/Symfony/Component/ExpressionLanguage/composer.json @@ -17,7 +17,8 @@ ], "require": { "php": "^7.1.3", - "symfony/cache": "~3.4|~4.0" + "symfony/cache": "~3.4|~4.0", + "symfony/contracts": "^1.0" }, "autoload": { "psr-4": { "Symfony\\Component\\ExpressionLanguage\\": "" }, diff --git a/src/Symfony/Component/HttpKernel/DataCollector/DataCollectorInterface.php b/src/Symfony/Component/HttpKernel/DataCollector/DataCollectorInterface.php index 549fd5d3a9..96d3b8f49a 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/DataCollectorInterface.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/DataCollectorInterface.php @@ -13,13 +13,14 @@ namespace Symfony\Component\HttpKernel\DataCollector; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Contract\Service\ResetInterface; /** * DataCollectorInterface. * * @author Fabien Potencier */ -interface DataCollectorInterface +interface DataCollectorInterface extends ResetInterface { /** * Collects data for the given Request and Response. @@ -32,9 +33,4 @@ interface DataCollectorInterface * @return string The collector name */ public function getName(); - - /** - * Resets this data collector to its initial state. - */ - public function reset(); } diff --git a/src/Symfony/Component/HttpKernel/DataCollector/EventDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/EventDataCollector.php index f9d5bed130..12f5084f0c 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/EventDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/EventDataCollector.php @@ -16,6 +16,7 @@ use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcherInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Contract\Service\ResetInterface; /** * EventDataCollector. @@ -47,7 +48,7 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter { $this->data = array(); - if ($this->dispatcher instanceof TraceableEventDispatcherInterface) { + if ($this->dispatcher instanceof ResetInterface) { $this->dispatcher->reset(); } } diff --git a/src/Symfony/Component/HttpKernel/DependencyInjection/ServicesResetter.php b/src/Symfony/Component/HttpKernel/DependencyInjection/ServicesResetter.php index b82d2fef3c..9af5e7934d 100644 --- a/src/Symfony/Component/HttpKernel/DependencyInjection/ServicesResetter.php +++ b/src/Symfony/Component/HttpKernel/DependencyInjection/ServicesResetter.php @@ -11,6 +11,8 @@ namespace Symfony\Component\HttpKernel\DependencyInjection; +use Symfony\Contract\Service\ResetInterface; + /** * Resets provided services. * @@ -19,7 +21,7 @@ namespace Symfony\Component\HttpKernel\DependencyInjection; * * @internal */ -class ServicesResetter +class ServicesResetter implements ResetInterface { private $resettableServices; private $resetMethods; diff --git a/src/Symfony/Component/HttpKernel/Profiler/Profiler.php b/src/Symfony/Component/HttpKernel/Profiler/Profiler.php index a97d63b05f..6ecfd2a4be 100644 --- a/src/Symfony/Component/HttpKernel/Profiler/Profiler.php +++ b/src/Symfony/Component/HttpKernel/Profiler/Profiler.php @@ -16,6 +16,7 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface; use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface; +use Symfony\Contract\Service\ResetInterface; use Psr\Log\LoggerInterface; /** @@ -23,7 +24,7 @@ use Psr\Log\LoggerInterface; * * @author Fabien Potencier */ -class Profiler +class Profiler implements ResetInterface { private $storage; diff --git a/src/Symfony/Component/HttpKernel/composer.json b/src/Symfony/Component/HttpKernel/composer.json index c41607bdff..d4974664ec 100644 --- a/src/Symfony/Component/HttpKernel/composer.json +++ b/src/Symfony/Component/HttpKernel/composer.json @@ -17,6 +17,7 @@ ], "require": { "php": "^7.1.3", + "symfony/contracts": "^1.0", "symfony/event-dispatcher": "~4.1", "symfony/http-foundation": "^4.1.1", "symfony/debug": "~3.4|~4.0", diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/Storage/TokenStorage.php b/src/Symfony/Component/Security/Core/Authentication/Token/Storage/TokenStorage.php index b4930813f5..703badc2b0 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Token/Storage/TokenStorage.php +++ b/src/Symfony/Component/Security/Core/Authentication/Token/Storage/TokenStorage.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Security\Core\Authentication\Token\Storage; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Contract\Service\ResetInterface; /** * TokenStorage contains a TokenInterface. @@ -21,7 +22,7 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; * @author Fabien Potencier * @author Johannes M. Schmitt */ -class TokenStorage implements TokenStorageInterface +class TokenStorage implements TokenStorageInterface, ResetInterface { private $token; @@ -40,4 +41,9 @@ class TokenStorage implements TokenStorageInterface { $this->token = $token; } + + public function reset() + { + $this->setToken(null); + } } diff --git a/src/Symfony/Component/Security/Core/composer.json b/src/Symfony/Component/Security/Core/composer.json index 60603bff8b..4df7190030 100644 --- a/src/Symfony/Component/Security/Core/composer.json +++ b/src/Symfony/Component/Security/Core/composer.json @@ -16,7 +16,8 @@ } ], "require": { - "php": "^7.1.3" + "php": "^7.1.3", + "symfony/contracts": "^1.0" }, "require-dev": { "psr/container": "^1.0", diff --git a/src/Symfony/Component/Security/composer.json b/src/Symfony/Component/Security/composer.json index bf04e86730..81407dcacf 100644 --- a/src/Symfony/Component/Security/composer.json +++ b/src/Symfony/Component/Security/composer.json @@ -17,6 +17,7 @@ ], "require": { "php": "^7.1.3", + "symfony/contracts": "^1.0", "symfony/event-dispatcher": "~3.4|~4.0", "symfony/http-foundation": "~3.4|~4.0", "symfony/http-kernel": "~3.4|~4.0", diff --git a/src/Symfony/Component/Stopwatch/Stopwatch.php b/src/Symfony/Component/Stopwatch/Stopwatch.php index fe1645fc54..2b66d88da9 100644 --- a/src/Symfony/Component/Stopwatch/Stopwatch.php +++ b/src/Symfony/Component/Stopwatch/Stopwatch.php @@ -11,12 +11,14 @@ namespace Symfony\Component\Stopwatch; +use Symfony\Contract\Service\ResetInterface; + /** * Stopwatch provides a way to profile code. * * @author Fabien Potencier */ -class Stopwatch +class Stopwatch implements ResetInterface { /** * @var bool diff --git a/src/Symfony/Component/Stopwatch/composer.json b/src/Symfony/Component/Stopwatch/composer.json index 26c6c3e922..356b1fec17 100644 --- a/src/Symfony/Component/Stopwatch/composer.json +++ b/src/Symfony/Component/Stopwatch/composer.json @@ -16,7 +16,8 @@ } ], "require": { - "php": "^7.1.3" + "php": "^7.1.3", + "symfony/contracts": "^1.0" }, "autoload": { "psr-4": { "Symfony\\Component\\Stopwatch\\": "" }, diff --git a/src/Symfony/Component/Validator/Validator/TraceableValidator.php b/src/Symfony/Component/Validator/Validator/TraceableValidator.php index 96134e2767..a5e50ca4ac 100644 --- a/src/Symfony/Component/Validator/Validator/TraceableValidator.php +++ b/src/Symfony/Component/Validator/Validator/TraceableValidator.php @@ -12,13 +12,14 @@ namespace Symfony\Component\Validator\Validator; use Symfony\Component\Validator\Context\ExecutionContextInterface; +use Symfony\Contract\Service\ResetInterface; /** * Collects some data about validator calls. * * @author Maxime Steinhausser */ -class TraceableValidator implements ValidatorInterface +class TraceableValidator implements ValidatorInterface, ResetInterface { private $validator; private $collectedData = array(); diff --git a/src/Symfony/Component/Validator/composer.json b/src/Symfony/Component/Validator/composer.json index 531ffd9d57..0e5253905e 100644 --- a/src/Symfony/Component/Validator/composer.json +++ b/src/Symfony/Component/Validator/composer.json @@ -17,6 +17,7 @@ ], "require": { "php": "^7.1.3", + "symfony/contracts": "^1.0", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", "symfony/translation": "~3.4|~4.0" diff --git a/src/Symfony/Contract/.gitignore b/src/Symfony/Contract/.gitignore new file mode 100644 index 0000000000..5414c2c655 --- /dev/null +++ b/src/Symfony/Contract/.gitignore @@ -0,0 +1,3 @@ +composer.lock +phpunit.xml +vendor/ diff --git a/src/Symfony/Contract/CHANGELOG.md b/src/Symfony/Contract/CHANGELOG.md new file mode 100644 index 0000000000..7f8d6d87ef --- /dev/null +++ b/src/Symfony/Contract/CHANGELOG.md @@ -0,0 +1,7 @@ +CHANGELOG +========= + +1.0.0 +----- + + * added `Service\ResetInterface` to provides a way to reset an object to its initial state diff --git a/src/Symfony/Contract/LICENSE b/src/Symfony/Contract/LICENSE new file mode 100644 index 0000000000..ad399a798d --- /dev/null +++ b/src/Symfony/Contract/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/src/Symfony/Contract/README.md b/src/Symfony/Contract/README.md new file mode 100644 index 0000000000..b8daa17cb4 --- /dev/null +++ b/src/Symfony/Contract/README.md @@ -0,0 +1,68 @@ +Symfony Contracts +================= + +A set of abstractions extracted out of the Symfony components. + +Can be used to build on semantics that the Symfony components proved useful - and +that already have battle tested implementations. + +Design Principles +----------------- + + * contracts are split by domain, each into their own sub-namespaces; + * contracts are small and consistent sets of PHP interfaces, traits, normative + docblocks and reference test suites when applicable, etc.; + * all contracts must have a proven implementation to enter this repository; + * they must be backward compatible with existing Symfony components. + +FAQ +--- + +### How to use this package? + +The abstractions in this package are useful to achieve loose coupling and +interoperability. By using the provided interfaces as type hints, you are able +to reuse any implementations that match their contracts. It could be a Symfony +component, or another one provided by the PHP community at large. + +Depending on their semantics, some interfaces can be combined with autowiring to +seamlessly inject a service in your classes. + +Others might be useful as labeling interfaces, to hint about a specific behavior +that could be enabled when using autoconfiguration or manual service tagging (or +any other means provided by your framework.) + +### How is this different from PHP-FIG's PSRs? + +When applicable, the provided contracts are built on top of PHP-FIG's PSR. We +encourage relying on them and won't duplicate the effort. Still, the FIG has +different goals and different processes. Here, we don't need to seek universal +standards. Instead, we're providing abstractions that are compatible with the +implementations provided by Symfony. This should actually also contribute +positively to the PHP-FIG (from which Symfony is a member), by hinting the group +at some abstractions the PHP world might like to take inspiration from. + +### Why isn't this package split into several packages? + +Putting all interfaces in one package eases discoverability and dependency +management. Instead of dealing with a myriad of small packages and the +corresponding matrix of versions, you just need to deal with one package and one +version. Also when using IDE autocompletion or just reading the source code, it +makes it easier to figure out which contracts are provided. + +There are two downsides to this approach: you may have unused files in your +`vendor/` directory, and in the future, it will be impossible to use two +different sub-namespaces in different major versions of the package. For the +"unused files" downside, it has no practical consequences: their file sizes are +very small, and there is no performance overhead at all since they are never +loaded. For major versions, this package follows the Symfony BC + deprecation +policies, with an additional restriction to never remove deprecated interfaces. + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/contracts.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/src/Symfony/Contract/Service/ResetInterface.php b/src/Symfony/Contract/Service/ResetInterface.php new file mode 100644 index 0000000000..a99669c911 --- /dev/null +++ b/src/Symfony/Contract/Service/ResetInterface.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contract\Service; + +/** + * Provides a way to reset an object to its initial state. + * + * When calling the "reset()" method on an object, it should be put back to its + * initial state. This usually means clearing any internal buffers and forwarding + * the call to internal dependencies. All properties of the object should be put + * back to the same state it had when it was first ready to use. + * + * This method could be called, for example, to recycle objects that are used as + * services, so that they can be used to handle several requests in the same + * process loop (note that we advise making your services stateless instead of + * implementing this interface when possible.) + */ +interface ResetInterface +{ + public function reset(); +} diff --git a/src/Symfony/Contract/composer.json b/src/Symfony/Contract/composer.json new file mode 100644 index 0000000000..2b515ef81c --- /dev/null +++ b/src/Symfony/Contract/composer.json @@ -0,0 +1,33 @@ +{ + "name": "symfony/contracts", + "type": "library", + "description": "A set of abstractions extracted out of the Symfony components", + "keywords": ["abstractions", "contracts", "decoupling", "interfaces", "interoperability", "standards"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": "^7.1.3" + }, + "autoload": { + "psr-4": { "Symfony\\Contract\\": "" }, + "exclude-from-classmap": [ + "**/Tests/" + ] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + } +} diff --git a/src/Symfony/Contract/phpunit.xml.dist b/src/Symfony/Contract/phpunit.xml.dist new file mode 100644 index 0000000000..bf26eb0b3d --- /dev/null +++ b/src/Symfony/Contract/phpunit.xml.dist @@ -0,0 +1,31 @@ + + + + + + + + + + ./Tests/ + + + + + + ./ + + ./Tests + ./vendor + + + + +