Merge branch '3.4'
* 3.4: [Bridge\Doctrine][FrameworkBundle] Deprecate some remaining uses of ContainerAwareTrait [FrameworkBundle] Fix bad interface hint in AbstractController [VarDumper] deprecate MongoCaster [HttpFoundation] deprecate using with the legacy mongo extension; use it with the mongodb/mongodb package and ext-mongodb instead Fix BC layer Reset profiler. [DI] Improve some deprecation messages [DI] remove inheritdoc from dumped container [Config] Fix dumped files invalidation by OPCache [Security] Add Guard authenticator <supports> method [Cache] Fix race condition in TagAwareAdapter [DI] Allow setting any public non-initialized services [Yaml] parse references on merge keys treat trailing backslashes in multi-line strings [FrameworkBundle] Expose dotenv in bin/console about fix refreshing line numbers for the inline parser fix version in changelog [FrameworkBundle] Make Controller helpers final [DoctrineBridge] Deprecate DbalSessionHandler
This commit is contained in:
commit
522d079110
|
@ -63,6 +63,12 @@ Debug
|
|||
|
||||
* Support for stacked errors in the `ErrorHandler` is deprecated and will be removed in Symfony 4.0.
|
||||
|
||||
EventDispatcher
|
||||
---------------
|
||||
|
||||
* Implementing `TraceableEventDispatcherInterface` without the `reset()` method
|
||||
is deprecated and will be unsupported in 4.0.
|
||||
|
||||
Filesystem
|
||||
----------
|
||||
|
||||
|
@ -234,6 +240,9 @@ HttpFoundation
|
|||
* `NativeSessionStorage::setSaveHandler()` now takes an instance of `\SessionHandlerInterface` as argument.
|
||||
Not passing it is deprecated and will throw a `TypeError` in 4.0.
|
||||
|
||||
* Using `Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler` with the legacy mongo extension
|
||||
has been deprecated and will be removed in 4.0. Use it with the mongodb/mongodb package and ext-mongodb instead.
|
||||
|
||||
HttpKernel
|
||||
----------
|
||||
|
||||
|
@ -270,6 +279,10 @@ HttpKernel
|
|||
|
||||
* The `Symfony\Component\HttpKernel\Config\EnvParametersResource` class has been deprecated and will be removed in 4.0.
|
||||
|
||||
* Implementing `DataCollectorInterface` without a `reset()` method has been deprecated and will be unsupported in 4.0.
|
||||
|
||||
* Implementing `DebugLoggerInterface` without a `clear()` method has been deprecated and will be unsupported in 4.0.
|
||||
|
||||
* The `ChainCacheClearer::add()` method has been deprecated and will be removed in 4.0,
|
||||
inject the list of clearers as a constructor argument instead.
|
||||
|
||||
|
@ -295,6 +308,9 @@ Security
|
|||
* Deprecated the HTTP digest authentication: `NonceExpiredException`,
|
||||
`DigestAuthenticationListener` and `DigestAuthenticationEntryPoint` will be
|
||||
removed in 4.0. Use another authentication system like `http_basic` instead.
|
||||
|
||||
* The `GuardAuthenticatorInterface` has been deprecated and will be removed in 4.0.
|
||||
Use `AuthenticatorInterface` instead.
|
||||
|
||||
SecurityBundle
|
||||
--------------
|
||||
|
@ -320,11 +336,11 @@ SecurityBundle
|
|||
|
||||
* Deprecated the HTTP digest authentication: `HttpDigestFactory` will be removed in 4.0.
|
||||
Use another authentication system like `http_basic` instead.
|
||||
|
||||
|
||||
* Deprecated setting the `switch_user.stateless` option to false when the firewall is `stateless`.
|
||||
Setting it to false will have no effect in 4.0.
|
||||
|
||||
* Not configuring explicitly the provider on a firewall is ambiguous when there is more than one registered provider.
|
||||
* Not configuring explicitly the provider on a firewall is ambiguous when there is more than one registered provider.
|
||||
Using the first configured provider is deprecated since 3.4 and will throw an exception on 4.0.
|
||||
Explicitly configure the provider to use on your firewalls.
|
||||
|
||||
|
|
|
@ -192,6 +192,8 @@ EventDispatcher
|
|||
* The `ContainerAwareEventDispatcher` class has been removed.
|
||||
Use `EventDispatcher` with closure factories instead.
|
||||
|
||||
* The `reset()` method has been added to `TraceableEventDispatcherInterface`.
|
||||
|
||||
ExpressionLanguage
|
||||
------------------
|
||||
|
||||
|
@ -540,6 +542,9 @@ HttpFoundation
|
|||
|
||||
* `NativeSessionStorage::setSaveHandler()` now requires an instance of `\SessionHandlerInterface` as argument.
|
||||
|
||||
* The `Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler` does not work with the legacy
|
||||
mongo extension anymore. It requires mongodb/mongodb package and ext-mongodb.
|
||||
|
||||
HttpKernel
|
||||
----------
|
||||
|
||||
|
@ -611,6 +616,10 @@ HttpKernel
|
|||
|
||||
* The `Symfony\Component\HttpKernel\Config\EnvParametersResource` class has been removed.
|
||||
|
||||
* The `reset()` method has been added to `Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface`.
|
||||
|
||||
* The `clear()` method has been added to `Symfony\Component\HttpKernel\Log\DebugLoggerInterface`.
|
||||
|
||||
* The `ChainCacheClearer::add()` method has been removed,
|
||||
inject the list of clearers as a constructor argument instead.
|
||||
|
||||
|
@ -673,6 +682,9 @@ Security
|
|||
`DigestAuthenticationListener` and `DigestAuthenticationEntryPoint` classes
|
||||
have been removed. Use another authentication system like `http_basic` instead.
|
||||
|
||||
* The `GuardAuthenticatorInterface` interface has been removed.
|
||||
Use `AuthenticatorInterface` instead.
|
||||
|
||||
SecurityBundle
|
||||
--------------
|
||||
|
||||
|
@ -693,10 +705,10 @@ SecurityBundle
|
|||
|
||||
* Removed the HTTP digest authentication system. The `HttpDigestFactory` class
|
||||
has been removed. Use another authentication system like `http_basic` instead.
|
||||
|
||||
|
||||
* The `switch_user.stateless` option is now always true if the firewall is stateless.
|
||||
|
||||
* Not configuring explicitly the provider on a firewall is ambiguous when there is more than one registered provider.
|
||||
* Not configuring explicitly the provider on a firewall is ambiguous when there is more than one registered provider.
|
||||
The first configured provider is not used anymore and an exception is thrown instead.
|
||||
Explicitly configure the provider to use on your firewalls.
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
"ext-xml": "*",
|
||||
"doctrine/common": "~2.4",
|
||||
"fig/link-util": "^1.0",
|
||||
"twig/twig": "~1.34|~2.4",
|
||||
"twig/twig": "^1.35|^2.4.4",
|
||||
"psr/cache": "~1.0",
|
||||
"psr/container": "^1.0",
|
||||
"psr/link": "^1.0",
|
||||
|
|
|
@ -28,6 +28,10 @@ class DoctrineDataCollector extends DataCollector
|
|||
private $registry;
|
||||
private $connections;
|
||||
private $managers;
|
||||
|
||||
/**
|
||||
* @var DebugStack[]
|
||||
*/
|
||||
private $loggers = array();
|
||||
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
|
@ -65,6 +69,16 @@ class DoctrineDataCollector extends DataCollector
|
|||
);
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->data = array();
|
||||
|
||||
foreach ($this->loggers as $logger) {
|
||||
$logger->queries = array();
|
||||
$logger->currentQuery = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public function getManagers()
|
||||
{
|
||||
return $this->data['managers'];
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
namespace Symfony\Bridge\Doctrine\HttpFoundation;
|
||||
|
||||
@trigger_error(sprintf('The class %s is deprecated since version 3.4 and will be removed in 4.0. Use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler instead.', DbalSessionHandler::class), E_USER_DEPRECATED);
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver\DriverException;
|
||||
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
|
||||
|
@ -25,6 +27,8 @@ use Doctrine\DBAL\Platforms\SQLServer2008Platform;
|
|||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
* @author Tobias Schultze <http://tobion.de>
|
||||
*
|
||||
* @deprecated since version 3.4, to be removed in 4.0. Use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler instead.
|
||||
*/
|
||||
class DbalSessionHandler implements \SessionHandlerInterface
|
||||
{
|
||||
|
|
|
@ -11,12 +11,16 @@
|
|||
|
||||
namespace Symfony\Bridge\Doctrine\HttpFoundation;
|
||||
|
||||
@trigger_error(sprintf('The class %s is deprecated since version 3.4 and will be removed in 4.0. Use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler::createTable instead.', DbalSessionHandlerSchema::class), E_USER_DEPRECATED);
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
/**
|
||||
* DBAL Session Storage Schema.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* @deprecated since version 3.4, to be removed in 4.0. Use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler::createTable instead.
|
||||
*/
|
||||
final class DbalSessionHandlerSchema extends Schema
|
||||
{
|
||||
|
|
|
@ -12,9 +12,10 @@
|
|||
namespace Symfony\Bridge\Doctrine;
|
||||
|
||||
use ProxyManager\Proxy\LazyLoadingInterface;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Container;
|
||||
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface as SymfonyContainerInterface;
|
||||
use Doctrine\Common\Persistence\AbstractManagerRegistry;
|
||||
|
||||
/**
|
||||
|
@ -24,7 +25,21 @@ use Doctrine\Common\Persistence\AbstractManagerRegistry;
|
|||
*/
|
||||
abstract class ManagerRegistry extends AbstractManagerRegistry implements ContainerAwareInterface
|
||||
{
|
||||
use ContainerAwareTrait;
|
||||
/**
|
||||
* @var ContainerInterface
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* @deprecated since version 3.4, to be removed in 4.0 alongside with the ContainerAwareInterface type.
|
||||
* @final since version 3.4
|
||||
*/
|
||||
public function setContainer(SymfonyContainerInterface $container = null)
|
||||
{
|
||||
@trigger_error(sprintf('The "%s()" method is deprecated since version 3.4 and will be removed in 4.0. Inject a PSR-11 container using the constructor instead.', __METHOD__), E_USER_DEPRECATED);
|
||||
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
|
|
@ -101,6 +101,20 @@ class DoctrineDataCollectorTest extends TestCase
|
|||
$this->assertTrue($collectedQueries['default'][1]['explainable']);
|
||||
}
|
||||
|
||||
public function testReset()
|
||||
{
|
||||
$queries = array(
|
||||
array('sql' => 'SELECT * FROM table1', 'params' => array(), 'types' => array(), 'executionMS' => 1),
|
||||
);
|
||||
$c = $this->createCollector($queries);
|
||||
$c->collect(new Request(), new Response());
|
||||
|
||||
$c->reset();
|
||||
$c->collect(new Request(), new Response());
|
||||
|
||||
$this->assertEquals(array('default' => array()), $c->getQueries());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider paramProvider
|
||||
*/
|
||||
|
|
|
@ -18,6 +18,8 @@ use Symfony\Bridge\Doctrine\HttpFoundation\DbalSessionHandler;
|
|||
* Test class for DbalSessionHandler.
|
||||
*
|
||||
* @author Drak <drak@zikula.org>
|
||||
*
|
||||
* @group legacy
|
||||
*/
|
||||
class DbalSessionHandlerTest extends TestCase
|
||||
{
|
||||
|
|
|
@ -31,7 +31,7 @@ class ManagerRegistryTest extends TestCase
|
|||
$container = new \LazyServiceProjectServiceContainer();
|
||||
|
||||
$registry = new TestManagerRegistry('name', array(), array('defaultManager' => 'foo'), 'defaultConnection', 'defaultManager', 'proxyInterfaceName');
|
||||
$registry->setContainer($container);
|
||||
$registry->setTestContainer($container);
|
||||
|
||||
$foo = $container->get('foo');
|
||||
$foo->bar = 123;
|
||||
|
@ -46,6 +46,11 @@ class ManagerRegistryTest extends TestCase
|
|||
|
||||
class TestManagerRegistry extends ManagerRegistry
|
||||
{
|
||||
public function setTestContainer($container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
public function getAliasNamespace($alias)
|
||||
{
|
||||
return 'Foo';
|
||||
|
|
|
@ -45,6 +45,16 @@ class Logger extends BaseLogger implements DebugLoggerInterface
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
if (($logger = $this->getDebugLogger()) && method_exists($logger, 'clear')) {
|
||||
$logger->clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a DebugLoggerInterface instance if one is registered with this logger.
|
||||
*
|
||||
|
|
|
@ -55,4 +55,13 @@ class DebugProcessor implements DebugLoggerInterface
|
|||
{
|
||||
return $this->errorCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->records = array();
|
||||
$this->errorCount = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,4 +78,17 @@ class LoggerTest extends TestCase
|
|||
$this->assertEquals('test', $record['message']);
|
||||
$this->assertEquals(Logger::INFO, $record['priority']);
|
||||
}
|
||||
|
||||
public function testClear()
|
||||
{
|
||||
$handler = new TestHandler();
|
||||
$logger = new Logger('test', array($handler));
|
||||
$logger->pushProcessor(new DebugProcessor());
|
||||
|
||||
$logger->addInfo('test');
|
||||
$logger->clear();
|
||||
|
||||
$this->assertEmpty($logger->getLogs());
|
||||
$this->assertSame(0, $logger->countErrors());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,16 @@ class TwigDataCollector extends DataCollector implements LateDataCollectorInterf
|
|||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->profile->reset();
|
||||
$this->computed = null;
|
||||
$this->data = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
],
|
||||
"require": {
|
||||
"php": "^7.1.3",
|
||||
"twig/twig": "~1.34|~2.4"
|
||||
"twig/twig": "^1.35|^2.4.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"fig/link-util": "^1.0",
|
||||
|
|
|
@ -81,6 +81,7 @@ CHANGELOG
|
|||
and `YamlLintCommand` classes have been marked as final
|
||||
* Added `asset.request_context.base_path` and `asset.request_context.secure` parameters
|
||||
to provide a default request context in case the stack is empty (similar to `router.request_context.*` parameters)
|
||||
* Display environment variables managed by `Dotenv` in `AboutCommand`
|
||||
|
||||
3.3.0
|
||||
-----
|
||||
|
|
|
@ -36,7 +36,19 @@ class AboutCommand extends Command
|
|||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this->setDescription('Displays information about the current project');
|
||||
$this
|
||||
->setDescription('Displays information about the current project')
|
||||
->setHelp(<<<'EOT'
|
||||
The <info>%command.name%</info> command displays information about the current Symfony project.
|
||||
|
||||
The <info>PHP</info> section displays important configuration that could affect your application. The values might
|
||||
be different between web and CLI.
|
||||
|
||||
The <info>Environment</info> section displays the current environment variables managed by Symfony Dotenv. It will not
|
||||
be shown if no variables were found. The values might be different between web and CLI.
|
||||
EOT
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -49,7 +61,7 @@ class AboutCommand extends Command
|
|||
/** @var $kernel KernelInterface */
|
||||
$kernel = $this->getApplication()->getKernel();
|
||||
|
||||
$io->table(array(), array(
|
||||
$rows = array(
|
||||
array('<info>Symfony</>'),
|
||||
new TableSeparator(),
|
||||
array('Version', Kernel::VERSION),
|
||||
|
@ -76,7 +88,19 @@ class AboutCommand extends Command
|
|||
array('OPcache', extension_loaded('Zend OPcache') && ini_get('opcache.enable') ? 'true' : 'false'),
|
||||
array('APCu', extension_loaded('apcu') && ini_get('apc.enabled') ? 'true' : 'false'),
|
||||
array('Xdebug', extension_loaded('xdebug') ? 'true' : 'false'),
|
||||
));
|
||||
);
|
||||
|
||||
if ($dotenv = self::getDotEnvVars()) {
|
||||
$rows = array_merge($rows, array(
|
||||
new TableSeparator(),
|
||||
array('<info>Environment (.env)</>'),
|
||||
new TableSeparator(),
|
||||
), array_map(function ($value, $name) {
|
||||
return array($name, $value);
|
||||
}, $dotenv, array_keys($dotenv)));
|
||||
}
|
||||
|
||||
$io->table(array(), $rows);
|
||||
}
|
||||
|
||||
private static function formatPath($path, $baseDir = null)
|
||||
|
@ -104,4 +128,16 @@ class AboutCommand extends Command
|
|||
|
||||
return false !== $date && new \DateTime() > $date->modify('last day of this month 23:59:59');
|
||||
}
|
||||
|
||||
private static function getDotEnvVars()
|
||||
{
|
||||
$vars = array();
|
||||
foreach (explode(',', getenv('SYMFONY_DOTENV_VARS')) as $name) {
|
||||
if ('' !== $name && false !== $value = getenv($name)) {
|
||||
$vars[$name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $vars;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,30 +26,6 @@ abstract class Controller implements ContainerAwareInterface
|
|||
use ContainerAwareTrait;
|
||||
use ControllerTrait;
|
||||
|
||||
/**
|
||||
* Returns true if the service id is defined.
|
||||
*
|
||||
* @param string $id The service id
|
||||
*
|
||||
* @return bool true if the service id is defined, false otherwise
|
||||
*/
|
||||
protected function has($id)
|
||||
{
|
||||
return $this->container->has($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a container service by its id.
|
||||
*
|
||||
* @param string $id The service id
|
||||
*
|
||||
* @return object The service
|
||||
*/
|
||||
protected function get($id)
|
||||
{
|
||||
return $this->container->get($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a container configuration parameter by its name.
|
||||
*
|
||||
|
|
|
@ -48,13 +48,7 @@ class ControllerResolver extends ContainerControllerResolver
|
|||
$resolvedController = parent::createController($controller);
|
||||
|
||||
if (1 === substr_count($controller, ':') && is_array($resolvedController)) {
|
||||
if ($resolvedController[0] instanceof ContainerAwareInterface) {
|
||||
$resolvedController[0]->setContainer($this->container);
|
||||
}
|
||||
|
||||
if ($resolvedController[0] instanceof AbstractController && null !== $previousContainer = $resolvedController[0]->setContainer($this->container)) {
|
||||
$resolvedController[0]->setContainer($previousContainer);
|
||||
}
|
||||
$resolvedController[0] = $this->configureController($resolvedController[0]);
|
||||
}
|
||||
|
||||
return $resolvedController;
|
||||
|
@ -65,9 +59,19 @@ class ControllerResolver extends ContainerControllerResolver
|
|||
*/
|
||||
protected function instantiateController($class)
|
||||
{
|
||||
$controller = parent::instantiateController($class);
|
||||
return $this->configureController(parent::instantiateController($class));
|
||||
}
|
||||
|
||||
private function configureController($controller)
|
||||
{
|
||||
if ($controller instanceof ContainerAwareInterface) {
|
||||
// @deprecated switch, to be removed in 4.0 where these classes
|
||||
// won't implement ContainerAwareInterface anymore
|
||||
switch (\get_class($controller)) {
|
||||
case RedirectController::class:
|
||||
case TemplateController::class:
|
||||
return $controller;
|
||||
}
|
||||
$controller->setContainer($this->container);
|
||||
}
|
||||
if ($controller instanceof AbstractController && null !== $previousContainer = $controller->setContainer($this->container)) {
|
||||
|
|
|
@ -39,6 +39,34 @@ use Doctrine\Bundle\DoctrineBundle\Registry;
|
|||
*/
|
||||
trait ControllerTrait
|
||||
{
|
||||
/**
|
||||
* Returns true if the service id is defined.
|
||||
*
|
||||
* @param string $id The service id
|
||||
*
|
||||
* @return bool true if the service id is defined, false otherwise
|
||||
*
|
||||
* @final since version 3.4
|
||||
*/
|
||||
protected function has($id)
|
||||
{
|
||||
return $this->container->has($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a container service by its id.
|
||||
*
|
||||
* @param string $id The service id
|
||||
*
|
||||
* @return object The service
|
||||
*
|
||||
* @final since version 3.4
|
||||
*/
|
||||
protected function get($id)
|
||||
{
|
||||
return $this->container->get($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a URL from the given parameters.
|
||||
*
|
||||
|
@ -49,6 +77,8 @@ trait ControllerTrait
|
|||
* @return string The generated URL
|
||||
*
|
||||
* @see UrlGeneratorInterface
|
||||
*
|
||||
* @final since version 3.4
|
||||
*/
|
||||
protected function generateUrl($route, $parameters = array(), $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH)
|
||||
{
|
||||
|
@ -63,6 +93,8 @@ trait ControllerTrait
|
|||
* @param array $query An array of query parameters
|
||||
*
|
||||
* @return Response A Response instance
|
||||
*
|
||||
* @final since version 3.4
|
||||
*/
|
||||
protected function forward($controller, array $path = array(), array $query = array())
|
||||
{
|
||||
|
@ -81,6 +113,8 @@ trait ControllerTrait
|
|||
* @param int $status The status code to use for the Response
|
||||
*
|
||||
* @return RedirectResponse
|
||||
*
|
||||
* @final since version 3.4
|
||||
*/
|
||||
protected function redirect($url, $status = 302)
|
||||
{
|
||||
|
@ -95,6 +129,8 @@ trait ControllerTrait
|
|||
* @param int $status The status code to use for the Response
|
||||
*
|
||||
* @return RedirectResponse
|
||||
*
|
||||
* @final since version 3.4
|
||||
*/
|
||||
protected function redirectToRoute($route, array $parameters = array(), $status = 302)
|
||||
{
|
||||
|
@ -110,6 +146,8 @@ trait ControllerTrait
|
|||
* @param array $context Context to pass to serializer when using serializer component
|
||||
*
|
||||
* @return JsonResponse
|
||||
*
|
||||
* @final since version 3.4
|
||||
*/
|
||||
protected function json($data, $status = 200, $headers = array(), $context = array())
|
||||
{
|
||||
|
@ -132,6 +170,8 @@ trait ControllerTrait
|
|||
* @param string $disposition Disposition of response ("attachment" is default, other type is "inline")
|
||||
*
|
||||
* @return BinaryFileResponse
|
||||
*
|
||||
* @final since version 3.4
|
||||
*/
|
||||
protected function file($file, $fileName = null, $disposition = ResponseHeaderBag::DISPOSITION_ATTACHMENT)
|
||||
{
|
||||
|
@ -148,6 +188,8 @@ trait ControllerTrait
|
|||
* @param string $message The message
|
||||
*
|
||||
* @throws \LogicException
|
||||
*
|
||||
* @final since version 3.4
|
||||
*/
|
||||
protected function addFlash($type, $message)
|
||||
{
|
||||
|
@ -167,6 +209,8 @@ trait ControllerTrait
|
|||
* @return bool
|
||||
*
|
||||
* @throws \LogicException
|
||||
*
|
||||
* @final since version 3.4
|
||||
*/
|
||||
protected function isGranted($attributes, $subject = null)
|
||||
{
|
||||
|
@ -186,6 +230,8 @@ trait ControllerTrait
|
|||
* @param string $message The message passed to the exception
|
||||
*
|
||||
* @throws AccessDeniedException
|
||||
*
|
||||
* @final since version 3.4
|
||||
*/
|
||||
protected function denyAccessUnlessGranted($attributes, $subject = null, $message = 'Access Denied.')
|
||||
{
|
||||
|
@ -205,6 +251,8 @@ trait ControllerTrait
|
|||
* @param array $parameters An array of parameters to pass to the view
|
||||
*
|
||||
* @return string The rendered view
|
||||
*
|
||||
* @final since version 3.4
|
||||
*/
|
||||
protected function renderView($view, array $parameters = array())
|
||||
{
|
||||
|
@ -227,14 +275,16 @@ trait ControllerTrait
|
|||
* @param Response $response A response instance
|
||||
*
|
||||
* @return Response A Response instance
|
||||
*
|
||||
* @final since version 3.4
|
||||
*/
|
||||
protected function render($view, array $parameters = array(), Response $response = null)
|
||||
{
|
||||
if ($this->container->has('templating')) {
|
||||
return $this->container->get('templating')->renderResponse($view, $parameters, $response);
|
||||
}
|
||||
|
||||
if (!$this->container->has('twig')) {
|
||||
$content = $this->container->get('templating')->render($view, $parameters);
|
||||
} elseif ($this->container->has('twig')) {
|
||||
$content = $this->container->get('twig')->render($view, $parameters);
|
||||
} else {
|
||||
throw new \LogicException('You can not use the "render" method if the Templating Component or the Twig Bundle are not available.');
|
||||
}
|
||||
|
||||
|
@ -242,7 +292,7 @@ trait ControllerTrait
|
|||
$response = new Response();
|
||||
}
|
||||
|
||||
$response->setContent($this->container->get('twig')->render($view, $parameters));
|
||||
$response->setContent($content);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
@ -255,6 +305,8 @@ trait ControllerTrait
|
|||
* @param StreamedResponse $response A response instance
|
||||
*
|
||||
* @return StreamedResponse A StreamedResponse instance
|
||||
*
|
||||
* @final since version 3.4
|
||||
*/
|
||||
protected function stream($view, array $parameters = array(), StreamedResponse $response = null)
|
||||
{
|
||||
|
@ -294,6 +346,8 @@ trait ControllerTrait
|
|||
* @param \Exception|null $previous The previous exception
|
||||
*
|
||||
* @return NotFoundHttpException
|
||||
*
|
||||
* @final since version 3.4
|
||||
*/
|
||||
protected function createNotFoundException($message = 'Not Found', \Exception $previous = null)
|
||||
{
|
||||
|
@ -311,6 +365,8 @@ trait ControllerTrait
|
|||
* @param \Exception|null $previous The previous exception
|
||||
*
|
||||
* @return AccessDeniedException
|
||||
*
|
||||
* @final since version 3.4
|
||||
*/
|
||||
protected function createAccessDeniedException($message = 'Access Denied.', \Exception $previous = null)
|
||||
{
|
||||
|
@ -325,6 +381,8 @@ trait ControllerTrait
|
|||
* @param array $options Options for the form
|
||||
*
|
||||
* @return Form
|
||||
*
|
||||
* @final since version 3.4
|
||||
*/
|
||||
protected function createForm($type, $data = null, array $options = array())
|
||||
{
|
||||
|
@ -338,6 +396,8 @@ trait ControllerTrait
|
|||
* @param array $options Options for the form
|
||||
*
|
||||
* @return FormBuilder
|
||||
*
|
||||
* @final since version 3.4
|
||||
*/
|
||||
protected function createFormBuilder($data = null, array $options = array())
|
||||
{
|
||||
|
@ -350,6 +410,8 @@ trait ControllerTrait
|
|||
* @return Registry
|
||||
*
|
||||
* @throws \LogicException If DoctrineBundle is not available
|
||||
*
|
||||
* @final since version 3.4
|
||||
*/
|
||||
protected function getDoctrine()
|
||||
{
|
||||
|
@ -368,6 +430,8 @@ trait ControllerTrait
|
|||
* @throws \LogicException If SecurityBundle is not available
|
||||
*
|
||||
* @see TokenInterface::getUser()
|
||||
*
|
||||
* @final since version 3.4
|
||||
*/
|
||||
protected function getUser()
|
||||
{
|
||||
|
@ -394,6 +458,8 @@ trait ControllerTrait
|
|||
* @param string $token The actual token sent with the request that should be validated
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @final since version 3.4
|
||||
*/
|
||||
protected function isCsrfTokenValid($id, $token)
|
||||
{
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
namespace Symfony\Bundle\FrameworkBundle\Controller;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
@ -23,10 +23,37 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
|||
* Redirects a request to another URL.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @final since version 3.4
|
||||
*/
|
||||
class RedirectController implements ContainerAwareInterface
|
||||
{
|
||||
use ContainerAwareTrait;
|
||||
/**
|
||||
* @deprecated since version 3.4, to be removed in 4.0
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
private $router;
|
||||
private $httpPort;
|
||||
private $httpsPort;
|
||||
|
||||
public function __construct(UrlGeneratorInterface $router = null, $httpPort = null, $httpsPort = null)
|
||||
{
|
||||
$this->router = $router;
|
||||
$this->httpPort = $httpPort;
|
||||
$this->httpsPort = $httpsPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since version 3.4, to be removed in 4.0 alongside with the ContainerAwareInterface type.
|
||||
*/
|
||||
public function setContainer(ContainerInterface $container = null)
|
||||
{
|
||||
@trigger_error(sprintf('The "%s()" method is deprecated since version 3.4 and will be removed in 4.0. Inject an UrlGeneratorInterface using the constructor instead.', __METHOD__), E_USER_DEPRECATED);
|
||||
|
||||
$this->container = $container;
|
||||
$this->router = $container->get('router');
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirects to another route with the given name.
|
||||
|
@ -61,7 +88,7 @@ class RedirectController implements ContainerAwareInterface
|
|||
}
|
||||
}
|
||||
|
||||
return new RedirectResponse($this->container->get('router')->generate($route, $attributes, UrlGeneratorInterface::ABSOLUTE_URL), $permanent ? 301 : 302);
|
||||
return new RedirectResponse($this->router->generate($route, $attributes, UrlGeneratorInterface::ABSOLUTE_URL), $permanent ? 301 : 302);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -115,8 +142,11 @@ class RedirectController implements ContainerAwareInterface
|
|||
if (null === $httpPort) {
|
||||
if ('http' === $request->getScheme()) {
|
||||
$httpPort = $request->getPort();
|
||||
} elseif ($this->container->hasParameter('request_listener.http_port')) {
|
||||
} elseif ($this->container && $this->container->hasParameter('request_listener.http_port')) {
|
||||
@trigger_error(sprintf('Passing the http port as a container parameter is deprecated since Symfony 3.4 and won\'t be possible in 4.0. Pass it to the constructor of the "%s" class instead.', __CLASS__), E_USER_DEPRECATED);
|
||||
$httpPort = $this->container->getParameter('request_listener.http_port');
|
||||
} else {
|
||||
$httpPort = $this->httpPort;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,8 +157,11 @@ class RedirectController implements ContainerAwareInterface
|
|||
if (null === $httpsPort) {
|
||||
if ('https' === $request->getScheme()) {
|
||||
$httpsPort = $request->getPort();
|
||||
} elseif ($this->container->hasParameter('request_listener.https_port')) {
|
||||
} elseif ($this->container && $this->container->hasParameter('request_listener.https_port')) {
|
||||
@trigger_error(sprintf('Passing the https port as a container parameter is deprecated since Symfony 3.4 and won\'t be possible in 4.0. Pass it to the constructor of the "%s" class instead.', __CLASS__), E_USER_DEPRECATED);
|
||||
$httpsPort = $this->container->getParameter('request_listener.https_port');
|
||||
} else {
|
||||
$httpsPort = $this->httpsPort;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,17 +12,48 @@
|
|||
namespace Symfony\Bundle\FrameworkBundle\Controller;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Templating\EngineInterface;
|
||||
use Twig\Environment;
|
||||
|
||||
/**
|
||||
* TemplateController.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @final since version 3.4
|
||||
*/
|
||||
class TemplateController implements ContainerAwareInterface
|
||||
{
|
||||
use ContainerAwareTrait;
|
||||
/**
|
||||
* @deprecated since version 3.4, to be removed in 4.0
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
private $twig;
|
||||
private $templating;
|
||||
|
||||
public function __construct(Environment $twig = null, EngineInterface $templating = null)
|
||||
{
|
||||
$this->twig = $twig;
|
||||
$this->templating = $templating;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since version 3.4, to be removed in 4.0 alongside with the ContainerAwareInterface type.
|
||||
*/
|
||||
public function setContainer(ContainerInterface $container = null)
|
||||
{
|
||||
@trigger_error(sprintf('The "%s()" method is deprecated since version 3.4 and will be removed in 4.0. Inject a Twig Environment or an EngineInterface using the constructor instead.', __METHOD__), E_USER_DEPRECATED);
|
||||
|
||||
if ($container->has('templating')) {
|
||||
$this->templating = $container->get('templating');
|
||||
} elseif ($container->has('twig')) {
|
||||
$this->twig = $container->get('twig');
|
||||
}
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a template.
|
||||
|
@ -36,10 +67,10 @@ class TemplateController implements ContainerAwareInterface
|
|||
*/
|
||||
public function templateAction($template, $maxAge = null, $sharedAge = null, $private = null)
|
||||
{
|
||||
if ($this->container->has('templating')) {
|
||||
$response = $this->container->get('templating')->renderResponse($template);
|
||||
} elseif ($this->container->has('twig')) {
|
||||
$response = new Response($this->container->get('twig')->render($template));
|
||||
if ($this->templating) {
|
||||
$response = new Response($this->templating->render($template));
|
||||
} elseif ($this->twig) {
|
||||
$response = new Response($this->twig->render($template));
|
||||
} else {
|
||||
throw new \LogicException('You can not use the TemplateController if the Templating Component or the Twig Bundle are not available.');
|
||||
}
|
||||
|
|
|
@ -466,9 +466,9 @@ class FrameworkExtension extends Extension
|
|||
|
||||
$container->setParameter('profiler.storage.dsn', $config['dsn']);
|
||||
|
||||
if (!$config['collect']) {
|
||||
$container->getDefinition('profiler')->addMethodCall('disable', array());
|
||||
}
|
||||
$container->getDefinition('profiler')
|
||||
->addArgument($config['collect'])
|
||||
->addTag('kernel.reset', array('method' => 'reset'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -104,5 +104,16 @@
|
|||
<argument>%kernel.project_dir%</argument>
|
||||
<argument>%kernel.debug%</argument>
|
||||
</service>
|
||||
|
||||
<service id="Symfony\Bundle\FrameworkBundle\Controller\RedirectController" public="true">
|
||||
<argument type="service" id="router" />
|
||||
<argument>%request_listener.http_port%</argument>
|
||||
<argument>%request_listener.https_port%</argument>
|
||||
</service>
|
||||
|
||||
<service id="Symfony\Bundle\FrameworkBundle\Controller\TemplateController" public="true">
|
||||
<argument type="service" id="twig" on-invalid="ignore" />
|
||||
<argument type="service" id="templating" on-invalid="ignore" />
|
||||
</service>
|
||||
</services>
|
||||
</container>
|
||||
|
|
|
@ -451,7 +451,7 @@ abstract class ControllerTraitTest extends TestCase
|
|||
public function testRenderTemplating()
|
||||
{
|
||||
$templating = $this->getMockBuilder('Symfony\Bundle\FrameworkBundle\Templating\EngineInterface')->getMock();
|
||||
$templating->expects($this->once())->method('renderResponse')->willReturn(new Response('bar'));
|
||||
$templating->expects($this->once())->method('render')->willReturn('bar');
|
||||
|
||||
$container = new Container();
|
||||
$container->set('templating', $templating);
|
||||
|
|
|
@ -15,6 +15,7 @@ use Symfony\Component\HttpFoundation\Response;
|
|||
use Symfony\Component\HttpFoundation\ParameterBag;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\RedirectController;
|
||||
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
|
||||
|
||||
|
@ -66,23 +67,14 @@ class RedirectControllerTest extends TestCase
|
|||
|
||||
$request->attributes = new ParameterBag($attributes);
|
||||
|
||||
$router = $this->getMockBuilder('Symfony\Component\Routing\RouterInterface')->getMock();
|
||||
$router = $this->getMockBuilder(UrlGeneratorInterface::class)->getMock();
|
||||
$router
|
||||
->expects($this->once())
|
||||
->method('generate')
|
||||
->with($this->equalTo($route), $this->equalTo($expectedAttributes))
|
||||
->will($this->returnValue($url));
|
||||
|
||||
$container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerInterface')->getMock();
|
||||
|
||||
$container
|
||||
->expects($this->once())
|
||||
->method('get')
|
||||
->with($this->equalTo('router'))
|
||||
->will($this->returnValue($router));
|
||||
|
||||
$controller = new RedirectController();
|
||||
$controller->setContainer($container);
|
||||
$controller = new RedirectController($router);
|
||||
|
||||
$returnResponse = $controller->redirectAction($request, $route, $permanent, $ignoreAttributes);
|
||||
|
||||
|
@ -130,7 +122,7 @@ class RedirectControllerTest extends TestCase
|
|||
$this->assertEquals(302, $returnResponse->getStatusCode());
|
||||
}
|
||||
|
||||
public function testUrlRedirectDefaultPortParameters()
|
||||
public function testUrlRedirectDefaultPorts()
|
||||
{
|
||||
$host = 'www.example.com';
|
||||
$baseUrl = '/base';
|
||||
|
@ -151,6 +143,30 @@ class RedirectControllerTest extends TestCase
|
|||
$this->assertRedirectUrl($returnValue, $expectedUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testUrlRedirectDefaultPortParameters()
|
||||
{
|
||||
$host = 'www.example.com';
|
||||
$baseUrl = '/base';
|
||||
$path = '/redirect-path';
|
||||
$httpPort = 1080;
|
||||
$httpsPort = 1443;
|
||||
|
||||
$expectedUrl = "https://$host:$httpsPort$baseUrl$path";
|
||||
$request = $this->createRequestObject('http', $host, $httpPort, $baseUrl);
|
||||
$controller = $this->createLegacyRedirectController(null, $httpsPort);
|
||||
$returnValue = $controller->urlRedirectAction($request, $path, false, 'https');
|
||||
$this->assertRedirectUrl($returnValue, $expectedUrl);
|
||||
|
||||
$expectedUrl = "http://$host:$httpPort$baseUrl$path";
|
||||
$request = $this->createRequestObject('https', $host, $httpPort, $baseUrl);
|
||||
$controller = $this->createLegacyRedirectController($httpPort);
|
||||
$returnValue = $controller->urlRedirectAction($request, $path, false, 'http');
|
||||
$this->assertRedirectUrl($returnValue, $expectedUrl);
|
||||
}
|
||||
|
||||
public function urlRedirectProvider()
|
||||
{
|
||||
return array(
|
||||
|
@ -256,6 +272,14 @@ class RedirectControllerTest extends TestCase
|
|||
}
|
||||
|
||||
private function createRedirectController($httpPort = null, $httpsPort = null)
|
||||
{
|
||||
return new RedirectController(null, $httpPort, $httpsPort);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
private function createLegacyRedirectController($httpPort = null, $httpsPort = null)
|
||||
{
|
||||
$container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerInterface')->getMock();
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
namespace Symfony\Bundle\FrameworkBundle\Tests\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\TemplateController;
|
||||
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
|
@ -25,6 +25,29 @@ class TemplateControllerTest extends TestCase
|
|||
$twig = $this->getMockBuilder('Twig\Environment')->disableOriginalConstructor()->getMock();
|
||||
$twig->expects($this->once())->method('render')->willReturn('bar');
|
||||
|
||||
$controller = new TemplateController($twig);
|
||||
|
||||
$this->assertEquals('bar', $controller->templateAction('mytemplate')->getContent());
|
||||
}
|
||||
|
||||
public function testTemplating()
|
||||
{
|
||||
$templating = $this->getMockBuilder(EngineInterface::class)->getMock();
|
||||
$templating->expects($this->once())->method('render')->willReturn('bar');
|
||||
|
||||
$controller = new TemplateController(null, $templating);
|
||||
|
||||
$this->assertEquals('bar', $controller->templateAction('mytemplate')->getContent());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testLegacyTwig()
|
||||
{
|
||||
$twig = $this->getMockBuilder('Twig\Environment')->disableOriginalConstructor()->getMock();
|
||||
$twig->expects($this->once())->method('render')->willReturn('bar');
|
||||
|
||||
$container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerInterface')->getMock();
|
||||
$container->expects($this->at(0))->method('has')->will($this->returnValue(false));
|
||||
$container->expects($this->at(1))->method('has')->will($this->returnValue(true));
|
||||
|
@ -36,10 +59,13 @@ class TemplateControllerTest extends TestCase
|
|||
$this->assertEquals('bar', $controller->templateAction('mytemplate')->getContent());
|
||||
}
|
||||
|
||||
public function testTemplating()
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testLegacyTemplating()
|
||||
{
|
||||
$templating = $this->getMockBuilder('Symfony\Bundle\FrameworkBundle\Templating\EngineInterface')->getMock();
|
||||
$templating->expects($this->once())->method('renderResponse')->willReturn(new Response('bar'));
|
||||
$templating->expects($this->once())->method('render')->willReturn('bar');
|
||||
|
||||
$container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerInterface')->getMock();
|
||||
$container->expects($this->at(0))->method('has')->willReturn(true);
|
||||
|
@ -57,12 +83,7 @@ class TemplateControllerTest extends TestCase
|
|||
*/
|
||||
public function testNoTwigNorTemplating()
|
||||
{
|
||||
$container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerInterface')->getMock();
|
||||
$container->expects($this->at(0))->method('has')->willReturn(false);
|
||||
$container->expects($this->at(1))->method('has')->willReturn(false);
|
||||
|
||||
$controller = new TemplateController();
|
||||
$controller->setContainer($container);
|
||||
|
||||
$controller->templateAction('mytemplate')->getContent();
|
||||
}
|
||||
|
|
|
@ -194,6 +194,14 @@ class SecurityDataCollector extends DataCollector implements LateDataCollectorIn
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->data = array();
|
||||
}
|
||||
|
||||
public function lateCollect()
|
||||
{
|
||||
$this->data = $this->cloneVar($this->data);
|
||||
|
|
|
@ -254,19 +254,12 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface, R
|
|||
|
||||
$f = $this->getTagsByKey;
|
||||
$tagsByKey = $f($items);
|
||||
$deletedTags = $this->deferred = array();
|
||||
$this->deferred = array();
|
||||
$tagVersions = $this->getTagVersions($tagsByKey);
|
||||
$f = $this->createCacheItem;
|
||||
|
||||
foreach ($tagsByKey as $key => $tags) {
|
||||
if ($tags) {
|
||||
$this->pool->saveDeferred($f(static::TAGS_PREFIX.$key, array_intersect_key($tagVersions, $tags), $items[$key]));
|
||||
} else {
|
||||
$deletedTags[] = static::TAGS_PREFIX.$key;
|
||||
}
|
||||
}
|
||||
if ($deletedTags) {
|
||||
$this->pool->deleteItems($deletedTags);
|
||||
$this->pool->saveDeferred($f(static::TAGS_PREFIX.$key, array_intersect_key($tagVersions, $tags), $items[$key]));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,15 @@ class CacheDataCollector extends DataCollector implements LateDataCollectorInter
|
|||
$this->data['total']['statistics'] = $this->calculateTotalStatistics();
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->data = array();
|
||||
foreach ($this->instances as $instance) {
|
||||
// Calling getCalls() will clear the calls.
|
||||
$instance->getCalls();
|
||||
}
|
||||
}
|
||||
|
||||
public function lateCollect()
|
||||
{
|
||||
$this->data = $this->cloneVar($this->data);
|
||||
|
|
|
@ -132,6 +132,10 @@ class ResourceCheckerConfigCache implements ConfigCacheInterface
|
|||
// discard chmod failure (some filesystem may not support it)
|
||||
}
|
||||
}
|
||||
|
||||
if (\function_exists('opcache_invalidate') && ini_get('opcache.enable')) {
|
||||
@opcache_invalidate($this->file, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -152,8 +152,8 @@ class Container implements ResettableContainerInterface
|
|||
throw new InvalidArgumentException('You cannot set service "service_container".');
|
||||
}
|
||||
|
||||
if (isset($this->fileMap[$id]) || isset($this->methodMap[$id])) {
|
||||
throw new InvalidArgumentException(sprintf('You cannot set the pre-defined service "%s".', $id));
|
||||
if (isset($this->services[$id]) && (isset($this->fileMap[$id]) || isset($this->methodMap[$id]))) {
|
||||
throw new InvalidArgumentException(sprintf('The "%s" service is already initialized, you cannot replace it.', $id));
|
||||
}
|
||||
|
||||
if (isset($this->aliases[$id])) {
|
||||
|
|
|
@ -889,26 +889,17 @@ EOF;
|
|||
$code .= <<<EOF
|
||||
}
|
||||
|
||||
/*{$this->docStar}
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
\$this->privates = array();
|
||||
parent::reset();
|
||||
}
|
||||
|
||||
/*{$this->docStar}
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped container that was already compiled.');
|
||||
}
|
||||
|
||||
/*{$this->docStar}
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCompiled()
|
||||
{
|
||||
return true;
|
||||
|
@ -919,9 +910,6 @@ EOF;
|
|||
if ($this->asFiles) {
|
||||
$code .= <<<EOF
|
||||
|
||||
/*{$this->docStar}
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function load(\$file, \$lazyLoad = true)
|
||||
{
|
||||
return require \$file;
|
||||
|
@ -1052,9 +1040,6 @@ EOF;
|
|||
|
||||
$code = <<<'EOF'
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getParameter($name)
|
||||
{
|
||||
$name = (string) $name;
|
||||
|
@ -1069,9 +1054,6 @@ EOF;
|
|||
return $this->parameters[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasParameter($name)
|
||||
{
|
||||
$name = (string) $name;
|
||||
|
@ -1079,17 +1061,11 @@ EOF;
|
|||
return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setParameter($name, $value)
|
||||
{
|
||||
throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getParameterBag()
|
||||
{
|
||||
if (null === $this->parameterBag) {
|
||||
|
@ -1104,9 +1080,6 @@ EOF;
|
|||
}
|
||||
|
||||
EOF;
|
||||
if ('' === $this->docStar) {
|
||||
$code = str_replace('/**', '/*', $code);
|
||||
}
|
||||
|
||||
if ($dynamicPhp) {
|
||||
$loadedDynamicParameters = $this->exportParameters(array_combine(array_keys($dynamicPhp), array_fill(0, count($dynamicPhp), false)), '', 8);
|
||||
|
|
|
@ -165,6 +165,36 @@ class ContainerTest extends TestCase
|
|||
$this->assertSame($foo, $c->get('alias'), '->set() replaces an existing alias');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage The "bar" service is already initialized, you cannot replace it.
|
||||
*/
|
||||
public function testSetWithNullOnInitializedPredefinedService()
|
||||
{
|
||||
$sc = new Container();
|
||||
$sc->set('foo', new \stdClass());
|
||||
$sc->set('foo', null);
|
||||
$this->assertFalse($sc->has('foo'), '->set() with null service resets the service');
|
||||
|
||||
$sc = new ProjectServiceContainer();
|
||||
$sc->get('bar');
|
||||
$sc->set('bar', null);
|
||||
$this->assertTrue($sc->has('bar'), '->set() with null service resets the pre-defined service');
|
||||
}
|
||||
|
||||
public function testSetWithNullOnUninitializedPredefinedService()
|
||||
{
|
||||
$sc = new Container();
|
||||
$sc->set('foo', new \stdClass());
|
||||
$sc->get('foo', null);
|
||||
$sc->set('foo', null);
|
||||
$this->assertFalse($sc->has('foo'), '->set() with null service resets the service');
|
||||
|
||||
$sc = new ProjectServiceContainer();
|
||||
$sc->set('bar', null);
|
||||
$this->assertTrue($sc->has('bar'), '->set() with null service resets the pre-defined service');
|
||||
}
|
||||
|
||||
public function testGet()
|
||||
{
|
||||
$sc = new ProjectServiceContainer();
|
||||
|
@ -362,16 +392,6 @@ class ContainerTest extends TestCase
|
|||
$c->get('internal_dependency');
|
||||
$c->get('internal');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage You cannot set the pre-defined service "bar".
|
||||
*/
|
||||
public function testReplacingAPreDefinedService()
|
||||
{
|
||||
$c = new ProjectServiceContainer();
|
||||
$c->set('bar', new \stdClass());
|
||||
}
|
||||
}
|
||||
|
||||
class ProjectServiceContainer extends Container
|
||||
|
|
|
@ -286,7 +286,7 @@ class PhpDumperTest extends TestCase
|
|||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage You cannot set the pre-defined service "bar".
|
||||
* @expectedExceptionMessage The "bar2" service is already initialized, you cannot replace it.
|
||||
*/
|
||||
public function testOverrideServiceWhenUsingADumpedContainer()
|
||||
{
|
||||
|
@ -294,7 +294,8 @@ class PhpDumperTest extends TestCase
|
|||
require_once self::$fixturesPath.'/includes/foo.php';
|
||||
|
||||
$container = new \ProjectServiceContainer();
|
||||
$container->set('bar', $bar = new \stdClass());
|
||||
$container->get('bar2');
|
||||
$container->set('bar2', new \stdClass());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -29,26 +29,17 @@ class Container extends AbstractContainer
|
|||
$this->aliases = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->privates = array();
|
||||
parent::reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped container that was already compiled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCompiled()
|
||||
{
|
||||
return true;
|
||||
|
|
|
@ -27,26 +27,17 @@ class ProjectServiceContainer extends Container
|
|||
$this->aliases = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->privates = array();
|
||||
parent::reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped container that was already compiled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCompiled()
|
||||
{
|
||||
return true;
|
||||
|
|
|
@ -32,26 +32,17 @@ class ProjectServiceContainer extends Container
|
|||
$this->aliases = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->privates = array();
|
||||
parent::reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped container that was already compiled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCompiled()
|
||||
{
|
||||
return true;
|
||||
|
@ -67,9 +58,6 @@ class ProjectServiceContainer extends Container
|
|||
return $this->services['test'] = new \stdClass(array('only dot' => '.', 'concatenation as value' => '.\'\'.', 'concatenation from the start value' => '\'\'.', '.' => 'dot as a key', '.\'\'.' => 'concatenation as a key', '\'\'.' => 'concatenation from the start key', 'optimize concatenation' => 'string1-string2', 'optimize concatenation with empty string' => 'string1string2', 'optimize concatenation from the start' => 'start', 'optimize concatenation at the end' => 'end'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getParameter($name)
|
||||
{
|
||||
$name = (string) $name;
|
||||
|
@ -84,9 +72,6 @@ class ProjectServiceContainer extends Container
|
|||
return $this->parameters[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasParameter($name)
|
||||
{
|
||||
$name = (string) $name;
|
||||
|
@ -94,17 +79,11 @@ class ProjectServiceContainer extends Container
|
|||
return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setParameter($name, $value)
|
||||
{
|
||||
throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getParameterBag()
|
||||
{
|
||||
if (null === $this->parameterBag) {
|
||||
|
|
|
@ -36,26 +36,17 @@ class ProjectServiceContainer extends Container
|
|||
$this->aliases = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->privates = array();
|
||||
parent::reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped container that was already compiled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCompiled()
|
||||
{
|
||||
return true;
|
||||
|
@ -71,9 +62,6 @@ class ProjectServiceContainer extends Container
|
|||
return $this->services['test'] = new \stdClass(('wiz'.$this->targetDirs[1]), array(('wiz'.$this->targetDirs[1]) => ($this->targetDirs[2].'/')));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getParameter($name)
|
||||
{
|
||||
$name = (string) $name;
|
||||
|
@ -88,9 +76,6 @@ class ProjectServiceContainer extends Container
|
|||
return $this->parameters[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasParameter($name)
|
||||
{
|
||||
$name = (string) $name;
|
||||
|
@ -98,17 +83,11 @@ class ProjectServiceContainer extends Container
|
|||
return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setParameter($name, $value)
|
||||
{
|
||||
throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getParameterBag()
|
||||
{
|
||||
if (null === $this->parameterBag) {
|
||||
|
|
|
@ -30,26 +30,17 @@ class ProjectServiceContainer extends Container
|
|||
$this->aliases = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->privates = array();
|
||||
parent::reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped container that was already compiled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCompiled()
|
||||
{
|
||||
return true;
|
||||
|
|
|
@ -31,26 +31,17 @@ class ProjectServiceContainer extends Container
|
|||
$this->aliases = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->privates = array();
|
||||
parent::reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped container that was already compiled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCompiled()
|
||||
{
|
||||
return true;
|
||||
|
|
|
@ -30,26 +30,17 @@ class ProjectServiceContainer extends Container
|
|||
$this->aliases = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->privates = array();
|
||||
parent::reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped container that was already compiled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCompiled()
|
||||
{
|
||||
return true;
|
||||
|
|
|
@ -36,26 +36,17 @@ class Symfony_DI_PhpDumper_Test_EnvParameters extends Container
|
|||
$this->aliases = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->privates = array();
|
||||
parent::reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped container that was already compiled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCompiled()
|
||||
{
|
||||
return true;
|
||||
|
@ -73,9 +64,6 @@ class Symfony_DI_PhpDumper_Test_EnvParameters extends Container
|
|||
return $this->services['test'] = new $class($this->getEnv('Bar'), 'foo'.$this->getEnv('string:FOO').'baz', $this->getEnv('int:Baz'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getParameter($name)
|
||||
{
|
||||
$name = (string) $name;
|
||||
|
@ -90,9 +78,6 @@ class Symfony_DI_PhpDumper_Test_EnvParameters extends Container
|
|||
return $this->parameters[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasParameter($name)
|
||||
{
|
||||
$name = (string) $name;
|
||||
|
@ -100,17 +85,11 @@ class Symfony_DI_PhpDumper_Test_EnvParameters extends Container
|
|||
return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setParameter($name, $value)
|
||||
{
|
||||
throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getParameterBag()
|
||||
{
|
||||
if (null === $this->parameterBag) {
|
||||
|
|
|
@ -30,22 +30,26 @@ class ProjectServiceContainer extends Container
|
|||
$this->aliases = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped container that was already compiled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCompiled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
public function isFrozen()
|
||||
{
|
||||
@trigger_error(sprintf('The %s() method is deprecated since version 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
>>>>>>> 3.4
|
||||
/**
|
||||
* Gets the 'foo' service.
|
||||
*
|
||||
|
|
|
@ -31,26 +31,17 @@ class ProjectServiceContainer extends Container
|
|||
$this->aliases = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->privates = array();
|
||||
parent::reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped container that was already compiled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCompiled()
|
||||
{
|
||||
return true;
|
||||
|
|
|
@ -29,34 +29,22 @@ class ProjectServiceContainer extends Container
|
|||
$this->aliases = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->privates = array();
|
||||
parent::reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped container that was already compiled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCompiled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getParameter($name)
|
||||
{
|
||||
$name = (string) $name;
|
||||
|
@ -71,9 +59,6 @@ class ProjectServiceContainer extends Container
|
|||
return $this->parameters[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasParameter($name)
|
||||
{
|
||||
$name = (string) $name;
|
||||
|
@ -81,17 +66,11 @@ class ProjectServiceContainer extends Container
|
|||
return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setParameter($name, $value)
|
||||
{
|
||||
throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getParameterBag()
|
||||
{
|
||||
if (null === $this->parameterBag) {
|
||||
|
|
|
@ -351,34 +351,22 @@ class Container%s extends Container
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->privates = array();
|
||||
parent::reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped container that was already compiled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCompiled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function load($file, $lazyLoad = true)
|
||||
{
|
||||
return require $file;
|
||||
|
@ -394,9 +382,6 @@ class Container%s extends Container
|
|||
return new \Bar\FooClass(($this->services['deprecated_service'] ?? $this->load(__DIR__.'/getDeprecatedServiceService.php')));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getParameter($name)
|
||||
{
|
||||
$name = (string) $name;
|
||||
|
@ -411,9 +396,6 @@ class Container%s extends Container
|
|||
return $this->parameters[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasParameter($name)
|
||||
{
|
||||
$name = (string) $name;
|
||||
|
@ -421,17 +403,11 @@ class Container%s extends Container
|
|||
return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setParameter($name, $value)
|
||||
{
|
||||
throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getParameterBag()
|
||||
{
|
||||
if (null === $this->parameterBag) {
|
||||
|
|
|
@ -56,26 +56,17 @@ class ProjectServiceContainer extends Container
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->privates = array();
|
||||
parent::reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped container that was already compiled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCompiled()
|
||||
{
|
||||
return true;
|
||||
|
@ -395,9 +386,6 @@ class ProjectServiceContainer extends Container
|
|||
return $this->privates['factory_simple'] = new \SimpleFactoryClass('foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getParameter($name)
|
||||
{
|
||||
$name = (string) $name;
|
||||
|
@ -412,9 +400,6 @@ class ProjectServiceContainer extends Container
|
|||
return $this->parameters[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasParameter($name)
|
||||
{
|
||||
$name = (string) $name;
|
||||
|
@ -422,17 +407,11 @@ class ProjectServiceContainer extends Container
|
|||
return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setParameter($name, $value)
|
||||
{
|
||||
throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getParameterBag()
|
||||
{
|
||||
if (null === $this->parameterBag) {
|
||||
|
|
|
@ -36,26 +36,17 @@ class ProjectServiceContainer extends Container
|
|||
$this->aliases = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->privates = array();
|
||||
parent::reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped container that was already compiled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCompiled()
|
||||
{
|
||||
return true;
|
||||
|
@ -75,9 +66,6 @@ class ProjectServiceContainer extends Container
|
|||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getParameter($name)
|
||||
{
|
||||
$name = (string) $name;
|
||||
|
@ -92,9 +80,6 @@ class ProjectServiceContainer extends Container
|
|||
return $this->parameters[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasParameter($name)
|
||||
{
|
||||
$name = (string) $name;
|
||||
|
@ -102,17 +87,11 @@ class ProjectServiceContainer extends Container
|
|||
return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setParameter($name, $value)
|
||||
{
|
||||
throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getParameterBag()
|
||||
{
|
||||
if (null === $this->parameterBag) {
|
||||
|
|
|
@ -29,34 +29,22 @@ class Symfony_DI_PhpDumper_Test_Base64Parameters extends Container
|
|||
$this->aliases = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->privates = array();
|
||||
parent::reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped container that was already compiled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCompiled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getParameter($name)
|
||||
{
|
||||
$name = (string) $name;
|
||||
|
@ -71,9 +59,6 @@ class Symfony_DI_PhpDumper_Test_Base64Parameters extends Container
|
|||
return $this->parameters[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasParameter($name)
|
||||
{
|
||||
$name = (string) $name;
|
||||
|
@ -81,17 +66,11 @@ class Symfony_DI_PhpDumper_Test_Base64Parameters extends Container
|
|||
return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setParameter($name, $value)
|
||||
{
|
||||
throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getParameterBag()
|
||||
{
|
||||
if (null === $this->parameterBag) {
|
||||
|
|
|
@ -37,26 +37,17 @@ class ProjectServiceContainer extends Container
|
|||
$this->aliases = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->privates = array();
|
||||
parent::reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped container that was already compiled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCompiled()
|
||||
{
|
||||
return true;
|
||||
|
|
|
@ -31,26 +31,17 @@ class ProjectServiceContainer extends Container
|
|||
$this->aliases = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->privates = array();
|
||||
parent::reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped container that was already compiled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCompiled()
|
||||
{
|
||||
return true;
|
||||
|
|
|
@ -30,26 +30,17 @@ class ProjectServiceContainer extends Container
|
|||
$this->aliases = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->privates = array();
|
||||
parent::reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped container that was already compiled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCompiled()
|
||||
{
|
||||
return true;
|
||||
|
|
|
@ -33,26 +33,17 @@ class Symfony_DI_PhpDumper_Test_Rot13Parameters extends Container
|
|||
$this->aliases = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->privates = array();
|
||||
parent::reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped container that was already compiled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCompiled()
|
||||
{
|
||||
return true;
|
||||
|
@ -80,9 +71,6 @@ class Symfony_DI_PhpDumper_Test_Rot13Parameters extends Container
|
|||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getParameter($name)
|
||||
{
|
||||
$name = (string) $name;
|
||||
|
@ -97,9 +85,6 @@ class Symfony_DI_PhpDumper_Test_Rot13Parameters extends Container
|
|||
return $this->parameters[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasParameter($name)
|
||||
{
|
||||
$name = (string) $name;
|
||||
|
@ -107,17 +92,11 @@ class Symfony_DI_PhpDumper_Test_Rot13Parameters extends Container
|
|||
return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setParameter($name, $value)
|
||||
{
|
||||
throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getParameterBag()
|
||||
{
|
||||
if (null === $this->parameterBag) {
|
||||
|
|
|
@ -31,26 +31,17 @@ class ProjectServiceContainer extends Container
|
|||
$this->aliases = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->privates = array();
|
||||
parent::reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped container that was already compiled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCompiled()
|
||||
{
|
||||
return true;
|
||||
|
|
|
@ -32,26 +32,17 @@ class Symfony_DI_PhpDumper_Test_Uninitialized_Reference extends Container
|
|||
$this->aliases = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->privates = array();
|
||||
parent::reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped container that was already compiled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCompiled()
|
||||
{
|
||||
return true;
|
||||
|
|
|
@ -6,6 +6,11 @@ CHANGELOG
|
|||
|
||||
* removed the `ContainerAwareEventDispatcher` class
|
||||
|
||||
3.4.0
|
||||
-----
|
||||
|
||||
* Implementing `TraceableEventDispatcherInterface` without the `reset()` method has been deprecated.
|
||||
|
||||
3.3.0
|
||||
-----
|
||||
|
||||
|
|
|
@ -212,6 +212,11 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
|
|||
return $notCalled;
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->called = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxies all method calls to the original event dispatcher.
|
||||
*
|
||||
|
|
|
@ -15,6 +15,8 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
|||
|
||||
/**
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @method reset() Resets the trace.
|
||||
*/
|
||||
interface TraceableEventDispatcherInterface extends EventDispatcherInterface
|
||||
{
|
||||
|
|
|
@ -124,6 +124,21 @@ class TraceableEventDispatcherTest extends TestCase
|
|||
$this->assertEquals(array(), $tdispatcher->getNotCalledListeners());
|
||||
}
|
||||
|
||||
public function testClearCalledListeners()
|
||||
{
|
||||
$tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
|
||||
$tdispatcher->addListener('foo', function () {}, 5);
|
||||
|
||||
$tdispatcher->dispatch('foo');
|
||||
$tdispatcher->reset();
|
||||
|
||||
$listeners = $tdispatcher->getNotCalledListeners();
|
||||
$this->assertArrayHasKey('stub', $listeners['foo.closure']);
|
||||
unset($listeners['foo.closure']['stub']);
|
||||
$this->assertEquals(array(), $tdispatcher->getCalledListeners());
|
||||
$this->assertEquals(array('foo.closure' => array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners);
|
||||
}
|
||||
|
||||
public function testGetCalledListenersNested()
|
||||
{
|
||||
$tdispatcher = null;
|
||||
|
|
|
@ -6,11 +6,15 @@ CHANGELOG
|
|||
|
||||
* removed `LockHandler`
|
||||
|
||||
3.4.0
|
||||
-----
|
||||
|
||||
* support for passing relative paths to `Filesystem::makePathRelative()` is deprecated and will be removed in 4.0
|
||||
|
||||
3.3.0
|
||||
-----
|
||||
|
||||
* added `appendToFile()` to append contents to existing files
|
||||
* support for passing relative paths to `Filesystem::makePathRelative()` is deprecated and will be removed in 4.0
|
||||
|
||||
3.2.0
|
||||
-----
|
||||
|
|
|
@ -74,11 +74,8 @@ class FormDataCollector extends DataCollector implements FormDataCollectorInterf
|
|||
}
|
||||
|
||||
$this->dataExtractor = $dataExtractor;
|
||||
$this->data = array(
|
||||
'forms' => array(),
|
||||
'forms_by_hash' => array(),
|
||||
'nb_errors' => 0,
|
||||
);
|
||||
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,6 +85,15 @@ class FormDataCollector extends DataCollector implements FormDataCollectorInterf
|
|||
{
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->data = array(
|
||||
'forms' => array(),
|
||||
'forms_by_hash' => array(),
|
||||
'nb_errors' => 0,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -695,6 +695,36 @@ class FormDataCollectorTest extends TestCase
|
|||
$this->assertFalse(isset($child21Data['has_children_error']), 'The leaf data does not contains "has_children_error" property.');
|
||||
}
|
||||
|
||||
public function testReset()
|
||||
{
|
||||
$form = $this->createForm('my_form');
|
||||
|
||||
$this->dataExtractor->expects($this->any())
|
||||
->method('extractConfiguration')
|
||||
->will($this->returnValue(array()));
|
||||
$this->dataExtractor->expects($this->any())
|
||||
->method('extractDefaultData')
|
||||
->will($this->returnValue(array()));
|
||||
$this->dataExtractor->expects($this->any())
|
||||
->method('extractSubmittedData')
|
||||
->with($form)
|
||||
->will($this->returnValue(array('errors' => array('baz'))));
|
||||
|
||||
$this->dataCollector->buildPreliminaryFormTree($form);
|
||||
$this->dataCollector->collectSubmittedData($form);
|
||||
|
||||
$this->dataCollector->reset();
|
||||
|
||||
$this->assertSame(
|
||||
array(
|
||||
'forms' => array(),
|
||||
'forms_by_hash' => array(),
|
||||
'nb_errors' => 0,
|
||||
),
|
||||
$this->dataCollector->getData()
|
||||
);
|
||||
}
|
||||
|
||||
private function createForm($name)
|
||||
{
|
||||
$builder = new FormBuilder($name, null, $this->dispatcher, $this->factory);
|
||||
|
|
|
@ -29,6 +29,7 @@ CHANGELOG
|
|||
* deprecated the `NativeSessionHandler` class,
|
||||
* deprecated the `AbstractProxy`, `NativeProxy` and `SessionHandlerProxy` classes,
|
||||
* deprecated setting session save handlers that do not implement `\SessionHandlerInterface` in `NativeSessionStorage::setSaveHandler()`
|
||||
* deprecated using `MongoDbSessionHandler` with the legacy mongo extension; use it with the mongodb/mongodb package and ext-mongodb instead
|
||||
|
||||
3.3.0
|
||||
-----
|
||||
|
|
|
@ -12,7 +12,12 @@
|
|||
namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
|
||||
|
||||
/**
|
||||
* Session handler using the mongodb/mongodb package and MongoDB driver extension.
|
||||
*
|
||||
* @author Markus Bachmann <markus.bachmann@bachi.biz>
|
||||
*
|
||||
* @see https://packagist.org/packages/mongodb/mongodb
|
||||
* @see http://php.net/manual/en/set.mongodb.php
|
||||
*/
|
||||
class MongoDbSessionHandler implements \SessionHandlerInterface
|
||||
{
|
||||
|
@ -57,14 +62,18 @@ class MongoDbSessionHandler implements \SessionHandlerInterface
|
|||
* If you use such an index, you can drop `gc_probability` to 0 since
|
||||
* no garbage-collection is required.
|
||||
*
|
||||
* @param \Mongo|\MongoClient|\MongoDB\Client $mongo A MongoDB\Client, MongoClient or Mongo instance
|
||||
* @param array $options An associative array of field options
|
||||
* @param \MongoDB\Client $mongo A MongoDB\Client instance
|
||||
* @param array $options An associative array of field options
|
||||
*
|
||||
* @throws \InvalidArgumentException When MongoClient or Mongo instance not provided
|
||||
* @throws \InvalidArgumentException When "database" or "collection" not provided
|
||||
*/
|
||||
public function __construct($mongo, array $options)
|
||||
{
|
||||
if ($mongo instanceof \MongoClient || $mongo instanceof \Mongo) {
|
||||
@trigger_error(sprintf('Using %s with the legacy mongo extension is deprecated as of 3.4 and will be removed in 4.0. Use it with the mongodb/mongodb package and ext-mongodb instead.', __CLASS__), E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
if (!($mongo instanceof \MongoDB\Client || $mongo instanceof \MongoClient || $mongo instanceof \Mongo)) {
|
||||
throw new \InvalidArgumentException('MongoClient or Mongo instance required');
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ use Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandl
|
|||
/**
|
||||
* @author Markus Bachmann <markus.bachmann@bachi.biz>
|
||||
* @group time-sensitive
|
||||
* @requires extension mongodb
|
||||
*/
|
||||
class MongoDbSessionHandlerTest extends TestCase
|
||||
{
|
||||
|
@ -31,21 +32,11 @@ class MongoDbSessionHandlerTest extends TestCase
|
|||
{
|
||||
parent::setUp();
|
||||
|
||||
if (extension_loaded('mongodb')) {
|
||||
if (!class_exists('MongoDB\Client')) {
|
||||
$this->markTestSkipped('The mongodb/mongodb package is required.');
|
||||
}
|
||||
} elseif (!extension_loaded('mongo')) {
|
||||
$this->markTestSkipped('The Mongo or MongoDB extension is required.');
|
||||
if (!class_exists('MongoDB\Client')) {
|
||||
$this->markTestSkipped('The mongodb/mongodb package is required.');
|
||||
}
|
||||
|
||||
if (phpversion('mongodb')) {
|
||||
$mongoClass = 'MongoDB\Client';
|
||||
} else {
|
||||
$mongoClass = version_compare(phpversion('mongo'), '1.3.0', '<') ? 'Mongo' : 'MongoClient';
|
||||
}
|
||||
|
||||
$this->mongo = $this->getMockBuilder($mongoClass)
|
||||
$this->mongo = $this->getMockBuilder('MongoDB\Client')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
|
@ -307,23 +298,12 @@ class MongoDbSessionHandlerTest extends TestCase
|
|||
$method = new \ReflectionMethod($this->storage, 'getMongo');
|
||||
$method->setAccessible(true);
|
||||
|
||||
if (phpversion('mongodb')) {
|
||||
$mongoClass = 'MongoDB\Client';
|
||||
} else {
|
||||
$mongoClass = version_compare(phpversion('mongo'), '1.3.0', '<') ? 'Mongo' : 'MongoClient';
|
||||
}
|
||||
|
||||
$this->assertInstanceOf($mongoClass, $method->invoke($this->storage));
|
||||
$this->assertInstanceOf('MongoDB\Client', $method->invoke($this->storage));
|
||||
}
|
||||
|
||||
private function createMongoCollectionMock()
|
||||
{
|
||||
$collectionClass = 'MongoCollection';
|
||||
if (phpversion('mongodb')) {
|
||||
$collectionClass = 'MongoDB\Collection';
|
||||
}
|
||||
|
||||
$collection = $this->getMockBuilder($collectionClass)
|
||||
$collection = $this->getMockBuilder('MongoDB\Collection')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
|
|
|
@ -38,7 +38,9 @@ CHANGELOG
|
|||
* deprecated the `ChainCacheClearer::add()` method
|
||||
* deprecated the `CacheaWarmerAggregate::add()` and `setWarmers()` methods
|
||||
* made `CacheWarmerAggregate` and `ChainCacheClearer` classes final
|
||||
|
||||
* added the possibility to reset the profiler to its initial state
|
||||
* deprecated data collectors without a `reset()` method
|
||||
* deprecated implementing `DebugLoggerInterface` without a `clear()` method
|
||||
|
||||
3.3.0
|
||||
-----
|
||||
|
|
|
@ -26,6 +26,11 @@ class AjaxDataCollector extends DataCollector
|
|||
// all collecting is done client side
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
// all collecting is done client side
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'ajax';
|
||||
|
|
|
@ -95,6 +95,14 @@ class ConfigDataCollector extends DataCollector implements LateDataCollectorInte
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->data = array();
|
||||
}
|
||||
|
||||
public function lateCollect()
|
||||
{
|
||||
$this->data = $this->cloneVar($this->data);
|
||||
|
|
|
@ -18,6 +18,8 @@ use Symfony\Component\HttpFoundation\Response;
|
|||
* DataCollectorInterface.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @method reset() Resets this data collector to its initial state.
|
||||
*/
|
||||
interface DataCollectorInterface
|
||||
{
|
||||
|
|
|
@ -27,6 +27,9 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter
|
|||
|
||||
public function __construct(EventDispatcherInterface $dispatcher = null)
|
||||
{
|
||||
if ($dispatcher instanceof TraceableEventDispatcherInterface && !method_exists($dispatcher, 'reset')) {
|
||||
@trigger_error(sprintf('Implementing "%s" without the "reset()" method is deprecated since version 3.4 and will be unsupported in 4.0 for class "%s".', TraceableEventDispatcherInterface::class, \get_class($dispatcher)), E_USER_DEPRECATED);
|
||||
}
|
||||
$this->dispatcher = $dispatcher;
|
||||
}
|
||||
|
||||
|
@ -41,6 +44,19 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter
|
|||
);
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->data = array();
|
||||
|
||||
if ($this->dispatcher instanceof TraceableEventDispatcherInterface) {
|
||||
if (!method_exists($this->dispatcher, 'reset')) {
|
||||
return; // @deprecated
|
||||
}
|
||||
|
||||
$this->dispatcher->reset();
|
||||
}
|
||||
}
|
||||
|
||||
public function lateCollect()
|
||||
{
|
||||
if ($this->dispatcher instanceof TraceableEventDispatcherInterface) {
|
||||
|
|
|
@ -34,6 +34,14 @@ class ExceptionDataCollector extends DataCollector
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->data = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the exception is not null.
|
||||
*
|
||||
|
|
|
@ -29,6 +29,10 @@ class LoggerDataCollector extends DataCollector implements LateDataCollectorInte
|
|||
public function __construct($logger = null, $containerPathPrefix = null)
|
||||
{
|
||||
if (null !== $logger && $logger instanceof DebugLoggerInterface) {
|
||||
if (!method_exists($logger, 'clear')) {
|
||||
@trigger_error(sprintf('Implementing "%s" without the "clear()" method is deprecated since version 3.4 and will be unsupported in 4.0 for class "%s".', DebugLoggerInterface::class, \get_class($logger)), E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
|
@ -43,6 +47,17 @@ class LoggerDataCollector extends DataCollector implements LateDataCollectorInte
|
|||
// everything is done as late as possible
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
if ($this->logger && method_exists($this->logger, 'clear')) {
|
||||
$this->logger->clear();
|
||||
}
|
||||
$this->data = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -23,10 +23,7 @@ class MemoryDataCollector extends DataCollector implements LateDataCollectorInte
|
|||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->data = array(
|
||||
'memory' => 0,
|
||||
'memory_limit' => $this->convertToBytes(ini_get('memory_limit')),
|
||||
);
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -37,6 +34,17 @@ class MemoryDataCollector extends DataCollector implements LateDataCollectorInte
|
|||
$this->updateMemoryUsage();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->data = array(
|
||||
'memory' => 0,
|
||||
'memory_limit' => $this->convertToBytes(ini_get('memory_limit')),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -156,6 +156,12 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter
|
|||
$this->data = $this->cloneVar($this->data);
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->data = array();
|
||||
$this->controllers = new \SplObjectStorage();
|
||||
}
|
||||
|
||||
public function getMethod()
|
||||
{
|
||||
return $this->data['method'];
|
||||
|
|
|
@ -23,17 +23,14 @@ use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
|
|||
*/
|
||||
class RouterDataCollector extends DataCollector
|
||||
{
|
||||
/**
|
||||
* @var \SplObjectStorage
|
||||
*/
|
||||
protected $controllers;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->controllers = new \SplObjectStorage();
|
||||
|
||||
$this->data = array(
|
||||
'redirect' => false,
|
||||
'url' => null,
|
||||
'route' => null,
|
||||
);
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -53,6 +50,17 @@ class RouterDataCollector extends DataCollector
|
|||
unset($this->controllers[$request]);
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->controllers = new \SplObjectStorage();
|
||||
|
||||
$this->data = array(
|
||||
'redirect' => false,
|
||||
'url' => null,
|
||||
'route' => null,
|
||||
);
|
||||
}
|
||||
|
||||
protected function guessRoute(Request $request, $controller)
|
||||
{
|
||||
return 'n/a';
|
||||
|
|
|
@ -49,6 +49,14 @@ class TimeDataCollector extends DataCollector implements LateDataCollectorInterf
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->data = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -15,6 +15,8 @@ namespace Symfony\Component\HttpKernel\Log;
|
|||
* DebugLoggerInterface.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @method clear() Removes all log records.
|
||||
*/
|
||||
interface DebugLoggerInterface
|
||||
{
|
||||
|
|
|
@ -40,6 +40,11 @@ class Profiler
|
|||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $initiallyEnabled = true;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
|
@ -48,11 +53,13 @@ class Profiler
|
|||
/**
|
||||
* @param ProfilerStorageInterface $storage A ProfilerStorageInterface instance
|
||||
* @param LoggerInterface $logger A LoggerInterface instance
|
||||
* @param bool $enable The initial enabled state
|
||||
*/
|
||||
public function __construct(ProfilerStorageInterface $storage, LoggerInterface $logger = null)
|
||||
public function __construct(ProfilerStorageInterface $storage, LoggerInterface $logger = null, $enable = true)
|
||||
{
|
||||
$this->storage = $storage;
|
||||
$this->logger = $logger;
|
||||
$this->initiallyEnabled = $this->enabled = (bool) $enable;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -188,6 +195,18 @@ class Profiler
|
|||
return $profile;
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
foreach ($this->collectors as $collector) {
|
||||
if (!method_exists($collector, 'reset')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$collector->reset();
|
||||
}
|
||||
$this->enabled = $this->initiallyEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Collectors associated with this profiler.
|
||||
*
|
||||
|
@ -218,6 +237,10 @@ class Profiler
|
|||
*/
|
||||
public function add(DataCollectorInterface $collector)
|
||||
{
|
||||
if (!method_exists($collector, 'reset')) {
|
||||
@trigger_error(sprintf('Implementing "%s" without the "reset()" method is deprecated since version 3.4 and will be unsupported in 4.0 for class "%s".', DataCollectorInterface::class, \get_class($collector)), E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$this->collectors[$collector->getName()] = $collector;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,4 +37,23 @@ class ExceptionDataCollectorTest extends TestCase
|
|||
$this->assertSame('exception', $c->getName());
|
||||
$this->assertSame($trace, $c->getTrace());
|
||||
}
|
||||
|
||||
public function testCollectWithoutException()
|
||||
{
|
||||
$c = new ExceptionDataCollector();
|
||||
$c->collect(new Request(), new Response());
|
||||
|
||||
$this->assertFalse($c->hasException());
|
||||
}
|
||||
|
||||
public function testReset()
|
||||
{
|
||||
$c = new ExceptionDataCollector();
|
||||
|
||||
$c->collect(new Request(), new Response(), new \Exception());
|
||||
$c->reset();
|
||||
$c->collect(new Request(), new Response());
|
||||
|
||||
$this->assertFalse($c->hasException());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,10 @@ class LoggerDataCollectorTest extends TestCase
|
|||
{
|
||||
public function testCollectWithUnexpectedFormat()
|
||||
{
|
||||
$logger = $this->getMockBuilder('Symfony\Component\HttpKernel\Log\DebugLoggerInterface')->getMock();
|
||||
$logger = $this
|
||||
->getMockBuilder('Symfony\Component\HttpKernel\Log\DebugLoggerInterface')
|
||||
->setMethods(array('countErrors', 'getLogs', 'clear'))
|
||||
->getMock();
|
||||
$logger->expects($this->once())->method('countErrors')->will($this->returnValue('foo'));
|
||||
$logger->expects($this->exactly(2))->method('getLogs')->will($this->returnValue(array()));
|
||||
|
||||
|
@ -43,7 +46,10 @@ class LoggerDataCollectorTest extends TestCase
|
|||
*/
|
||||
public function testCollect($nb, $logs, $expectedLogs, $expectedDeprecationCount, $expectedScreamCount, $expectedPriorities = null)
|
||||
{
|
||||
$logger = $this->getMockBuilder('Symfony\Component\HttpKernel\Log\DebugLoggerInterface')->getMock();
|
||||
$logger = $this
|
||||
->getMockBuilder('Symfony\Component\HttpKernel\Log\DebugLoggerInterface')
|
||||
->setMethods(array('countErrors', 'getLogs', 'clear'))
|
||||
->getMock();
|
||||
$logger->expects($this->once())->method('countErrors')->will($this->returnValue($nb));
|
||||
$logger->expects($this->exactly(2))->method('getLogs')->will($this->returnValue($logs));
|
||||
|
||||
|
@ -70,6 +76,18 @@ class LoggerDataCollectorTest extends TestCase
|
|||
}
|
||||
}
|
||||
|
||||
public function testReset()
|
||||
{
|
||||
$logger = $this
|
||||
->getMockBuilder('Symfony\Component\HttpKernel\Log\DebugLoggerInterface')
|
||||
->setMethods(array('countErrors', 'getLogs', 'clear'))
|
||||
->getMock();
|
||||
$logger->expects($this->once())->method('clear');
|
||||
|
||||
$c = new LoggerDataCollector($logger);
|
||||
$c->reset();
|
||||
}
|
||||
|
||||
public function getCollectTestData()
|
||||
{
|
||||
yield 'simple log' => array(
|
||||
|
|
|
@ -29,6 +29,11 @@ class CloneVarDataCollector extends DataCollector
|
|||
$this->data = $this->cloneVar($this->varToClone);
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->data = array();
|
||||
}
|
||||
|
||||
public function getData()
|
||||
{
|
||||
return $this->data;
|
||||
|
|
|
@ -25,4 +25,8 @@ class TestEventDispatcher extends EventDispatcher implements TraceableEventDispa
|
|||
{
|
||||
return array('bar');
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
namespace Symfony\Component\HttpKernel\Tests\Profiler;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface;
|
||||
use Symfony\Component\HttpKernel\DataCollector\RequestDataCollector;
|
||||
use Symfony\Component\HttpKernel\Profiler\FileProfilerStorage;
|
||||
use Symfony\Component\HttpKernel\Profiler\Profiler;
|
||||
|
@ -40,6 +41,19 @@ class ProfilerTest extends TestCase
|
|||
$this->assertSame('bar', $profile->getCollector('request')->getRequestQuery()->all()['foo']->getValue());
|
||||
}
|
||||
|
||||
public function testReset()
|
||||
{
|
||||
$collector = $this->getMockBuilder(DataCollectorInterface::class)
|
||||
->setMethods(['collect', 'getName', 'reset'])
|
||||
->getMock();
|
||||
$collector->expects($this->any())->method('getName')->willReturn('mock');
|
||||
$collector->expects($this->once())->method('reset');
|
||||
|
||||
$profiler = new Profiler($this->storage);
|
||||
$profiler->add($collector);
|
||||
$profiler->reset();
|
||||
}
|
||||
|
||||
public function testFindWorksWithDates()
|
||||
{
|
||||
$profiler = new Profiler($this->storage);
|
||||
|
|
|
@ -26,6 +26,7 @@ CHANGELOG
|
|||
requests.
|
||||
* deprecated HTTP digest authentication
|
||||
* Added a new password encoder for the Argon2i hashing algorithm
|
||||
* deprecated `GuardAuthenticatorInterface` in favor of `AuthenticatorInterface`
|
||||
|
||||
3.3.0
|
||||
-----
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
namespace Symfony\Component\Security\Guard;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken;
|
||||
|
||||
|
@ -19,8 +20,20 @@ use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken;
|
|||
*
|
||||
* @author Ryan Weaver <ryan@knpuniversity.com>
|
||||
*/
|
||||
abstract class AbstractGuardAuthenticator implements GuardAuthenticatorInterface
|
||||
abstract class AbstractGuardAuthenticator implements AuthenticatorInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated since version 3.4, to be removed in 4.0
|
||||
*/
|
||||
public function supports(Request $request)
|
||||
{
|
||||
@trigger_error(sprintf('The "%s()" method is deprecated since version 3.4 and will be removed in 4.0. Implement the "%s::supports()" method in class "%s" instead.', __METHOD__, AuthenticatorInterface::class, get_class($this)), E_USER_DEPRECATED);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut to create a PostAuthenticationGuardToken for you, if you don't really
|
||||
* care about which authenticated token you're using.
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
<?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\Security\Guard;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* The interface for all "guard" authenticators.
|
||||
*
|
||||
* The methods on this interface are called throughout the guard authentication
|
||||
* process to give you the power to control most parts of the process from
|
||||
* one location.
|
||||
*
|
||||
* @author Ryan Weaver <ryan@knpuniversity.com>
|
||||
* @author Amaury Leroux de Lens <amaury@lerouxdelens.com>
|
||||
*/
|
||||
interface AuthenticatorInterface extends GuardAuthenticatorInterface
|
||||
{
|
||||
/**
|
||||
* Does the authenticator support the given Request?
|
||||
*
|
||||
* If this returns false, the authenticator will be skipped.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function supports(Request $request);
|
||||
|
||||
/**
|
||||
* Get the authentication credentials from the request and return them
|
||||
* as any type (e.g. an associate array).
|
||||
*
|
||||
* Whatever value you return here will be passed to getUser() and checkCredentials()
|
||||
*
|
||||
* For example, for a form login, you might:
|
||||
*
|
||||
* return array(
|
||||
* 'username' => $request->request->get('_username'),
|
||||
* 'password' => $request->request->get('_password'),
|
||||
* );
|
||||
*
|
||||
* Or for an API token that's on a header, you might use:
|
||||
*
|
||||
* return array('api_key' => $request->headers->get('X-API-TOKEN'));
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return mixed Any non-null value
|
||||
*
|
||||
* @throws \UnexpectedValueException If null is returned
|
||||
*/
|
||||
public function getCredentials(Request $request);
|
||||
}
|
|
@ -15,9 +15,10 @@ use Symfony\Component\HttpFoundation\Request;
|
|||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
|
||||
use Symfony\Component\Security\Guard\GuardAuthenticatorInterface;
|
||||
use Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken;
|
||||
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
|
||||
use Symfony\Component\Security\Guard\GuardAuthenticatorInterface;
|
||||
use Symfony\Component\Security\Guard\AuthenticatorInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||
|
@ -28,6 +29,7 @@ use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
|
|||
* Authentication listener for the "guard" system.
|
||||
*
|
||||
* @author Ryan Weaver <ryan@knpuniversity.com>
|
||||
* @author Amaury Leroux de Lens <amaury@lerouxdelens.com>
|
||||
*/
|
||||
class GuardAuthenticationListener implements ListenerInterface
|
||||
{
|
||||
|
@ -39,11 +41,11 @@ class GuardAuthenticationListener implements ListenerInterface
|
|||
private $rememberMeServices;
|
||||
|
||||
/**
|
||||
* @param GuardAuthenticatorHandler $guardHandler The Guard handler
|
||||
* @param AuthenticationManagerInterface $authenticationManager An AuthenticationManagerInterface instance
|
||||
* @param string $providerKey The provider (i.e. firewall) key
|
||||
* @param iterable|GuardAuthenticatorInterface[] $guardAuthenticators The authenticators, with keys that match what's passed to GuardAuthenticationProvider
|
||||
* @param LoggerInterface $logger A LoggerInterface instance
|
||||
* @param GuardAuthenticatorHandler $guardHandler The Guard handler
|
||||
* @param AuthenticationManagerInterface $authenticationManager An AuthenticationManagerInterface instance
|
||||
* @param string $providerKey The provider (i.e. firewall) key
|
||||
* @param iterable|AuthenticatorInterface[] $guardAuthenticators The authenticators, with keys that match what's passed to GuardAuthenticationProvider
|
||||
* @param LoggerInterface $logger A LoggerInterface instance
|
||||
*/
|
||||
public function __construct(GuardAuthenticatorHandler $guardHandler, AuthenticationManagerInterface $authenticationManager, $providerKey, $guardAuthenticators, LoggerInterface $logger = null)
|
||||
{
|
||||
|
@ -100,12 +102,29 @@ class GuardAuthenticationListener implements ListenerInterface
|
|||
$this->logger->debug('Calling getCredentials() on guard configurator.', array('firewall_key' => $this->providerKey, 'authenticator' => get_class($guardAuthenticator)));
|
||||
}
|
||||
|
||||
// abort the execution of the authenticator if it doesn't support the request
|
||||
if ($guardAuthenticator instanceof AuthenticatorInterface) {
|
||||
if (!$guardAuthenticator->supports($request)) {
|
||||
return;
|
||||
}
|
||||
// as there was a support for given request,
|
||||
// authenticator is expected to give not-null credentials.
|
||||
$credentialsCanBeNull = false;
|
||||
} else {
|
||||
// deprecated since version 3.4, to be removed in 4.0
|
||||
$credentialsCanBeNull = true;
|
||||
}
|
||||
|
||||
// allow the authenticator to fetch authentication info from the request
|
||||
$credentials = $guardAuthenticator->getCredentials($request);
|
||||
|
||||
// allow null to be returned to skip authentication
|
||||
if (null === $credentials) {
|
||||
return;
|
||||
// deprecated since version 3.4, to be removed in 4.0
|
||||
if ($credentialsCanBeNull) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new \UnexpectedValueException(sprintf('The return value of "%s::getCredentials()" must not be null. Return false from "%s::supports()" instead.', get_class($guardAuthenticator), get_class($guardAuthenticator)));
|
||||
}
|
||||
|
||||
// create a token with the unique key, so that the provider knows which authenticator to use
|
||||
|
@ -172,10 +191,10 @@ class GuardAuthenticationListener implements ListenerInterface
|
|||
* Checks to see if remember me is supported in the authenticator and
|
||||
* on the firewall. If it is, the RememberMeServicesInterface is notified.
|
||||
*
|
||||
* @param GuardAuthenticatorInterface $guardAuthenticator
|
||||
* @param Request $request
|
||||
* @param TokenInterface $token
|
||||
* @param Response $response
|
||||
* @param AuthenticatorInterface $guardAuthenticator
|
||||
* @param Request $request
|
||||
* @param TokenInterface $token
|
||||
* @param Response $response
|
||||
*/
|
||||
private function triggerRememberMe(GuardAuthenticatorInterface $guardAuthenticator, Request $request, TokenInterface $token, Response $response = null)
|
||||
{
|
||||
|
|
|
@ -29,6 +29,8 @@ use Symfony\Component\Security\Http\SecurityEvents;
|
|||
* can be called directly (e.g. for manual authentication) or overridden.
|
||||
*
|
||||
* @author Ryan Weaver <ryan@knpuniversity.com>
|
||||
*
|
||||
* @final since version 3.4
|
||||
*/
|
||||
class GuardAuthenticatorHandler
|
||||
{
|
||||
|
@ -61,10 +63,10 @@ class GuardAuthenticatorHandler
|
|||
/**
|
||||
* Returns the "on success" response for the given GuardAuthenticator.
|
||||
*
|
||||
* @param TokenInterface $token
|
||||
* @param Request $request
|
||||
* @param GuardAuthenticatorInterface $guardAuthenticator
|
||||
* @param string $providerKey The provider (i.e. firewall) key
|
||||
* @param TokenInterface $token
|
||||
* @param Request $request
|
||||
* @param AuthenticatorInterface $guardAuthenticator
|
||||
* @param string $providerKey The provider (i.e. firewall) key
|
||||
*
|
||||
* @return null|Response
|
||||
*/
|
||||
|
@ -88,10 +90,10 @@ class GuardAuthenticatorHandler
|
|||
* Convenience method for authenticating the user and returning the
|
||||
* Response *if any* for success.
|
||||
*
|
||||
* @param UserInterface $user
|
||||
* @param Request $request
|
||||
* @param GuardAuthenticatorInterface $authenticator
|
||||
* @param string $providerKey The provider (i.e. firewall) key
|
||||
* @param UserInterface $user
|
||||
* @param Request $request
|
||||
* @param AuthenticatorInterface $authenticator
|
||||
* @param string $providerKey The provider (i.e. firewall) key
|
||||
*
|
||||
* @return Response|null
|
||||
*/
|
||||
|
@ -110,10 +112,10 @@ class GuardAuthenticatorHandler
|
|||
* Handles an authentication failure and returns the Response for the
|
||||
* GuardAuthenticator.
|
||||
*
|
||||
* @param AuthenticationException $authenticationException
|
||||
* @param Request $request
|
||||
* @param GuardAuthenticatorInterface $guardAuthenticator
|
||||
* @param string $providerKey The key of the firewall
|
||||
* @param AuthenticationException $authenticationException
|
||||
* @param Request $request
|
||||
* @param AuthenticatorInterface $guardAuthenticator
|
||||
* @param string $providerKey The key of the firewall
|
||||
*
|
||||
* @return null|Response
|
||||
*/
|
||||
|
|
|
@ -28,6 +28,8 @@ use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface
|
|||
* one location.
|
||||
*
|
||||
* @author Ryan Weaver <ryan@knpuniversity.com>
|
||||
*
|
||||
* @deprecated since version 3.4, to be removed in 4.0. Use AuthenticatorInterface instead
|
||||
*/
|
||||
interface GuardAuthenticatorInterface extends AuthenticationEntryPointInterface
|
||||
{
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace Symfony\Component\Security\Guard\Provider;
|
|||
use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
|
||||
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
|
||||
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
|
||||
use Symfony\Component\Security\Guard\GuardAuthenticatorInterface;
|
||||
use Symfony\Component\Security\Guard\AuthenticatorInterface;
|
||||
use Symfony\Component\Security\Guard\Token\GuardTokenInterface;
|
||||
use Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken;
|
||||
use Symfony\Component\Security\Core\User\UserCheckerInterface;
|
||||
|
@ -32,7 +32,7 @@ use Symfony\Component\Security\Core\Exception\AuthenticationExpiredException;
|
|||
class GuardAuthenticationProvider implements AuthenticationProviderInterface
|
||||
{
|
||||
/**
|
||||
* @var GuardAuthenticatorInterface[]
|
||||
* @var AuthenticatorInterface[]
|
||||
*/
|
||||
private $guardAuthenticators;
|
||||
private $userProvider;
|
||||
|
@ -40,10 +40,10 @@ class GuardAuthenticationProvider implements AuthenticationProviderInterface
|
|||
private $userChecker;
|
||||
|
||||
/**
|
||||
* @param iterable|GuardAuthenticatorInterface[] $guardAuthenticators The authenticators, with keys that match what's passed to GuardAuthenticationListener
|
||||
* @param UserProviderInterface $userProvider The user provider
|
||||
* @param string $providerKey The provider (i.e. firewall) key
|
||||
* @param UserCheckerInterface $userChecker
|
||||
* @param iterable|AuthenticatorInterface[] $guardAuthenticators The authenticators, with keys that match what's passed to GuardAuthenticationListener
|
||||
* @param UserProviderInterface $userProvider The user provider
|
||||
* @param string $providerKey The provider (i.e. firewall) key
|
||||
* @param UserCheckerInterface $userChecker
|
||||
*/
|
||||
public function __construct($guardAuthenticators, UserProviderInterface $userProvider, $providerKey, UserCheckerInterface $userChecker)
|
||||
{
|
||||
|
@ -101,7 +101,7 @@ class GuardAuthenticationProvider implements AuthenticationProviderInterface
|
|||
// instances that will be checked if you have multiple firewalls.
|
||||
}
|
||||
|
||||
private function authenticateViaGuard(GuardAuthenticatorInterface $guardAuthenticator, PreAuthenticationGuardToken $token)
|
||||
private function authenticateViaGuard($guardAuthenticator, PreAuthenticationGuardToken $token)
|
||||
{
|
||||
// get the user from the GuardAuthenticator
|
||||
$user = $guardAuthenticator->getUser($token->getCredentials(), $this->userProvider);
|
||||
|
|
|
@ -14,12 +14,16 @@ namespace Symfony\Component\Security\Guard\Tests\Firewall;
|
|||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Guard\AuthenticatorInterface;
|
||||
use Symfony\Component\Security\Guard\Firewall\GuardAuthenticationListener;
|
||||
use Symfony\Component\Security\Guard\GuardAuthenticatorInterface;
|
||||
use Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken;
|
||||
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||
|
||||
/**
|
||||
* @author Ryan Weaver <weaverryan@gmail.com>
|
||||
* @author Amaury Leroux de Lens <amaury@lerouxdelens.com>
|
||||
*/
|
||||
class GuardAuthenticationListenerTest extends TestCase
|
||||
{
|
||||
|
@ -32,11 +36,16 @@ class GuardAuthenticationListenerTest extends TestCase
|
|||
|
||||
public function testHandleSuccess()
|
||||
{
|
||||
$authenticator = $this->getMockBuilder('Symfony\Component\Security\Guard\GuardAuthenticatorInterface')->getMock();
|
||||
$authenticateToken = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
|
||||
$authenticator = $this->getMockBuilder(AuthenticatorInterface::class)->getMock();
|
||||
$authenticateToken = $this->getMockBuilder(TokenInterface::class)->getMock();
|
||||
$providerKey = 'my_firewall';
|
||||
|
||||
$credentials = array('username' => 'weaverryan', 'password' => 'all_your_base');
|
||||
|
||||
$authenticator
|
||||
->expects($this->once())
|
||||
->method('supports')
|
||||
->willReturn(true);
|
||||
$authenticator
|
||||
->expects($this->once())
|
||||
->method('getCredentials')
|
||||
|
@ -82,10 +91,14 @@ class GuardAuthenticationListenerTest extends TestCase
|
|||
|
||||
public function testHandleSuccessStopsAfterResponseIsSet()
|
||||
{
|
||||
$authenticator1 = $this->getMockBuilder('Symfony\Component\Security\Guard\GuardAuthenticatorInterface')->getMock();
|
||||
$authenticator2 = $this->getMockBuilder('Symfony\Component\Security\Guard\GuardAuthenticatorInterface')->getMock();
|
||||
$authenticator1 = $this->getMockBuilder(AuthenticatorInterface::class)->getMock();
|
||||
$authenticator2 = $this->getMockBuilder(AuthenticatorInterface::class)->getMock();
|
||||
|
||||
// mock the first authenticator to fail, and set a Response
|
||||
$authenticator1
|
||||
->expects($this->once())
|
||||
->method('supports')
|
||||
->willReturn(true);
|
||||
$authenticator1
|
||||
->expects($this->once())
|
||||
->method('getCredentials')
|
||||
|
@ -112,10 +125,15 @@ class GuardAuthenticationListenerTest extends TestCase
|
|||
|
||||
public function testHandleSuccessWithRememberMe()
|
||||
{
|
||||
$authenticator = $this->getMockBuilder('Symfony\Component\Security\Guard\GuardAuthenticatorInterface')->getMock();
|
||||
$authenticateToken = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
|
||||
$authenticator = $this->getMockBuilder(AuthenticatorInterface::class)->getMock();
|
||||
$authenticateToken = $this->getMockBuilder(TokenInterface::class)->getMock();
|
||||
$providerKey = 'my_firewall_with_rememberme';
|
||||
|
||||
$authenticator
|
||||
->expects($this->once())
|
||||
->method('supports')
|
||||
->with($this->equalTo($this->request))
|
||||
->willReturn(true);
|
||||
$authenticator
|
||||
->expects($this->once())
|
||||
->method('getCredentials')
|
||||
|
@ -155,10 +173,14 @@ class GuardAuthenticationListenerTest extends TestCase
|
|||
|
||||
public function testHandleCatchesAuthenticationException()
|
||||
{
|
||||
$authenticator = $this->getMockBuilder('Symfony\Component\Security\Guard\GuardAuthenticatorInterface')->getMock();
|
||||
$authenticator = $this->getMockBuilder(AuthenticatorInterface::class)->getMock();
|
||||
$providerKey = 'my_firewall2';
|
||||
|
||||
$authException = new AuthenticationException('Get outta here crazy user with a bad password!');
|
||||
$authenticator
|
||||
->expects($this->once())
|
||||
->method('supports')
|
||||
->willReturn(true);
|
||||
$authenticator
|
||||
->expects($this->once())
|
||||
->method('getCredentials')
|
||||
|
@ -185,6 +207,96 @@ class GuardAuthenticationListenerTest extends TestCase
|
|||
$listener->handle($this->event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testLegacyInterfaceNullCredentials()
|
||||
{
|
||||
$authenticatorA = $this->getMockBuilder(GuardAuthenticatorInterface::class)->getMock();
|
||||
$providerKey = 'my_firewall3';
|
||||
|
||||
$authenticatorA
|
||||
->expects($this->once())
|
||||
->method('getCredentials')
|
||||
->will($this->returnValue(null));
|
||||
|
||||
// this is not called
|
||||
$this->authenticationManager
|
||||
->expects($this->never())
|
||||
->method('authenticate');
|
||||
|
||||
$this->guardAuthenticatorHandler
|
||||
->expects($this->never())
|
||||
->method('handleAuthenticationSuccess');
|
||||
|
||||
$listener = new GuardAuthenticationListener(
|
||||
$this->guardAuthenticatorHandler,
|
||||
$this->authenticationManager,
|
||||
$providerKey,
|
||||
array($authenticatorA),
|
||||
$this->logger
|
||||
);
|
||||
|
||||
$listener->handle($this->event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testLegacyInterfaceKeepsWorking()
|
||||
{
|
||||
$authenticator = $this->getMockBuilder(GuardAuthenticatorInterface::class)->getMock();
|
||||
$authenticateToken = $this->getMockBuilder(TokenInterface::class)->getMock();
|
||||
$providerKey = 'my_firewall';
|
||||
|
||||
$credentials = array('username' => 'weaverryan', 'password' => 'all_your_base');
|
||||
|
||||
$authenticator
|
||||
->expects($this->once())
|
||||
->method('getCredentials')
|
||||
->with($this->equalTo($this->request))
|
||||
->will($this->returnValue($credentials));
|
||||
|
||||
// a clone of the token that should be created internally
|
||||
$uniqueGuardKey = 'my_firewall_0';
|
||||
$nonAuthedToken = new PreAuthenticationGuardToken($credentials, $uniqueGuardKey);
|
||||
|
||||
$this->authenticationManager
|
||||
->expects($this->once())
|
||||
->method('authenticate')
|
||||
->with($this->equalTo($nonAuthedToken))
|
||||
->will($this->returnValue($authenticateToken));
|
||||
|
||||
$this->guardAuthenticatorHandler
|
||||
->expects($this->once())
|
||||
->method('authenticateWithToken')
|
||||
->with($authenticateToken, $this->request);
|
||||
|
||||
$this->guardAuthenticatorHandler
|
||||
->expects($this->once())
|
||||
->method('handleAuthenticationSuccess')
|
||||
->with($authenticateToken, $this->request, $authenticator, $providerKey);
|
||||
|
||||
$listener = new GuardAuthenticationListener(
|
||||
$this->guardAuthenticatorHandler,
|
||||
$this->authenticationManager,
|
||||
$providerKey,
|
||||
array($authenticator),
|
||||
$this->logger
|
||||
);
|
||||
|
||||
$listener->setRememberMeServices($this->rememberMeServices);
|
||||
// should never be called - our handleAuthenticationSuccess() does not return a Response
|
||||
$this->rememberMeServices
|
||||
->expects($this->never())
|
||||
->method('loginSuccess');
|
||||
|
||||
$listener->handle($this->event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testReturnNullToSkipAuth()
|
||||
{
|
||||
$authenticatorA = $this->getMockBuilder('Symfony\Component\Security\Guard\GuardAuthenticatorInterface')->getMock();
|
||||
|
@ -220,6 +332,62 @@ class GuardAuthenticationListenerTest extends TestCase
|
|||
$listener->handle($this->event);
|
||||
}
|
||||
|
||||
public function testSupportsReturnFalseSkipAuth()
|
||||
{
|
||||
$authenticator = $this->getMockBuilder(AuthenticatorInterface::class)->getMock();
|
||||
$providerKey = 'my_firewall4';
|
||||
|
||||
$authenticator
|
||||
->expects($this->once())
|
||||
->method('supports')
|
||||
->will($this->returnValue(false));
|
||||
|
||||
// this is not called
|
||||
$authenticator
|
||||
->expects($this->never())
|
||||
->method('getCredentials');
|
||||
|
||||
$listener = new GuardAuthenticationListener(
|
||||
$this->guardAuthenticatorHandler,
|
||||
$this->authenticationManager,
|
||||
$providerKey,
|
||||
array($authenticator),
|
||||
$this->logger
|
||||
);
|
||||
|
||||
$listener->handle($this->event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \UnexpectedValueException
|
||||
*/
|
||||
public function testReturnNullFromGetCredentials()
|
||||
{
|
||||
$authenticator = $this->getMockBuilder(AuthenticatorInterface::class)->getMock();
|
||||
$providerKey = 'my_firewall4';
|
||||
|
||||
$authenticator
|
||||
->expects($this->once())
|
||||
->method('supports')
|
||||
->will($this->returnValue(true));
|
||||
|
||||
// this will raise exception
|
||||
$authenticator
|
||||
->expects($this->once())
|
||||
->method('getCredentials')
|
||||
->will($this->returnValue(null));
|
||||
|
||||
$listener = new GuardAuthenticationListener(
|
||||
$this->guardAuthenticatorHandler,
|
||||
$this->authenticationManager,
|
||||
$providerKey,
|
||||
array($authenticator),
|
||||
$this->logger
|
||||
);
|
||||
|
||||
$listener->handle($this->event);
|
||||
}
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager')
|
||||
|
|
|
@ -14,6 +14,7 @@ namespace Symfony\Component\Security\Guard\Tests;
|
|||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Security\Guard\AuthenticatorInterface;
|
||||
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
|
||||
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
|
||||
|
@ -128,7 +129,7 @@ class GuardAuthenticatorHandlerTest extends TestCase
|
|||
$this->dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
|
||||
$this->token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
|
||||
$this->request = new Request(array(), array(), array(), array(), array(), array());
|
||||
$this->guardAuthenticator = $this->getMockBuilder('Symfony\Component\Security\Guard\GuardAuthenticatorInterface')->getMock();
|
||||
$this->guardAuthenticator = $this->getMockBuilder(AuthenticatorInterface::class)->getMock();
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
namespace Symfony\Component\Security\Guard\Tests\Provider;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
use Symfony\Component\Security\Guard\AuthenticatorInterface;
|
||||
use Symfony\Component\Security\Guard\Provider\GuardAuthenticationProvider;
|
||||
use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken;
|
||||
|
||||
|
@ -28,6 +31,68 @@ class GuardAuthenticationProviderTest extends TestCase
|
|||
{
|
||||
$providerKey = 'my_cool_firewall';
|
||||
|
||||
$authenticatorA = $this->getMockBuilder(AuthenticatorInterface::class)->getMock();
|
||||
$authenticatorB = $this->getMockBuilder(AuthenticatorInterface::class)->getMock();
|
||||
$authenticatorC = $this->getMockBuilder(AuthenticatorInterface::class)->getMock();
|
||||
$authenticators = array($authenticatorA, $authenticatorB, $authenticatorC);
|
||||
|
||||
// called 2 times - for authenticator A and B (stops on B because of match)
|
||||
$this->preAuthenticationToken->expects($this->exactly(2))
|
||||
->method('getGuardProviderKey')
|
||||
// it will return the "1" index, which will match authenticatorB
|
||||
->will($this->returnValue('my_cool_firewall_1'));
|
||||
|
||||
$enteredCredentials = array(
|
||||
'username' => '_weaverryan_test_user',
|
||||
'password' => 'guard_auth_ftw',
|
||||
);
|
||||
$this->preAuthenticationToken->expects($this->atLeastOnce())
|
||||
->method('getCredentials')
|
||||
->will($this->returnValue($enteredCredentials));
|
||||
|
||||
// authenticators A and C are never called
|
||||
$authenticatorA->expects($this->never())
|
||||
->method('getUser');
|
||||
$authenticatorC->expects($this->never())
|
||||
->method('getUser');
|
||||
|
||||
$mockedUser = $this->getMockBuilder(UserInterface::class)->getMock();
|
||||
$authenticatorB->expects($this->once())
|
||||
->method('getUser')
|
||||
->with($enteredCredentials, $this->userProvider)
|
||||
->will($this->returnValue($mockedUser));
|
||||
// checkCredentials is called
|
||||
$authenticatorB->expects($this->once())
|
||||
->method('checkCredentials')
|
||||
->with($enteredCredentials, $mockedUser)
|
||||
// authentication works!
|
||||
->will($this->returnValue(true));
|
||||
$authedToken = $this->getMockBuilder(TokenInterface::class)->getMock();
|
||||
$authenticatorB->expects($this->once())
|
||||
->method('createAuthenticatedToken')
|
||||
->with($mockedUser, $providerKey)
|
||||
->will($this->returnValue($authedToken));
|
||||
|
||||
// user checker should be called
|
||||
$this->userChecker->expects($this->once())
|
||||
->method('checkPreAuth')
|
||||
->with($mockedUser);
|
||||
$this->userChecker->expects($this->once())
|
||||
->method('checkPostAuth')
|
||||
->with($mockedUser);
|
||||
|
||||
$provider = new GuardAuthenticationProvider($authenticators, $this->userProvider, $providerKey, $this->userChecker);
|
||||
$actualAuthedToken = $provider->authenticate($this->preAuthenticationToken);
|
||||
$this->assertSame($authedToken, $actualAuthedToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testLegacyAuthenticate()
|
||||
{
|
||||
$providerKey = 'my_cool_firewall';
|
||||
|
||||
$authenticatorA = $this->getMockBuilder('Symfony\Component\Security\Guard\GuardAuthenticatorInterface')->getMock();
|
||||
$authenticatorB = $this->getMockBuilder('Symfony\Component\Security\Guard\GuardAuthenticatorInterface')->getMock();
|
||||
$authenticatorC = $this->getMockBuilder('Symfony\Component\Security\Guard\GuardAuthenticatorInterface')->getMock();
|
||||
|
|
|
@ -29,7 +29,7 @@ class PreAuthenticationGuardToken extends AbstractToken implements GuardTokenInt
|
|||
|
||||
/**
|
||||
* @param mixed $credentials
|
||||
* @param string $guardProviderKey Unique key that bind this token to a specific GuardAuthenticatorInterface
|
||||
* @param string $guardProviderKey Unique key that bind this token to a specific AuthenticatorInterface
|
||||
*/
|
||||
public function __construct($credentials, $guardProviderKey)
|
||||
{
|
||||
|
|
|
@ -58,6 +58,14 @@ class TranslationDataCollector extends DataCollector implements LateDataCollecto
|
|||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->data = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
|
|
|
@ -19,6 +19,7 @@ use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;
|
|||
use Symfony\Component\Validator\Validator\TraceableValidator;
|
||||
use Symfony\Component\VarDumper\Caster\Caster;
|
||||
use Symfony\Component\VarDumper\Caster\ClassStub;
|
||||
use Symfony\Component\VarDumper\Cloner\Data;
|
||||
use Symfony\Component\VarDumper\Cloner\Stub;
|
||||
|
||||
/**
|
||||
|
@ -31,10 +32,7 @@ class ValidatorDataCollector extends DataCollector implements LateDataCollectorI
|
|||
public function __construct(TraceableValidator $validator)
|
||||
{
|
||||
$this->validator = $validator;
|
||||
$this->data = array(
|
||||
'calls' => array(),
|
||||
'violations_count' => 0,
|
||||
);
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -45,6 +43,15 @@ class ValidatorDataCollector extends DataCollector implements LateDataCollectorI
|
|||
// Everything is collected once, on kernel terminate.
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->validator->reset();
|
||||
$this->data = array(
|
||||
'calls' => $this->cloneVar(array()),
|
||||
'violations_count' => 0,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -52,16 +59,22 @@ class ValidatorDataCollector extends DataCollector implements LateDataCollectorI
|
|||
{
|
||||
$collected = $this->validator->getCollectedData();
|
||||
$this->data['calls'] = $this->cloneVar($collected);
|
||||
$this->data['violations_count'] += array_reduce($collected, function ($previous, $item) {
|
||||
return $previous += count($item['violations']);
|
||||
$this->data['violations_count'] = array_reduce($collected, function ($previous, $item) {
|
||||
return $previous + count($item['violations']);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Data
|
||||
*/
|
||||
public function getCalls()
|
||||
{
|
||||
return $this->data['calls'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getViolationsCount()
|
||||
{
|
||||
return $this->data['violations_count'];
|
||||
|
|
|
@ -50,6 +50,33 @@ class ValidatorDataCollectorTest extends TestCase
|
|||
$this->assertCount(2, $call['violations']);
|
||||
}
|
||||
|
||||
public function testReset()
|
||||
{
|
||||
$originalValidator = $this->createMock(ValidatorInterface::class);
|
||||
$validator = new TraceableValidator($originalValidator);
|
||||
|
||||
$collector = new ValidatorDataCollector($validator);
|
||||
|
||||
$violations = new ConstraintViolationList(array(
|
||||
$this->createMock(ConstraintViolation::class),
|
||||
$this->createMock(ConstraintViolation::class),
|
||||
));
|
||||
$originalValidator->method('validate')->willReturn($violations);
|
||||
|
||||
$validator->validate(new \stdClass());
|
||||
|
||||
$collector->lateCollect();
|
||||
$collector->reset();
|
||||
|
||||
$this->assertCount(0, $collector->getCalls());
|
||||
$this->assertSame(0, $collector->getViolationsCount());
|
||||
|
||||
$collector->lateCollect();
|
||||
|
||||
$this->assertCount(0, $collector->getCalls());
|
||||
$this->assertSame(0, $collector->getViolationsCount());
|
||||
}
|
||||
|
||||
protected function createMock($classname)
|
||||
{
|
||||
return $this->getMockBuilder($classname)->disableOriginalConstructor()->getMock();
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
|
||||
namespace Symfony\Component\Validator\Validator;
|
||||
|
||||
use Symfony\Component\Validator\ConstraintViolationList;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
|
||||
/**
|
||||
|
@ -30,13 +29,18 @@ class TraceableValidator implements ValidatorInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* @return ConstraintViolationList[]
|
||||
* @return array
|
||||
*/
|
||||
public function getCollectedData()
|
||||
{
|
||||
return $this->collectedData;
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->collectedData = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -16,6 +16,7 @@ CHANGELOG
|
|||
-----
|
||||
|
||||
* added `AbstractCloner::setMinDepth()` function to ensure minimum tree depth
|
||||
* deprecated `MongoCaster`
|
||||
|
||||
2.7.0
|
||||
-----
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue