Merge branch 'master' into form-padded-choice-list

This commit is contained in:
Victor Berchet 2011-05-09 15:30:04 +02:00
commit e0f03471ae
80 changed files with 821 additions and 294 deletions

View File

@ -8,6 +8,50 @@
beta1 から beta2
----------------
* ``error_handler`` の設定が削除されました。\ ``ErrorHandler`` クラスは Symfony Standard Edition の ``AppKernel`` で直接管理されるように変更されました。
* Doctrine のメタデータ用のディレクトリが、\ ``Resources/config/doctrine/metadata/orm/`` から ``Resources/config/doctrine`` に変更され、各ファイルの拡張子が ``.dcm.yml`` から ``.orm.yml`` に変更されました。
変更前:
Resources/config/doctrine/metadata/orm/Bundle.Entity.dcm.xml
Resources/config/doctrine/metadata/orm/Bundle.Entity.dcm.yml
変更後:
Resources/config/doctrine/Bundle.Entity.orm.xml
Resources/config/doctrine/Bundle.Entity.orm.yml
* 新しい Doctrine Registry クラスの導入により、次のパラメータは削除されました(\ `doctrine` サービスのメソッドに置き換えられました)。
* doctrine.orm.entity_managers
* doctrine.orm.default_entity_manager
* doctrine.dbal.default_connection
変更前:
$container->getParameter('doctrine.orm.entity_managers')
$container->getParameter('doctrine.orm.default_entity_manager')
$container->getParameter('doctrine.orm.default_connection')
変更後:
$container->get('doctrine')->getEntityManagerNames()
$container->get('doctrine')->getDefaultEntityManagerName()
$container->get('doctrine')->getDefaultConnectionName()
ただし、これらのメソッドを使わなくても、次のようにして Registry オブジェクトから直接 EntityManager オブジェクトを取得できます。
変更前:
$em = $this->get('doctrine.orm.entity_manager');
$em = $this->get('doctrine.orm.foobar_entity_manager');
変更後:
$em = $this->get('doctrine')->getEntityManager();
$em = $this->get('doctrine')->getEntityManager('foobar');
* `doctrine:generate:entities` コマンドの引数とオプションが変更されました。
新しい引数とオプションの詳細は、\ `./app/console doctrine:generate:entities --help` コマンドを実行して確認してください。
@ -44,20 +88,32 @@ beta1 から beta2
- { name: doctrine.event_subscriber } # すべてのコネクションに対して登録
- { name: doctrine.event_subscriber, connection: default } # デフォルトコネクションにのみ登録
* `doctrine.orm.entity_managers` は、エンティティマネージャーの名前と ID のペアのハッシュに変更されました。
変更前: array('default', 'foo')
変更後: array('default' => 'doctrine.orm.default_entity_manager', 'foo' => 'doctrine.orm.foo_entity_manager'))
* アプリケーションの翻訳ファイルは、\ `Resources` ディレクトリに保存されるように変更されました。
変更前:
app/translations/catalogue.fr.xml
app/translations/catalogue.fr.xml
変更後:
app/Resources/translations/catalogue.fr.xml
app/Resources/translations/catalogue.fr.xml
* "collection" フォームタイプの "modifiable" オプションは、2 つのオプション "allow_add" と "allow_delete" に分割されました。
変更前:
$builder->add('tags', 'collection', array(
'type' => 'text',
'modifiable' => true,
));
変更後:
$builder->add('tags', 'collection', array(
'type' => 'text',
'allow_add' => true,
'allow_delete' => true,
));
PR12 から beta1
---------------

View File

@ -14,7 +14,7 @@ beta1 to beta2
* The Doctrine metadata files has moved from
``Resources/config/doctrine/metadata/orm/`` to ``Resources/config/doctrine``
and the extension from ``.dcm.yml`` to ``.orm.dcm.yml``
and the extension from ``.dcm.yml`` to ``.orm.yml``
Before:
@ -23,8 +23,8 @@ beta1 to beta2
After:
Resources/config/doctrine/Bundle.Entity.orm.dcm.xml
Resources/config/doctrine/Bundle.Entity.orm.dcm.yml
Resources/config/doctrine/Bundle.Entity.orm.xml
Resources/config/doctrine/Bundle.Entity.orm.yml
* With the introduction of a new Doctrine Registry class, the following
parameters have been removed (replaced by methods on the `doctrine`
@ -124,6 +124,9 @@ beta1 to beta2
'allow_delete' => true,
));
* Serializer: The NormalizerInterface's `supports()` method has been split in
two methods: `supportsNormalization` and `supportsDenormalization`.
PR12 to beta1
-------------
@ -144,6 +147,9 @@ PR12 to beta1
* The `File::getWebPath()` and `File::rename()` methods have been removed, as
well as the `framework.document_root` configuration setting.
* The `File::getDefaultExtension()` method has been renamed to `File::guessExtension()`.
The renamed method now returns null if it cannot guess the extension.
* The `session` configuration has been refactored:
* The `class` option has been removed (use the `session.class` parameter
@ -210,11 +216,11 @@ PR11 to PR12
<app:engine>twig</app:engine>
<twig:extension>twig.extension.debug</twig:extension>
* Fixes a critical security issue which allowed all users to switch to
* Fixes a critical security issue which allowed all users to switch to
arbitrary accounts when the SwitchUserListener was activated. Configurations
which do not use the SwitchUserListener are not affected.
* The Dependency Injection Container now strongly validates the references of
* The Dependency Injection Container now strongly validates the references of
all your services at the end of its compilation process. If you have invalid
references this will result in a compile-time exception instead of a run-time
exception (the previous behavior).

View File

@ -9,9 +9,9 @@
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\MonologBundle\Logger;
namespace Symfony\Bridge\Monolog\Handler;
use Monolog\Logger as MonologLogger;
use Monolog\Logger;
use Monolog\Handler\TestHandler;
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
@ -46,7 +46,7 @@ class DebugHandler extends TestHandler implements DebugLoggerInterface
public function countErrors()
{
$cnt = 0;
foreach (array(MonologLogger::ERROR, MonologLogger::CRITICAL, MonologLogger::ALERT) as $level) {
foreach (array(Logger::ERROR, Logger::CRITICAL, Logger::ALERT) as $level) {
if (isset($this->recordsByLevel[$level])) {
$cnt += count($this->recordsByLevel[$level]);
}

View File

@ -9,11 +9,12 @@
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\MonologBundle\Logger;
namespace Symfony\Bridge\Monolog\Handler;
use Monolog\Handler\FirePHPHandler as BaseFirePHPHandler;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\HttpKernelInterface;
/**
* FirePHPHandler.
@ -32,6 +33,22 @@ class FirePHPHandler extends BaseFirePHPHandler
*/
private $response;
/**
* Adds the headers to the response once it's created
*/
public function onCoreResponse(FilterResponseEvent $event)
{
if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
return;
}
$this->response = $event->getResponse();
foreach ($this->headers as $header => $content) {
$this->response->headers->set($header, $content);
}
$this->headers = array();
}
/**
* {@inheritDoc}
*/
@ -43,16 +60,4 @@ class FirePHPHandler extends BaseFirePHPHandler
$this->headers[$header] = $content;
}
}
/**
* Adds the headers to the response once it's created
*/
public function onCoreResponse(FilterResponseEvent $event)
{
$this->response = $event->getResponse();
foreach ($this->headers as $header => $content) {
$this->response->headers->set($header, $content);
}
$this->headers = array();
}
}

View File

@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\MonologBundle\Logger;
namespace Symfony\Bridge\Monolog;
use Monolog\Logger as BaseLogger;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
@ -35,9 +35,4 @@ class Logger extends BaseLogger implements LoggerInterface
}
}
}
public function log($message, $level)
{
return $this->addRecord($level, $message);
}
}

View File

@ -26,6 +26,9 @@ use Symfony\Component\Console\Output\OutputInterface;
*/
class DumpCommand extends Command
{
private $basePath;
private $am;
protected function configure()
{
$this
@ -36,21 +39,29 @@ class DumpCommand extends Command
;
}
protected function initialize(InputInterface $input, OutputInterface $output)
{
parent::initialize($input, $output);
$this->basePath = $input->getArgument('write_to') ?: $this->container->getParameter('assetic.write_to');
$this->am = $this->container->get('assetic.asset_manager');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
if (!$basePath = $input->getArgument('write_to')) {
$basePath = $this->container->getParameter('assetic.write_to');
if (!$input->getOption('watch')) {
foreach ($this->am->getNames() as $name) {
$this->dumpAsset($name, $output);
}
return;
}
$am = $this->container->get('assetic.asset_manager');
if ($input->getOption('watch')) {
return $this->watch($am, $basePath, $output, $this->container->getParameter('kernel.debug'));
if (!$this->am->isDebug()) {
throw new \RuntimeException('The --watch option is only available in debug mode.');
}
foreach ($am->getNames() as $name) {
$this->dumpAsset($am->get($name), $basePath, $output);
}
$this->watch($output);
}
/**
@ -59,22 +70,15 @@ class DumpCommand extends Command
* This method includes an infinite loop the continuously polls the asset
* manager for changes.
*
* @param LazyAssetManager $am The asset manager
* @param string $basePath The base directory to write to
* @param OutputInterface $output The command output
* @param Boolean $debug Debug mode
* @param OutputInterface $output The command output
*/
protected function watch(LazyAssetManager $am, $basePath, OutputInterface $output, $debug = false)
private function watch(OutputInterface $output)
{
if (!$debug) {
throw new \RuntimeException('The --watch option is only available in debug mode.');
}
$refl = new \ReflectionClass('Assetic\\AssetManager');
$prop = $refl->getProperty('assets');
$prop->setAccessible(true);
$cache = sys_get_temp_dir().'/assetic_watch_'.substr(sha1($basePath), 0, 7);
$cache = sys_get_temp_dir().'/assetic_watch_'.substr(sha1($this->basePath), 0, 7);
if (file_exists($cache)) {
$previously = unserialize(file_get_contents($cache));
} else {
@ -84,15 +88,15 @@ class DumpCommand extends Command
$error = '';
while (true) {
try {
foreach ($am->getNames() as $name) {
if ($asset = $this->checkAsset($am, $name, $previously)) {
$this->dumpAsset($asset, $basePath, $output);
foreach ($this->am->getNames() as $name) {
if ($asset = $this->checkAsset($name, $previously)) {
$this->dumpAsset($asset, $output);
}
}
// reset the asset manager
$prop->setValue($am, array());
$am->load();
$prop->setValue($this->am, array());
$this->am->load();
file_put_contents($cache, serialize($previously));
$error = '';
@ -110,16 +114,15 @@ class DumpCommand extends Command
/**
* Checks if an asset should be dumped.
*
* @param LazyAssetManager $am The asset manager
* @param string $name The asset name
* @param array &$previously An array of previous visits
* @param string $name The asset name
* @param array &$previously An array of previous visits
*
* @return AssetInterface|Boolean The asset if it should be dumped
*/
protected function checkAsset(LazyAssetManager $am, $name, array &$previously)
private function checkAsset($name, array &$previously)
{
$formula = $am->hasFormula($name) ? serialize($am->getFormula($name)) : null;
$asset = $am->get($name);
$formula = $this->am->hasFormula($name) ? serialize($this->am->getFormula($name)) : null;
$asset = $this->am->get($name);
$mtime = $asset->getLastModified();
if (isset($previously[$name])) {
@ -136,15 +139,39 @@ class DumpCommand extends Command
/**
* Writes an asset.
*
* @param AssetInterface $asset An asset
* @param string $basePath The base directory to write to
* @param OutputInterface $output The command output
* If the application or asset is in debug mode, each leaf asset will be
* dumped as well.
*
* @param string $name An asset name
* @param OutputInterface $output The command output
*/
private function dumpAsset($name, OutputInterface $output)
{
$asset = $this->am->get($name);
$formula = $this->am->getFormula($name);
// start by dumping the main asset
$this->doDump($asset, $output);
// dump each leaf if debug
if (isset($formula[2]['debug']) ? $formula[2]['debug'] : $this->am->isDebug()) {
foreach ($asset as $leaf) {
$this->doDump($leaf, $output);
}
}
}
/**
* Performs the asset dump.
*
* @param AssetInterface $asset An asset
* @param OutputInterface $output The command output
*
* @throws RuntimeException If there is a problem writing the asset
*/
protected function dumpAsset(AssetInterface $asset, $basePath, OutputInterface $output)
private function doDump(AssetInterface $asset, OutputInterface $output)
{
$target = rtrim($basePath, '/').'/'.str_replace('_controller/', '', $asset->getTargetUrl());
$target = rtrim($this->basePath, '/').'/'.str_replace('_controller/', '', $asset->getTargetUrl());
if (!is_dir($dir = dirname($target))) {
$output->writeln('<info>[dir+]</info> '.$dir);
if (false === @mkdir($dir, 0777, true)) {

View File

@ -0,0 +1,165 @@
<?php
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Symfony\Bundle\AsseticBundle\Tests\Command;
use Symfony\Bundle\AsseticBundle\Command\DumpCommand;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\NullOutput;
class DumpCommandTest extends \PHPUnit_Framework_TestCase
{
private $writeTo;
private $application;
private $definition;
private $kernel;
private $container;
private $am;
protected function setUp()
{
if (!class_exists('Assetic\\AssetManager')) {
$this->markTestSkipped('Assetic is not available.');
}
$this->writeTo = sys_get_temp_dir().'/assetic_dump';
$this->application = $this->getMockBuilder('Symfony\\Bundle\\FrameworkBundle\\Console\\Application')
->disableOriginalConstructor()
->getMock();
$this->definition = $this->getMockBuilder('Symfony\\Component\\Console\\Input\\InputDefinition')
->disableOriginalConstructor()
->getMock();
$this->kernel = $this->getMock('Symfony\\Component\\HttpKernel\\KernelInterface');
$this->container = $this->getMock('Symfony\\Component\\DependencyInjection\\ContainerInterface');
$this->am = $this->getMockBuilder('Assetic\\Factory\\LazyAssetManager')
->disableOriginalConstructor()
->getMock();
$this->application->expects($this->any())
->method('getDefinition')
->will($this->returnValue($this->definition));
$this->definition->expects($this->any())
->method('getArguments')
->will($this->returnValue(array()));
$this->definition->expects($this->any())
->method('getOptions')
->will($this->returnValue(array()));
$this->application->expects($this->any())
->method('getKernel')
->will($this->returnValue($this->kernel));
$this->kernel->expects($this->any())
->method('getContainer')
->will($this->returnValue($this->container));
$this->container->expects($this->any())
->method('getParameter')
->with('assetic.write_to')
->will($this->returnValue($this->writeTo));
$this->container->expects($this->once())
->method('get')
->with('assetic.asset_manager')
->will($this->returnValue($this->am));
$this->command = new DumpCommand();
$this->command->setApplication($this->application);
}
protected function tearDown()
{
if (is_dir($this->writeTo)) {
array_map('unlink', glob($this->writeTo.'/*'));
rmdir($this->writeTo);
}
}
public function testEmptyAssetManager()
{
$this->am->expects($this->once())
->method('getNames')
->will($this->returnValue(array()));
$this->command->run(new ArrayInput(array()), new NullOutput());
}
public function testDumpOne()
{
$asset = $this->getMock('Assetic\\Asset\\AssetInterface');
$this->am->expects($this->once())
->method('getNames')
->will($this->returnValue(array('test_asset')));
$this->am->expects($this->once())
->method('get')
->with('test_asset')
->will($this->returnValue($asset));
$this->am->expects($this->once())
->method('getFormula')
->with('test_asset')
->will($this->returnValue(array()));
$this->am->expects($this->once())
->method('isDebug')
->will($this->returnValue(false));
$asset->expects($this->once())
->method('getTargetUrl')
->will($this->returnValue('test_asset.css'));
$asset->expects($this->once())
->method('dump')
->will($this->returnValue('/* test_asset */'));
$this->command->run(new ArrayInput(array()), new NullOutput());
$this->assertFileExists($this->writeTo.'/test_asset.css');
$this->assertEquals('/* test_asset */', file_get_contents($this->writeTo.'/test_asset.css'));
}
public function testDumpDebug()
{
$asset = $this->getMock('Assetic\\Asset\\AssetCollection');
$leaf = $this->getMock('Assetic\\Asset\\AssetInterface');
$this->am->expects($this->once())
->method('getNames')
->will($this->returnValue(array('test_asset')));
$this->am->expects($this->once())
->method('get')
->with('test_asset')
->will($this->returnValue($asset));
$this->am->expects($this->once())
->method('getFormula')
->with('test_asset')
->will($this->returnValue(array()));
$this->am->expects($this->once())
->method('isDebug')
->will($this->returnValue(true));
$asset->expects($this->once())
->method('getTargetUrl')
->will($this->returnValue('test_asset.css'));
$asset->expects($this->once())
->method('dump')
->will($this->returnValue('/* test_asset */'));
$asset->expects($this->once())
->method('getIterator')
->will($this->returnValue(new \ArrayIterator(array($leaf))));
$leaf->expects($this->once())
->method('getTargetUrl')
->will($this->returnValue('test_leaf.css'));
$leaf->expects($this->once())
->method('dump')
->will($this->returnValue('/* test_leaf */'));
$this->command->run(new ArrayInput(array()), new NullOutput());
$this->assertFileExists($this->writeTo.'/test_asset.css');
$this->assertFileExists($this->writeTo.'/test_leaf.css');
$this->assertEquals('/* test_asset */', file_get_contents($this->writeTo.'/test_asset.css'));
$this->assertEquals('/* test_leaf */', file_get_contents($this->writeTo.'/test_leaf.css'));
}
}

View File

@ -263,11 +263,12 @@ abstract class AbstractDoctrineExtension extends Extension
}
$container->addResource(new FileResource($resource));
if (($files = glob($dir.'/'.$configPath.'/*.orm.dcm.xml')) && count($files)) {
$extension = $this->getMappingResourceExtension();
if (($files = glob($dir.'/'.$configPath.'/*.'.$extension.'.xml')) && count($files)) {
return 'xml';
} elseif (($files = glob($dir.'/'.$configPath.'/*.orm.dcm.yml')) && count($files)) {
} elseif (($files = glob($dir.'/'.$configPath.'/*.'.$extension.'.yml')) && count($files)) {
return 'yml';
} elseif (($files = glob($dir.'/'.$configPath.'/*.orm.dcm.php')) && count($files)) {
} elseif (($files = glob($dir.'/'.$configPath.'/*.'.$extension.'.php')) && count($files)) {
return 'php';
}
@ -306,4 +307,11 @@ abstract class AbstractDoctrineExtension extends Extension
* @return string
*/
abstract protected function getMappingResourceConfigDirectory();
/**
* Extension used by the mapping files.
*
* @return string
*/
abstract protected function getMappingResourceExtension();
}

View File

@ -31,6 +31,7 @@ class GenerateEntitiesDoctrineCommand extends DoctrineCommand
->setName('doctrine:generate:entities')
->setDescription('Generate entity classes and method stubs from your mapping information')
->addArgument('name', InputArgument::REQUIRED, 'A bundle name, a namespace, or a class name')
->addOption('path', null, InputOption::VALUE_REQUIRED, 'The path where to generate entities when it cannot be guessed')
->setHelp(<<<EOT
The <info>doctrine:generate:entities</info> command generates entity classes
and method stubs from your mapping information:
@ -49,6 +50,13 @@ You have to limit generation of entities:
* To a namespace
<info>./app/console doctrine:generate:entities MyCustomBundle/Entity</info>
If the entities are not stored in a bundle, and if the classes do not exist,
the command has no way to guess where they should be generated. In this case,
you must provide the <comment>--path</comment> option:
<info>./app/console doctrine:generate:entities Blog/Entity --path=src/</info>
EOT
);
}
@ -69,10 +77,10 @@ EOT
if (class_exists($name)) {
$output->writeln(sprintf('Generating entity "<info>%s</info>"', $name));
list($metadatas, $namespace, $path) = $this->getClassInfo($name);
list($metadatas, $namespace, $path) = $this->getClassInfo($name, $input->getOption('path'));
} else {
$output->writeln(sprintf('Generating entities for namespace "<info>%s</info>"', $name));
list($metadatas, $namespace, $path) = $this->getNamespaceInfo($name);
list($metadatas, $namespace, $path) = $this->getNamespaceInfo($name, $input->getOption('path'));
}
}
@ -104,33 +112,36 @@ EOT
return array($metadatas, $bundle->getNamespace(), $path);
}
private function getClassInfo($class)
private function getClassInfo($class, $path)
{
if (!$metadatas = $this->findMetadatasByClass($class)) {
throw new \RuntimeException(sprintf('Entity "%s" is not a mapped entity.', $class));
}
$r = $metadatas[$class]->getReflectionClass();
if (!$r) {
throw new \RuntimeException('Unable to determine where to save the "%s" class.', $class);
if (class_exists($class)) {
$r = $metadatas[$class]->getReflectionClass();
$path = $this->findBasePathForClass($class, $r->getNamespacename(), dirname($r->getFilename()));
} elseif (!$path) {
throw new \RuntimeException(sprintf('Unable to determine where to save the "%s" class (use the --path option).', $class));
}
$path = $this->findBasePathForClass($class, $r->getNamespacename(), dirname($r->getFilename()));
return array($metadatas, $r->getNamespacename(), $path);
}
private function getNamespaceInfo($namespace)
private function getNamespaceInfo($namespace, $path)
{
if (!$metadatas = $this->findMetadatasByNamespace($namespace)) {
throw new \RuntimeException(sprintf('Namespace "%s" does not contain any mapped entities.', $namespace));
}
$first = reset($metadatas);
$r = $first->getReflectionClass();
if (!$r) {
throw new \RuntimeException('Unable to determine where to save the "%s" class.', $class);
$class = key($metadatas);
if (class_exists($class)) {
$r = $first->getReflectionClass();
$path = $this->findBasePathForClass($namespace, $r->getNamespacename(), dirname($r->getFilename()));
} elseif (!$path) {
throw new \RuntimeException(sprintf('Unable to determine where to save the "%s" class (use the --path option).', $class));
}
$path = $this->findBasePathForClass($namespace, $r->getNamespacename(), dirname($r->getFilename()));
return array($metadatas, $namespace, $path);
}

View File

@ -103,7 +103,7 @@ EOT
$mappingPath = $mappingCode = false;
} else {
$mappingType = 'yaml' == $mappingType ? 'yml' : $mappingType;
$mappingPath = $bundle->getPath().'/Resources/config/doctrine/'.str_replace('\\', '.', $fullEntityClassName).'.orm.dcm.'.$mappingType;
$mappingPath = $bundle->getPath().'/Resources/config/doctrine/'.str_replace('\\', '.', $fullEntityClassName).'.orm.'.$mappingType;
$mappingCode = $exporter->exportClassMetadata($class);
$entityGenerator = $this->getEntityGenerator();

View File

@ -89,9 +89,9 @@ EOT
$className = $class->name;
$class->name = $bundle->getNamespace().'\\Entity\\'.$className;
if ('annotation' === $type) {
$path = $destPath.'/'.$className.'.orm.dcm.php';
$path = $destPath.'/'.$className.'.orm.php';
} else {
$path = $destPath.'/'.str_replace('\\', '.', $class->name).'.orm.dcm.'.$type;
$path = $destPath.'/'.str_replace('\\', '.', $class->name).'.orm.'.$type;
}
$output->writeln(sprintf(' > writing <comment>%s</comment>', $path));
$code = $exporter->exportClassMetadata($class);

View File

@ -318,6 +318,11 @@ class DoctrineExtension extends AbstractDoctrineExtension
return 'Resources/config/doctrine';
}
protected function getMappingResourceExtension()
{
return 'orm';
}
/**
* Loads a configured entity managers cache drivers.
*

View File

@ -22,7 +22,7 @@ class XmlDriver extends BaseXmlDriver
{
protected $_globalFile = 'mapping';
protected $_classCache;
protected $_fileExtension = '.orm.dcm.xml';
protected $_fileExtension = '.orm.xml';
public function isTransient($className)
{

View File

@ -22,7 +22,7 @@ class YamlDriver extends BaseYamlDriver
{
protected $_globalFile = 'mapping';
protected $_classCache;
protected $_fileExtension = '.orm.dcm.yml';
protected $_fileExtension = '.orm.yml';
public function isTransient($className)
{

View File

@ -24,7 +24,7 @@
</service>
<service id="profiler_listener" class="%profiler_listener.class%">
<tag name="kernel.listener" event="onCoreResponse" />
<tag name="kernel.listener" event="onCoreResponse" priority="-100" />
<tag name="kernel.listener" event="onCoreException" />
<tag name="kernel.listener" event="onCoreRequest" />
<argument type="service" id="service_container" />

View File

@ -2,6 +2,7 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset={{ _charset }}"/>
<meta name="robots" content="noindex,nofollow" />
<title>{% block title '' %}</title>
<link href="{{ asset('bundles/framework/css/exception_layout.css') }}" rel="stylesheet" type="text/css" media="all" />
<link href="{{ asset('bundles/framework/css/exception.css') }}" rel="stylesheet" type="text/css" media="all" />

View File

@ -59,7 +59,7 @@ class Translator extends BaseTranslator
// check option names
if ($diff = array_diff(array_keys($options), array_keys($this->options))) {
throw new \InvalidArgumentException(sprintf('The Router does not support the following options: \'%s\'.', implode('\', \'', $diff)));
throw new \InvalidArgumentException(sprintf('The Translator does not support the following options: \'%s\'.', implode('\', \'', $diff)));
}
$this->options = array_merge($this->options, $options);

View File

@ -57,13 +57,18 @@ class Configuration implements ConfigurationInterface
->scalarNode('priority')->defaultValue(0)->end()
->scalarNode('level')->defaultValue('DEBUG')->end()
->booleanNode('bubble')->defaultFalse()->end()
->scalarNode('path')->end() // stream and rotating
->scalarNode('ident')->end() // syslog
->scalarNode('facility')->end() // syslog
->scalarNode('max_files')->end() // rotating
->scalarNode('action_level')->end() // fingers_crossed
->scalarNode('buffer_size')->end() // fingers_crossed and buffer
->scalarNode('path')->defaultValue('%kernel.logs_dir%/%kernel.environment%.log')->end() // stream and rotating
->scalarNode('ident')->defaultFalse()->end() // syslog
->scalarNode('facility')->defaultValue('user')->end() // syslog
->scalarNode('max_files')->defaultValue(0)->end() // rotating
->scalarNode('action_level')->defaultValue('WARNING')->end() // fingers_crossed
->booleanNode('stop_buffering')->defaultTrue()->end()// fingers_crossed
->scalarNode('buffer_size')->defaultValue(0)->end() // fingers_crossed and buffer
->scalarNode('handler')->end() // fingers_crossed and buffer
->scalarNode('from_email')->end() // swift_mailer and native_mailer
->scalarNode('to_email')->end() // swift_mailer and native_mailer
->scalarNode('subject')->end() // swift_mailer and native_mailer
->scalarNode('email_prototype')->end() // swift_mailer
->scalarNode('formatter')->end()
->end()
->append($this->getProcessorsNode())
@ -71,6 +76,14 @@ class Configuration implements ConfigurationInterface
->ifTrue(function($v) { return ('fingers_crossed' === $v['type'] || 'buffer' === $v['type']) && 1 !== count($v['handler']); })
->thenInvalid('The handler has to be specified to use a FingersCrossedHandler')
->end()
->validate()
->ifTrue(function($v) { return 'swift_mailer' === $v['type'] && empty($v['email_prototype']) && (empty($v['from_email']) || empty($v['to_email']) || empty($v['subject'])); })
->thenInvalid('The sender, recipient and subject or an email prototype have to be specified to use a SwiftMailerHandler')
->end()
->validate()
->ifTrue(function($v) { return 'native_mailer' === $v['type'] && (empty($v['from_email']) || empty($v['to_email']) || empty($v['subject'])); })
->thenInvalid('The sender, recipient and subject have to be specified to use a NativeMailerHandler')
->end()
->validate()
->ifTrue(function($v) { return 'service' === $v['type'] && !isset($v['id']); })
->thenInvalid('The id has to be specified to use a service as handler')

View File

@ -112,10 +112,6 @@ class MonologExtension extends Extension
return $handlerId;
case 'stream':
if (!isset($handler['path'])) {
$handler['path'] = '%kernel.logs_dir%/%kernel.environment%.log';
}
$definition->setArguments(array(
$handler['path'],
$handler['level'],
@ -132,22 +128,15 @@ class MonologExtension extends Extension
break;
case 'rotating_file':
if (!isset($handler['path'])) {
$handler['path'] = '%kernel.logs_dir%/%kernel.environment%.log';
}
$definition->setArguments(array(
$handler['path'],
isset($handler['max_files']) ? $handler['max_files'] : 0,
$handler['max_files'],
$handler['level'],
$handler['bubble'],
));
break;
case 'fingers_crossed':
if (!isset($handler['action_level'])) {
$handler['action_level'] = 'WARNING';
}
$handler['action_level'] = is_int($handler['action_level']) ? $handler['action_level'] : constant('Monolog\Logger::'.strtoupper($handler['action_level']));
$nestedHandlerId = $this->getHandlerId($handler['handler']);
array_push($this->nestedHandlers, $nestedHandlerId);
@ -155,8 +144,9 @@ class MonologExtension extends Extension
$definition->setArguments(array(
new Reference($nestedHandlerId),
$handler['action_level'],
isset($handler['buffer_size']) ? $handler['buffer_size'] : 0,
$handler['buffer_size'],
$handler['bubble'],
$handler['stop_buffering'],
));
break;
@ -166,20 +156,13 @@ class MonologExtension extends Extension
$definition->setArguments(array(
new Reference($nestedHandlerId),
isset($handler['buffer_size']) ? $handler['buffer_size'] : 0,
$handler['buffer_size'],
$handler['level'],
$handler['bubble'],
));
break;
case 'syslog':
if (!isset($handler['ident'])) {
$handler['ident'] = false;
}
if (!isset($handler['facility'])) {
$handler['facility'] = 'user';
}
$definition->setArguments(array(
$handler['ident'],
$handler['facility'],
@ -188,13 +171,49 @@ class MonologExtension extends Extension
));
break;
default:
// Handler using the constructor of AbstractHandler without adding their own arguments
case 'swift_mailer':
if (isset($handler['email_prototype'])) {
$prototype = $this->parseDefinition($handler['email_prototype']);
} else {
$message = new Definition('Swift_Message');
$message->setPublic(false);
$message->addMethodCall('setFrom', $handler['from_email']);
$message->addMethodCall('setTo', $handler['to_email']);
$message->addMethodCall('setSubject', $handler['subject']);
$messageId = sprintf('%s.mail_prototype', $handlerId);
$container->setDefinition($messageId, $message);
$prototype = new Reference($messageId);
}
$definition->setArguments(array(
new Reference('mailer'),
$prototype,
$handler['level'],
$handler['bubble'],
));
break;
case 'native_mailer':
$definition->setArguments(array(
$handler['to_email'],
$handler['subject'],
$handler['from_email'],
$handler['level'],
$handler['bubble'],
));
break;
// Handlers using the constructor of AbstractHandler without adding their own arguments
case 'test':
case 'null':
case 'debug':
$definition->setArguments(array(
$handler['level'],
$handler['bubble'],
));
break;
default:
throw new \InvalidArgumentException(sprintf('Invalid handler type "%s" given for handler "%s"', $handler['type'], $name));
}
if (!empty($handler['formatter'])) {
@ -216,10 +235,16 @@ class MonologExtension extends Extension
private function addProcessors(Definition $definition, array $processors)
{
foreach (array_reverse($processors) as $processor) {
if (0 === strpos($processor, '@')) {
$processor = new Reference(substr($processor, 1));
}
$definition->addMethodCall('pushProcessor', array($processor));
$definition->addMethodCall('pushProcessor', array($this->parseDefinition($processor)));
}
}
private function parseDefinition($definition)
{
if (0 === strpos($processor, '@')) {
return new Reference(substr($definition, 1));
}
return $definition;
}
}

View File

@ -5,7 +5,7 @@
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="monolog.logger.class">Symfony\Bundle\MonologBundle\Logger\Logger</parameter>
<parameter key="monolog.logger.class">Symfony\Bridge\Monolog\Logger</parameter>
<parameter key="monolog.handler.stream.class">Monolog\Handler\StreamHandler</parameter>
<parameter key="monolog.handler.fingers_crossed.class">Monolog\Handler\FingersCrossedHandler</parameter>
<parameter key="monolog.handler.buffer.class">Monolog\Handler\BufferHandler</parameter>
@ -13,8 +13,10 @@
<parameter key="monolog.handler.syslog.class">Monolog\Handler\SyslogHandler</parameter>
<parameter key="monolog.handler.null.class">Monolog\Handler\NullHandler</parameter>
<parameter key="monolog.handler.test.class">Monolog\Handler\TestHandler</parameter>
<parameter key="monolog.handler.firephp.class">Symfony\Bundle\MonologBundle\Logger\FirePHPHandler</parameter>
<parameter key="monolog.handler.debug.class">Symfony\Bundle\MonologBundle\Logger\DebugHandler</parameter>
<parameter key="monolog.handler.firephp.class">Symfony\Bridge\Monolog\Handler\FirePHPHandler</parameter>
<parameter key="monolog.handler.debug.class">Symfony\Bridge\Monolog\Handler\DebugHandler</parameter>
<parameter key="monolog.handler.swift_mailer.class">Monolog\Handler\SwiftMailerHandler</parameter>
<parameter key="monolog.handler.native_mailer.class">Monolog\Handler\NativeMailerHandler</parameter>
</parameters>
<services>

View File

@ -77,7 +77,7 @@ class MonologExtensionTest extends TestCase
$handler = $container->getDefinition('monolog.handler.main');
$this->assertDICDefinitionClass($handler, '%monolog.handler.fingers_crossed.class%');
$this->assertDICConstructorArguments($handler, array(new Reference('monolog.handler.nested'), \Monolog\Logger::ERROR, 0, false));
$this->assertDICConstructorArguments($handler, array(new Reference('monolog.handler.nested'), \Monolog\Logger::ERROR, 0, false, true));
}
public function testLoadWithOverwriting()
@ -110,7 +110,7 @@ class MonologExtensionTest extends TestCase
$handler = $container->getDefinition('monolog.handler.main');
$this->assertDICDefinitionClass($handler, '%monolog.handler.fingers_crossed.class%');
$this->assertDICConstructorArguments($handler, array(new Reference('monolog.handler.nested'), \Monolog\Logger::ERROR, 0, false));
$this->assertDICConstructorArguments($handler, array(new Reference('monolog.handler.nested'), \Monolog\Logger::ERROR, 0, false, true));
}
public function testLoadWithNewAtEnd()
@ -188,6 +188,17 @@ class MonologExtensionTest extends TestCase
$this->assertDICConstructorArguments($handler, array('/tmp/last.log', \Monolog\Logger::ERROR, true));
}
/**
* @expectedException InvalidArgumentException
*/
public function testExceptionWhenInvalidHandler()
{
$container = new ContainerBuilder();
$loader = new MonologExtension();
$loader->load(array(array('handlers' => array('main' => array('type' => 'invalid_handler')))), $container);
}
/**
* @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
*/

View File

@ -2,6 +2,7 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="robots" content="noindex,nofollow" />
<title>{% block title 'Profiler' %}</title>
<link rel="shortcut icon" type="image/x-icon" href="{{ asset('bundles/webprofiler/favicon.ico') }}" />
{% block head %}

View File

@ -11,6 +11,8 @@
namespace Symfony\Component\Config\Definition;
use Symfony\Component\Config\Definition\Exception\ForbiddenOverwriteException;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\Config\Definition\Exception\DuplicateKeyException;
use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
@ -193,8 +195,11 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
foreach ($this->children as $name => $child) {
if (!array_key_exists($name, $value)) {
if ($child->isRequired()) {
$msg = sprintf('The node at path "%s.%s" must be configured.', $this->getPath(), $name);
throw new InvalidConfigurationException($msg);
$msg = sprintf('The child node "%s" at path "%s" must be configured.', $name, $this->getPath());
$ex = new InvalidConfigurationException($msg);
$ex->setPath($this->getPath());
throw $ex;
}
if ($child->hasDefaultValue()) {
@ -223,11 +228,14 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
protected function validateType($value)
{
if (!is_array($value) && (!$this->allowFalse || false !== $value)) {
throw new InvalidTypeException(sprintf(
$ex = new InvalidTypeException(sprintf(
'Invalid type for path "%s". Expected array, but got %s',
$this->getPath(),
gettype($value)
));
$ex->setPath($this->getPath());
throw $ex;
}
}
@ -256,7 +264,10 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
// if extra fields are present, throw exception
if (count($value) && !$this->ignoreExtraKeys) {
$msg = sprintf('Unrecognized options "%s" under "%s"', implode(', ', array_keys($value)), $this->getPath());
throw new InvalidConfigurationException($msg);
$ex = new InvalidConfigurationException($msg);
$ex->setPath($this->getPath().'.'.reset($value));
throw $ex;
}
return $normalized;
@ -309,13 +320,16 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
// no conflict
if (!array_key_exists($k, $leftSide)) {
if (!$this->allowNewKeys) {
throw new InvalidConfigurationException(sprintf(
$ex = new InvalidConfigurationException(sprintf(
'You are not allowed to define new elements for path "%s". '
.'Please define all elements for this path in one config file. '
.'If you are trying to overwrite an element, make sure you redefine it '
.'with the same name.',
$this->getPath()
));
$ex->setPath($this->getPath());
throw $ex;
}
$leftSide[$k] = $v;

View File

@ -26,11 +26,14 @@ class BooleanNode extends ScalarNode
protected function validateType($value)
{
if (!is_bool($value)) {
throw new InvalidTypeException(sprintf(
$ex = new InvalidTypeException(sprintf(
'Invalid type for path "%s". Expected boolean, but got %s.',
$this->getPath(),
gettype($value)
));
$ex->setPath($this->getPath());
throw $ex;
}
}
}

View File

@ -19,4 +19,15 @@ namespace Symfony\Component\Config\Definition\Exception;
*/
class InvalidConfigurationException extends Exception
{
private $path;
public function setPath($path)
{
$this->path = $path;
}
public function getPath()
{
return $this->path;
}
}

View File

@ -161,7 +161,10 @@ class PrototypedArrayNode extends ArrayNode
if (count($value) < $this->minNumberOfElements) {
$msg = sprintf('The path "%s" should have at least %d element(s) defined.', $this->getPath(), $this->minNumberOfElements);
throw new InvalidConfigurationException($msg);
$ex = new InvalidConfigurationException($msg);
$ex->setPath($this->getPath());
throw $ex;
}
return $value;
@ -186,7 +189,10 @@ class PrototypedArrayNode extends ArrayNode
if (null !== $this->keyAttribute && is_array($v)) {
if (!isset($v[$this->keyAttribute]) && is_int($k)) {
$msg = sprintf('The attribute "%s" must be set for path "%s".', $this->keyAttribute, $this->getPath());
throw new InvalidConfigurationException($msg);
$ex = new InvalidConfigurationException($msg);
$ex->setPath($this->getPath());
throw $ex;
} else if (isset($v[$this->keyAttribute])) {
$k = $v[$this->keyAttribute];
@ -203,7 +209,10 @@ class PrototypedArrayNode extends ArrayNode
if (array_key_exists($k, $normalized)) {
$msg = sprintf('Duplicate key "%s" for path "%s".', $k, $this->getPath());
throw new DuplicateKeyException($msg);
$ex = new DuplicateKeyException($msg);
$ex->setPath($this->getPath());
throw $ex;
}
}
@ -249,11 +258,14 @@ class PrototypedArrayNode extends ArrayNode
// no conflict
if (!array_key_exists($k, $leftSide)) {
if (!$this->allowNewKeys) {
throw new InvalidConfigurationException(sprintf(
$ex = new InvalidConfigurationException(sprintf(
'You are not allowed to define new elements for path "%s". ' .
'Please define all elements for this path in one config file.',
$this->getPath()
));
$ex->setPath($this->getPath());
throw $ex;
}
$leftSide[$k] = $v;

View File

@ -34,11 +34,14 @@ class ScalarNode extends VariableNode
protected function validateType($value)
{
if (!is_scalar($value) && null !== $value) {
throw new InvalidTypeException(sprintf(
$ex = new InvalidTypeException(sprintf(
'Invalid type for path "%s". Expected scalar, but got %s.',
$this->getPath(),
gettype($value)
));
$ex->setPath($this->getPath());
throw $ex;
}
}
}

View File

@ -84,11 +84,14 @@ class VariableNode extends BaseNode implements PrototypeNodeInterface
protected function finalizeValue($value)
{
if (!$this->allowEmptyValue && empty($value)) {
throw new InvalidConfigurationException(sprintf(
$ex = new InvalidConfigurationException(sprintf(
'The path "%s" cannot contain an empty value, but got %s.',
$this->getPath(),
json_encode($value)
));
$ex->setPath($this->getPath());
throw $ex;
}
return $value;

View File

@ -49,9 +49,8 @@ class SortableIterator extends \ArrayIterator
throw new \InvalidArgumentException(sprintf('The SortableIterator takes a \Closure or a valid built-in sort algorithm as an argument (%s given).', $sort));
}
$array = new \ArrayObject(iterator_to_array($iterator));
$array->uasort($sort);
parent::__construct(iterator_to_array($iterator));
parent::__construct($array);
$this->uasort($sort);
}
}

View File

@ -13,7 +13,6 @@ namespace Symfony\Component\Form\Extension\Core;
use Symfony\Component\Form\Extension\Core\Type;
use Symfony\Component\Form\AbstractExtension;
use Symfony\Component\Validator\ValidatorInterface;
use Symfony\Component\HttpFoundation\File\TemporaryStorage;
/**

View File

@ -13,7 +13,6 @@ namespace Symfony\Component\Form\Extension\Core\DataTransformer;
use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
class ArrayToBooleanChoicesTransformer implements DataTransformerInterface

View File

@ -13,7 +13,6 @@ namespace Symfony\Component\Form\Extension\Core\DataTransformer;
use Symfony\Component\Form\Util\FormUtil;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
class ArrayToChoicesTransformer implements DataTransformerInterface

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\Form\Extension\Core\DataTransformer;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
/**

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\Form\Extension\Core\DataTransformer;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
use Symfony\Component\HttpFoundation\File\File;

View File

@ -13,7 +13,6 @@ namespace Symfony\Component\Form\Extension\Core\DataTransformer;
use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
class ScalarToBooleanChoicesTransformer implements DataTransformerInterface

View File

@ -15,7 +15,6 @@ use Symfony\Component\Form\Events;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
use Symfony\Component\Form\Event\FilterDataEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\File\TemporaryStorage;

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\Form\Extension\Core\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
class BirthdayType extends AbstractType
{

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\Form\Extension\Core\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Locale\Locale;
class CountryType extends AbstractType

View File

@ -12,8 +12,6 @@
namespace Symfony\Component\Form\Extension\Core\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormInterface;
class EmailType extends AbstractType
{

View File

@ -20,7 +20,6 @@ use Symfony\Component\Form\FormView;
use Symfony\Component\Form\Extension\Core\EventListener\TrimListener;
use Symfony\Component\Form\Extension\Core\Validator\DefaultValidator;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\Validator\ValidatorInterface;
class FieldType extends AbstractType
{

View File

@ -14,9 +14,7 @@ namespace Symfony\Component\Form\Extension\Core\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Form\Extension\Core\EventListener\FixFileUploadListener;
use Symfony\Component\Form\Extension\Core\DataTransformer\DataTransformerChain;
use Symfony\Component\Form\ReversedTransformer;
use Symfony\Component\Form\Extension\Core\DataTransformer\FileToStringTransformer;
use Symfony\Component\Form\Extension\Core\DataTransformer\FileToArrayTransformer;

View File

@ -15,9 +15,7 @@ use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper;
use Symfony\Component\EventDispatcher\EventDispatcher;
class FormType extends AbstractType
{

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\Form\Extension\Core\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
class HiddenType extends AbstractType
{

View File

@ -12,9 +12,6 @@
namespace Symfony\Component\Form\Extension\Core\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
class TextType extends AbstractType
{

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\Form\Extension\Core\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
class TextareaType extends AbstractType
{

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\Form\Extension\Core\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\Extension\Core\ChoiceList\TimezoneChoiceList;
class TimezoneType extends AbstractType

View File

@ -14,16 +14,10 @@ namespace Symfony\Component\Form;
use Symfony\Component\Form\Event\DataEvent;
use Symfony\Component\Form\Event\FilterDataEvent;
use Symfony\Component\Form\Exception\FormException;
use Symfony\Component\Form\Exception\MissingOptionsException;
use Symfony\Component\Form\Exception\AlreadyBoundException;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
use Symfony\Component\Form\Exception\DanglingFieldException;
use Symfony\Component\Form\Exception\FieldDefinitionException;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\FileBag;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Form represents a form.

View File

@ -11,7 +11,6 @@
namespace Symfony\Component\Form;
use Symfony\Component\Form\Guess\Guess;
use Symfony\Component\Form\Exception\FormException;
use Symfony\Component\Form\Exception\UnexpectedTypeException;

View File

@ -251,9 +251,10 @@ SELECTCLAUSE;
{
$sql = <<<SELECTCLAUSE
SELECT a.ancestor_id
FROM acl_object_identities o
INNER JOIN acl_classes c ON c.id = o.class_id
INNER JOIN acl_object_identity_ancestors a ON a.object_identity_id = o.id
FROM
{$this->options['oid_table_name']} o
INNER JOIN {$this->options['class_table_name']} c ON c.id = o.class_id
INNER JOIN {$this->options['oid_ancestors_table_name']} a ON a.object_identity_id = o.id
WHERE (
SELECTCLAUSE;

View File

@ -224,14 +224,14 @@ class XmlEncoder extends AbstractEncoder implements DecoderInterface
$append = $this->selectNodeType($parentNode, $data);
} elseif (is_array($data) && false === is_numeric($key)) {
/**
* Is this array fully numeric keys?
*/
* Is this array fully numeric keys?
*/
if (ctype_digit(implode('', array_keys($data)))) {
/**
* Create nodes to append to $parentNode based on the $key of this array
* Produces <xml><item>0</item><item>1</item></xml>
* From array("item" => array(0,1));
*/
* Create nodes to append to $parentNode based on the $key of this array
* Produces <xml><item>0</item><item>1</item></xml>
* From array("item" => array(0,1));
*/
foreach ($data as $subData) {
$append = $this->appendNode($parentNode, $subData, $key);
}

View File

@ -39,13 +39,27 @@ class CustomNormalizer extends AbstractNormalizer
/**
* Checks if the given class implements the NormalizableInterface.
*
* @param ReflectionClass $class A ReflectionClass instance of the class
* to serialize into or from.
* @param string $format The format being (de-)serialized from or into.
* @param mixed $data Data to normalize.
* @param string $format The format being (de-)serialized from or into.
* @return Boolean
*/
public function supports(\ReflectionClass $class, $format = null)
public function supportsNormalization($data, $format = null)
{
return $class->implementsInterface('Symfony\Component\Serializer\Normalizer\NormalizableInterface');
return $data instanceof NormalizableInterface;
}
/**
* Checks if the given class implements the NormalizableInterface.
*
* @param mixed $data Data to denormalize from.
* @param string $type The class to which the data should be denormalized.
* @param string $format The format being deserialized from.
* @return Boolean
*/
public function supportsDenormalization($data, $type, $format = null)
{
$class = new \ReflectionClass($type);
return $class->isSubclassOf('Symfony\Component\Serializer\Normalizer\NormalizableInterface');
}
}

View File

@ -107,23 +107,37 @@ class GetSetMethodNormalizer extends AbstractNormalizer
return $object;
}
/**
* {@inheritDoc}
*/
public function supportsNormalization($data, $format = null)
{
return $this->supports(get_class($data));
}
/**
* {@inheritDoc}
*/
public function supportsDenormalization($data, $type, $format = null)
{
return $this->supports($type);
}
/**
* Checks if the given class has any get{Property} method.
*
* @param ReflectionClass $class A ReflectionClass instance of the class
* to serialize into or from.
* @param string $format The format being (de-)serialized from or into.
* @return Boolean Whether the class has any getters.
* @param string $class
* @return Boolean
*/
public function supports(\ReflectionClass $class, $format = null)
private function supports($class)
{
$class = new \ReflectionClass($class);
$methods = $class->getMethods(\ReflectionMethod::IS_PUBLIC);
foreach ($methods as $method) {
if ($this->isGetMethod($method)) {
return true;
}
}
return false;
}

View File

@ -14,7 +14,7 @@ use Symfony\Component\Serializer\SerializerInterface;
*/
/**
* Defines the interface of serializers
* Defines the interface of normalizers.
*
* @author Jordi Boggiano <j.boggiano@seld.be>
*/
@ -43,16 +43,25 @@ interface NormalizerInterface
function denormalize($data, $class, $format = null);
/**
* Checks whether the given class is supported by this normalizer
*
* @param ReflectionClass $class
* @param string $format format the given data was extracted from
* Checks whether the given class is supported for normalization by this normalizer
*
* @param mixed $data Data to normalize.
* @param string $format The format being (de-)serialized from or into.
* @return Boolean
*
* @api
*/
function supports(\ReflectionClass $class, $format = null);
function supportsNormalization($data, $format = null);
/**
* Checks whether the given class is supported for denormalization by this normalizer
*
* @param mixed $data Data to denormalize from.
* @param string $type The class to which the data should be denormalized.
* @param string $format The format being deserialized from.
* @return Boolean
* @api
*/
function supportsDenormalization($data, $type, $format = null);
/**
* Sets the owning Serializer object

View File

@ -31,6 +31,7 @@ class Serializer implements SerializerInterface
private $normalizers = array();
private $encoders = array();
protected $normalizerCache = array();
protected $denormalizerCache = array();
/**
* @param mixed $value value to test
@ -46,7 +47,14 @@ class Serializer implements SerializerInterface
*/
public function serialize($data, $format)
{
return $this->encode($data, $format);
return $this->encode($this->normalize($data, $format), $format);
}
/**
* {@inheritDoc}
*/
public function deserialize($data, $type, $format) {
return $this->denormalize($this->decode($data, $format), $type, $format);
}
/**
@ -61,9 +69,8 @@ class Serializer implements SerializerInterface
if (isset($this->normalizerCache[$class][$format])) {
return $this->normalizerCache[$class][$format]->normalize($object, $format, $properties);
}
$reflClass = new \ReflectionClass($class);
foreach ($this->normalizers as $normalizer) {
if ($normalizer->supports($reflClass, $format)) {
if ($normalizer->supportsNormalization($object, $class, $format)) {
$this->normalizerCache[$class][$format] = $normalizer;
return $normalizer->normalize($object, $format, $properties);
}
@ -79,13 +86,12 @@ class Serializer implements SerializerInterface
if (!$this->normalizers) {
throw new \LogicException('You must register at least one normalizer to be able to denormalize objects.');
}
if (isset($this->normalizerCache[$class][$format])) {
return $this->normalizerCache[$class][$format]->denormalize($data, $class, $format);
if (isset($this->denormalizerCache[$class][$format])) {
return $this->denormalizerCache[$class][$format]->denormalize($data, $class, $format);
}
$reflClass = new \ReflectionClass($class);
foreach ($this->normalizers as $normalizer) {
if ($normalizer->supports($reflClass, $format)) {
$this->normalizerCache[$class][$format] = $normalizer;
if ($normalizer->supportsDenormalization($class, $format)) {
$this->denormalizerCache[$class][$format] = $normalizer;
return $normalizer->denormalize($data, $class, $format);
}
}
@ -95,20 +101,38 @@ class Serializer implements SerializerInterface
/**
* {@inheritdoc}
*/
public function normalize($data, $format)
public function normalize($data, $format = null)
{
if (is_array($data)) {
foreach ($data as $key => $val) {
$data[$key] = $this->isStructuredType($val) ? $this->normalize($val, $format) : $val;
}
if (!$this->isStructuredType($data)) {
return $data;
}
if ($data instanceof Traversable) {
$normalized = array();
foreach ($data as $key => $val) {
$normalized[$key] = $this->normalize($val, $format);
}
return $normalized;
}
if (is_object($data)) {
return $this->normalizeObject($data, $format);
}
if (is_array($data)) {
foreach ($data as $key => $val) {
$data[$key] = $this->normalize($val, $format);
}
return $data;
}
throw new \UnexpectedValueException('An unexpected value could not be normalized: '.var_export($data, true));
}
/**
* {@inheritDoc}
*/
public function denormalize($data, $type, $format = null)
{
return $this->denormalizeObject($data, $type, $format);
}
/**
* {@inheritdoc}
*/

View File

@ -31,6 +31,15 @@ interface SerializerInterface
*/
function serialize($data, $format);
/**
* Deserializes data into the given type.
*
* @param mixed $data
* @param string $type
* @param string $format
*/
function deserialize($data, $type, $format);
/**
* Normalizes any data into a set of arrays/scalars
*
@ -39,27 +48,18 @@ interface SerializerInterface
* @return array|scalar
* @api
*/
function normalize($data, $format);
function normalize($data, $format = null);
/**
* Normalizes an object into a set of arrays/scalars
* Denormalizes data into the given type.
*
* @param object $object object to normalize
* @param string $format format name, present to give the option to normalizers to act differently based on formats
* @param array $properties a list of properties to extract, if null all properties are returned
* @return array|scalar
*/
function normalizeObject($object, $format, $properties = null);
/**
* Denormalizes data back into an object of the given class
* @param mixed $data
* @param string $type
* @param string $format
*
* @param mixed $data data to restore
* @param string $class the expected class to instantiate
* @param string $format format name, present to give the option to normalizers to act differently based on formats
* @return object
* @return mixed
*/
function denormalizeObject($data, $class, $format = null);
function denormalize($data, $type, $format = null);
/**
* Encodes data into the given format
@ -80,48 +80,4 @@ interface SerializerInterface
* @api
*/
function decode($data, $format);
/**
* @param NormalizerInterface $normalizer
*/
function addNormalizer(NormalizerInterface $normalizer);
/**
* @return array[]NormalizerInterface
*/
function getNormalizers();
/**
* @param NormalizerInterface $normalizer
*/
function removeNormalizer(NormalizerInterface $normalizer);
/**
* @param string $format format name
* @param EncoderInterface $encoder
*/
function setEncoder($format, EncoderInterface $encoder);
/**
* @return EncoderInterface
*/
function getEncoders();
/**
* @return array[]EncoderInterface
*/
function getEncoder($format);
/**
* Checks whether the serializer has an encoder registered for the given format
*
* @param string $format format name
* @return Boolean
*/
function hasEncoder($format);
/**
* @param string $format format name
*/
function removeEncoder($format);
}

View File

@ -28,7 +28,7 @@ class CountryValidator extends ConstraintValidator
return true;
}
if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString()'))) {
if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
throw new UnexpectedTypeException($value, 'string');
}

View File

@ -29,7 +29,7 @@ class DateTimeValidator extends ConstraintValidator
return true;
}
if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString()'))) {
if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
throw new UnexpectedTypeException($value, 'string');
}

View File

@ -25,7 +25,7 @@ class DateValidator extends ConstraintValidator
return true;
}
if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString()'))) {
if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
throw new UnexpectedTypeException($value, 'string');
}

View File

@ -24,7 +24,7 @@ class EmailValidator extends ConstraintValidator
return true;
}
if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString()'))) {
if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
throw new UnexpectedTypeException($value, 'string');
}

View File

@ -25,7 +25,7 @@ class FileValidator extends ConstraintValidator
return true;
}
if (!is_scalar($value) && !$value instanceof FileObject && !(is_object($value) && method_exists($value, '__toString()'))) {
if (!is_scalar($value) && !$value instanceof FileObject && !(is_object($value) && method_exists($value, '__toString'))) {
throw new UnexpectedTypeException($value, 'string');
}

View File

@ -31,7 +31,7 @@ class IpValidator extends ConstraintValidator
return true;
}
if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString()'))) {
if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
throw new UnexpectedTypeException($value, 'string');
}

View File

@ -28,7 +28,7 @@ class LanguageValidator extends ConstraintValidator
return true;
}
if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString()'))) {
if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
throw new UnexpectedTypeException($value, 'string');
}

View File

@ -28,7 +28,7 @@ class LocaleValidator extends ConstraintValidator
return true;
}
if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString()'))) {
if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
throw new UnexpectedTypeException($value, 'string');
}

View File

@ -23,7 +23,7 @@ class MaxLengthValidator extends ConstraintValidator
return true;
}
if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString()'))) {
if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
throw new UnexpectedTypeException($value, 'string');
}

View File

@ -23,7 +23,7 @@ class MinLengthValidator extends ConstraintValidator
return true;
}
if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString()'))) {
if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
throw new UnexpectedTypeException($value, 'string');
}

View File

@ -23,7 +23,7 @@ class RegexValidator extends ConstraintValidator
return true;
}
if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString()'))) {
if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
throw new UnexpectedTypeException($value, 'string');
}

View File

@ -25,7 +25,7 @@ class TimeValidator extends ConstraintValidator
return true;
}
if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString()'))) {
if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
throw new UnexpectedTypeException($value, 'string');
}

View File

@ -38,7 +38,7 @@ class UrlValidator extends ConstraintValidator
return true;
}
if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString()'))) {
if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
throw new UnexpectedTypeException($value, 'string');
}

View File

@ -62,6 +62,11 @@ class CrawlerTest extends \PHPUnit_Framework_TestCase
$crawler->addHtmlContent('<html><div class="foo"></html>', 'UTF-8');
$this->assertEquals('foo', $crawler->filter('div')->attr('class'), '->addHtmlContent() adds nodes from an HTML string');
$crawler->addHtmlContent('<html><head><base href="http://symfony.com"></head><a href="/contact"></a></html>', 'UTF-8');
$this->assertEquals('http://symfony.com', $crawler->filter('base')->attr('href'), '->addHtmlContent() adds nodes from an HTML string');
$this->assertEquals('http://symfony.com/contact', $crawler->filter('a')->link()->getUri(), '->addHtmlContent() adds nodes from an HTML string');
}
/**

View File

@ -147,6 +147,7 @@ class EventDispatcherTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($this->dispatcher->hasListeners(self::preBar));
$this->dispatcher->removeListener(array('preBar'), $this->listener);
$this->assertFalse($this->dispatcher->hasListeners(self::preBar));
$this->dispatcher->removeListener(array('notExists'), $this->listener);
}
public function testAddSubscriber()

View File

@ -158,12 +158,18 @@ class StubNumberFormatterTest extends LocaleTestCase
array(-100, 'JPY', '(¥100)'),
array(1000.12, 'JPY', '¥1,000'),
array(100, 'EUR', '€100.00'),
array(-100, 'EUR', '(€100.00)'),
array(1000.12, 'EUR', '€1,000.12'),
// Rounding checks
array(1000.121, 'BRL', 'R$1,000.12'),
array(1000.123, 'BRL', 'R$1,000.12'),
array(1000.125, 'BRL', 'R$1,000.12'),
array(1000.127, 'BRL', 'R$1,000.13'),
array(1000.129, 'BRL', 'R$1,000.13'),
array(11.50999, 'BRL', 'R$11.51'),
array(11.9999464, 'BRL', 'R$12.00')
);
}
@ -200,13 +206,19 @@ class StubNumberFormatterTest extends LocaleTestCase
array(100, 'CHF', $chf, '%s100.00'),
array(-100, 'CHF', $chf, '(%s100.00)'),
array(1000.12, 'CHF', $chf, '%s1,000.10'),
array('1000.12', 'CHF', $chf, '%s1,000.10'),
// Rounding checks
array(1000.121, 'CHF', $chf, '%s1,000.10'),
array(1000.123, 'CHF', $chf, '%s1,000.10'),
array(1000.125, 'CHF', $chf, '%s1,000.10'),
array(1000.127, 'CHF', $chf, '%s1,000.15'),
array(1000.129, 'CHF', $chf, '%s1,000.15')
array(1000.129, 'CHF', $chf, '%s1,000.15'),
array(1200000.00, 'CHF', $chf, '%s1,200,000.00'),
array(1200000.1, 'CHF', $chf, '%s1,200,000.10'),
array(1200000.10, 'CHF', $chf, '%s1,200,000.10'),
array(1200000.101, 'CHF', $chf, '%s1,200,000.10')
);
}
@ -356,6 +368,12 @@ class StubNumberFormatterTest extends LocaleTestCase
$formatter->format(1, StubNumberFormatter::TYPE_CURRENCY);
}
public function testFormatTypeCurrencyReturnStub()
{
$formatter = $this->getStubFormatterWithDecimalStyle();
$this->assertFalse(@$formatter->format(1, StubNumberFormatter::TYPE_CURRENCY));
}
/**
* @dataProvider formatTypeCurrencyProvider
* @expectedException PHPUnit_Framework_Error_Warning

View File

@ -44,9 +44,15 @@ class CustomNormalizerTest extends \PHPUnit_Framework_TestCase
$this->assertNull($obj->xmlFoo);
}
public function testSupports()
public function testSupportsNormalization()
{
$this->assertTrue($this->normalizer->supports(new \ReflectionClass(get_class(new ScalarDummy))));
$this->assertFalse($this->normalizer->supports(new \ReflectionClass('stdClass')));
$this->assertTrue($this->normalizer->supportsNormalization(new ScalarDummy));
$this->assertFalse($this->normalizer->supportsNormalization(new \stdClass));
}
public function testSupportsDenormalization()
{
$this->assertTrue($this->normalizer->supportsDenormalization(array(), 'Symfony\Tests\Component\Serializer\Fixtures\ScalarDummy'));
$this->assertFalse($this->normalizer->supportsDenormalization(array(), 'stdClass'));
}
}

View File

@ -29,7 +29,8 @@ class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase
$obj->setBar('bar');
$this->assertEquals(
array('foo' => 'foo', 'bar' => 'bar', 'foobar' => 'foobar'),
$this->normalizer->normalize($obj, 'any'));
$this->normalizer->normalize($obj, 'any')
);
}
public function testNormalizeRestricted()
@ -39,14 +40,17 @@ class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase
$obj->setBar('bar');
$this->assertEquals(
array('foo' => 'foo'),
$this->normalizer->normalize($obj, 'any', array('foo')));
$this->normalizer->normalize($obj, 'any', array('foo'))
);
}
public function testDenormalize()
{
$obj = $this->normalizer->denormalize(
array('foo' => 'foo', 'bar' => 'bar', 'foobar' => 'foobar'),
__NAMESPACE__.'\GetSetDummy', 'any');
__NAMESPACE__.'\GetSetDummy',
'any'
);
$this->assertEquals('foo', $obj->getFoo());
$this->assertEquals('bar', $obj->getBar());
}

View File

@ -37,4 +37,14 @@ class CsvFileLoaderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('en', $catalogue->getLocale());
$this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
}
/**
* @expectedException \InvalidArgumentException
*/
public function testLoadThrowsAnExceptionIfFileNotExists()
{
$loader = new CsvFileLoader();
$resource = __DIR__.'/../fixtures/not-exists.csv';
$loader->load($resource, 'en', 'domain1');
}
}

View File

@ -1 +1,4 @@
"foo"; "bar"
"foo"; "bar"
#"bar"; "foo"
"incorrect"; "number"; "columns"; "will"; "be"; "ignored"
"incorrect"
Can't render this file because it contains an unexpected character in line 2 and column 2.

View File

@ -78,6 +78,11 @@ class ConstraintTest extends \PHPUnit_Framework_TestCase
new ConstraintC();
}
public function testRequiredOptionsPassed()
{
new ConstraintC(array('option1' => 'default'));
}
public function testGroupsAreConvertedToArray()
{
$constraint = new ConstraintA(array('groups' => 'Foo'));

View File

@ -0,0 +1,102 @@
<?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\Tests\Component\Validator;
use Symfony\Component\Validator\ExecutionContext;
class ExecutionContextTest extends \PHPUnit_Framework_TestCase
{
protected $walker;
protected $metadataFactory;
protected $context;
protected function setUp()
{
$this->walker = $this->getMock('Symfony\Component\Validator\GraphWalker', array(), array(), '', false);
$this->metadataFactory = $this->getMock('Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface');
$this->context = new ExecutionContext('Root', $this->walker, $this->metadataFactory);
}
public function testClone()
{
$clone = clone $this->context;
$this->assertNotSame($this->context, $clone);
}
public function testAddViolation()
{
$this->assertEquals(0, count($this->context->getViolations()));
$this->context->addViolation('', array(), '');
$this->assertEquals(1, count($this->context->getViolations()));
}
public function testGetViolations()
{
$this->context->addViolation('', array(), '');
$this->assertEquals(1, count($this->context->getViolations()));
$this->assertInstanceOf('Symfony\Component\Validator\ConstraintViolationList', $this->context->getViolations());
}
public function testGetRoot()
{
$this->assertEquals('Root', $this->context->getRoot());
}
public function testSetGetPropertyPath()
{
$this->context->setPropertyPath('property_path');
$this->assertEquals('property_path', $this->context->getPropertyPath());
}
public function testSetGetCurrentClass()
{
$this->context->setCurrentClass('current_class');
$this->assertEquals('current_class', $this->context->getCurrentClass());
}
public function testSetGetCurrentProperty()
{
$this->context->setCurrentProperty('current_property');
$this->assertEquals('current_property', $this->context->getCurrentProperty());
}
public function testSetGetGroup()
{
$this->context->setGroup('group');
$this->assertEquals('group', $this->context->getGroup());
}
public function testGetGraphWalker()
{
$this->assertSame($this->walker, $this->context->getGraphWalker());
$this->assertInstanceOf(
'Symfony\Component\Validator\GraphWalker',
$this->context->getGraphWalker()
);
}
public function testGetMetadataFactory()
{
$this->assertSame($this->metadataFactory, $this->context->getMetadataFactory());
$this->assertInstanceOf(
'Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface',
$this->context->getMetadataFactory()
);
}
}

View File

@ -146,4 +146,12 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(1, count($result));
}
public function testGetMetadataFactory()
{
$this->assertInstanceOf(
'Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface',
$this->validator->getMetadataFactory()
);
}
}