diff --git a/UPDATE.ja.md b/UPDATE.ja.md index cd5ab856c2..286250835a 100644 --- a/UPDATE.ja.md +++ b/UPDATE.ja.md @@ -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 --------------- diff --git a/UPDATE.md b/UPDATE.md index ade5b3b6f3..a80ec2a361 100644 --- a/UPDATE.md +++ b/UPDATE.md @@ -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 twig twig.extension.debug -* 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). diff --git a/src/Symfony/Bundle/MonologBundle/Logger/DebugHandler.php b/src/Symfony/Bridge/Monolog/Handler/DebugHandler.php similarity index 86% rename from src/Symfony/Bundle/MonologBundle/Logger/DebugHandler.php rename to src/Symfony/Bridge/Monolog/Handler/DebugHandler.php index 85b3e13257..44a9e2e7fe 100644 --- a/src/Symfony/Bundle/MonologBundle/Logger/DebugHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/DebugHandler.php @@ -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]); } diff --git a/src/Symfony/Bundle/MonologBundle/Logger/FirePHPHandler.php b/src/Symfony/Bridge/Monolog/Handler/FirePHPHandler.php similarity index 86% rename from src/Symfony/Bundle/MonologBundle/Logger/FirePHPHandler.php rename to src/Symfony/Bridge/Monolog/Handler/FirePHPHandler.php index 743faa6c83..6b67386115 100755 --- a/src/Symfony/Bundle/MonologBundle/Logger/FirePHPHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/FirePHPHandler.php @@ -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(); - } } diff --git a/src/Symfony/Bundle/MonologBundle/Logger/Logger.php b/src/Symfony/Bridge/Monolog/Logger.php similarity index 86% rename from src/Symfony/Bundle/MonologBundle/Logger/Logger.php rename to src/Symfony/Bridge/Monolog/Logger.php index 6d74db904e..23a276cc97 100644 --- a/src/Symfony/Bundle/MonologBundle/Logger/Logger.php +++ b/src/Symfony/Bridge/Monolog/Logger.php @@ -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); - } } diff --git a/src/Symfony/Bundle/AsseticBundle/Command/DumpCommand.php b/src/Symfony/Bundle/AsseticBundle/Command/DumpCommand.php index dc0b28d8ff..98d3bc28de 100644 --- a/src/Symfony/Bundle/AsseticBundle/Command/DumpCommand.php +++ b/src/Symfony/Bundle/AsseticBundle/Command/DumpCommand.php @@ -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('[dir+] '.$dir); if (false === @mkdir($dir, 0777, true)) { diff --git a/src/Symfony/Bundle/AsseticBundle/Tests/Command/DumpCommandTest.php b/src/Symfony/Bundle/AsseticBundle/Tests/Command/DumpCommandTest.php new file mode 100644 index 0000000000..372d5e10c8 --- /dev/null +++ b/src/Symfony/Bundle/AsseticBundle/Tests/Command/DumpCommandTest.php @@ -0,0 +1,165 @@ + + * + * 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')); + } +} diff --git a/src/Symfony/Bundle/DoctrineAbstractBundle/DependencyInjection/AbstractDoctrineExtension.php b/src/Symfony/Bundle/DoctrineAbstractBundle/DependencyInjection/AbstractDoctrineExtension.php index fd828c56f9..d92eb95028 100644 --- a/src/Symfony/Bundle/DoctrineAbstractBundle/DependencyInjection/AbstractDoctrineExtension.php +++ b/src/Symfony/Bundle/DoctrineAbstractBundle/DependencyInjection/AbstractDoctrineExtension.php @@ -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(); } diff --git a/src/Symfony/Bundle/DoctrineBundle/Command/GenerateEntitiesDoctrineCommand.php b/src/Symfony/Bundle/DoctrineBundle/Command/GenerateEntitiesDoctrineCommand.php index 6eb8807ac5..6cae3514c5 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Command/GenerateEntitiesDoctrineCommand.php +++ b/src/Symfony/Bundle/DoctrineBundle/Command/GenerateEntitiesDoctrineCommand.php @@ -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(<<doctrine:generate:entities 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 ./app/console doctrine:generate:entities MyCustomBundle/Entity + +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 --path option: + + ./app/console doctrine:generate:entities Blog/Entity --path=src/ + EOT ); } @@ -69,10 +77,10 @@ EOT if (class_exists($name)) { $output->writeln(sprintf('Generating entity "%s"', $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 "%s"', $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); } diff --git a/src/Symfony/Bundle/DoctrineBundle/Command/GenerateEntityDoctrineCommand.php b/src/Symfony/Bundle/DoctrineBundle/Command/GenerateEntityDoctrineCommand.php index 9ae233b7aa..de029f2c53 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Command/GenerateEntityDoctrineCommand.php +++ b/src/Symfony/Bundle/DoctrineBundle/Command/GenerateEntityDoctrineCommand.php @@ -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(); diff --git a/src/Symfony/Bundle/DoctrineBundle/Command/ImportMappingDoctrineCommand.php b/src/Symfony/Bundle/DoctrineBundle/Command/ImportMappingDoctrineCommand.php index 225c6ecdec..d34f86af05 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Command/ImportMappingDoctrineCommand.php +++ b/src/Symfony/Bundle/DoctrineBundle/Command/ImportMappingDoctrineCommand.php @@ -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 %s', $path)); $code = $exporter->exportClassMetadata($class); diff --git a/src/Symfony/Bundle/DoctrineBundle/DependencyInjection/DoctrineExtension.php b/src/Symfony/Bundle/DoctrineBundle/DependencyInjection/DoctrineExtension.php index f3856b214d..9b9825cab5 100755 --- a/src/Symfony/Bundle/DoctrineBundle/DependencyInjection/DoctrineExtension.php +++ b/src/Symfony/Bundle/DoctrineBundle/DependencyInjection/DoctrineExtension.php @@ -318,6 +318,11 @@ class DoctrineExtension extends AbstractDoctrineExtension return 'Resources/config/doctrine'; } + protected function getMappingResourceExtension() + { + return 'orm'; + } + /** * Loads a configured entity managers cache drivers. * diff --git a/src/Symfony/Bundle/DoctrineBundle/Mapping/Driver/XmlDriver.php b/src/Symfony/Bundle/DoctrineBundle/Mapping/Driver/XmlDriver.php index 6fa65c24e5..3981aec03b 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Mapping/Driver/XmlDriver.php +++ b/src/Symfony/Bundle/DoctrineBundle/Mapping/Driver/XmlDriver.php @@ -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) { diff --git a/src/Symfony/Bundle/DoctrineBundle/Mapping/Driver/YamlDriver.php b/src/Symfony/Bundle/DoctrineBundle/Mapping/Driver/YamlDriver.php index 285298af21..6f89166e9b 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Mapping/Driver/YamlDriver.php +++ b/src/Symfony/Bundle/DoctrineBundle/Mapping/Driver/YamlDriver.php @@ -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) { diff --git a/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/XmlBundle/Resources/config/doctrine/Fixtures.Bundles.XmlBundle.Entity.Test.orm.dcm.xml b/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/XmlBundle/Resources/config/doctrine/Fixtures.Bundles.XmlBundle.Entity.Test.orm.xml similarity index 100% rename from src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/XmlBundle/Resources/config/doctrine/Fixtures.Bundles.XmlBundle.Entity.Test.orm.dcm.xml rename to src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/XmlBundle/Resources/config/doctrine/Fixtures.Bundles.XmlBundle.Entity.Test.orm.xml diff --git a/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/YamlBundle/Resources/config/doctrine/Fixtures.Bundles.YamlBundle.Entity.Test.orm.dcm.yml b/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/YamlBundle/Resources/config/doctrine/Fixtures.Bundles.YamlBundle.Entity.Test.orm.yml similarity index 100% rename from src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/YamlBundle/Resources/config/doctrine/Fixtures.Bundles.YamlBundle.Entity.Test.orm.dcm.yml rename to src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/YamlBundle/Resources/config/doctrine/Fixtures.Bundles.YamlBundle.Entity.Test.orm.yml diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/profiling.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/profiling.xml index 9dcaaa401d..541b19430f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/profiling.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/profiling.xml @@ -24,7 +24,7 @@ - + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/layout.html.twig b/src/Symfony/Bundle/FrameworkBundle/Resources/views/layout.html.twig index dc1d4e1ada..74308a5fa3 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/layout.html.twig +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/layout.html.twig @@ -2,6 +2,7 @@ + {% block title '' %} diff --git a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php index 87049b616a..7bbe983c26 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php +++ b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php @@ -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); diff --git a/src/Symfony/Bundle/MonologBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/MonologBundle/DependencyInjection/Configuration.php index a6c76a77a2..f3c8698dbf 100644 --- a/src/Symfony/Bundle/MonologBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/MonologBundle/DependencyInjection/Configuration.php @@ -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') diff --git a/src/Symfony/Bundle/MonologBundle/DependencyInjection/MonologExtension.php b/src/Symfony/Bundle/MonologBundle/DependencyInjection/MonologExtension.php index 8e1cdff9b7..09bf0ca52d 100644 --- a/src/Symfony/Bundle/MonologBundle/DependencyInjection/MonologExtension.php +++ b/src/Symfony/Bundle/MonologBundle/DependencyInjection/MonologExtension.php @@ -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; + } } diff --git a/src/Symfony/Bundle/MonologBundle/Resources/config/monolog.xml b/src/Symfony/Bundle/MonologBundle/Resources/config/monolog.xml index 28e9df73da..979828b4c6 100644 --- a/src/Symfony/Bundle/MonologBundle/Resources/config/monolog.xml +++ b/src/Symfony/Bundle/MonologBundle/Resources/config/monolog.xml @@ -5,7 +5,7 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - Symfony\Bundle\MonologBundle\Logger\Logger + Symfony\Bridge\Monolog\Logger Monolog\Handler\StreamHandler Monolog\Handler\FingersCrossedHandler Monolog\Handler\BufferHandler @@ -13,8 +13,10 @@ Monolog\Handler\SyslogHandler Monolog\Handler\NullHandler Monolog\Handler\TestHandler - Symfony\Bundle\MonologBundle\Logger\FirePHPHandler - Symfony\Bundle\MonologBundle\Logger\DebugHandler + Symfony\Bridge\Monolog\Handler\FirePHPHandler + Symfony\Bridge\Monolog\Handler\DebugHandler + Monolog\Handler\SwiftMailerHandler + Monolog\Handler\NativeMailerHandler diff --git a/src/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/MonologExtensionTest.php b/src/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/MonologExtensionTest.php index 1cecce1378..b48dc8dd9e 100644 --- a/src/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/MonologExtensionTest.php +++ b/src/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/MonologExtensionTest.php @@ -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 */ diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base.html.twig index 47cb4967a5..a3dc3423ed 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base.html.twig @@ -2,6 +2,7 @@ + {% block title 'Profiler' %} {% block head %} diff --git a/src/Symfony/Component/Config/Definition/ArrayNode.php b/src/Symfony/Component/Config/Definition/ArrayNode.php index 67d76d5e0f..85a45faa5c 100644 --- a/src/Symfony/Component/Config/Definition/ArrayNode.php +++ b/src/Symfony/Component/Config/Definition/ArrayNode.php @@ -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; diff --git a/src/Symfony/Component/Config/Definition/BooleanNode.php b/src/Symfony/Component/Config/Definition/BooleanNode.php index 9ca59661e3..45f1ad3429 100644 --- a/src/Symfony/Component/Config/Definition/BooleanNode.php +++ b/src/Symfony/Component/Config/Definition/BooleanNode.php @@ -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; } } } \ No newline at end of file diff --git a/src/Symfony/Component/Config/Definition/Exception/InvalidConfigurationException.php b/src/Symfony/Component/Config/Definition/Exception/InvalidConfigurationException.php index b46543dcd6..ea6a4305b9 100644 --- a/src/Symfony/Component/Config/Definition/Exception/InvalidConfigurationException.php +++ b/src/Symfony/Component/Config/Definition/Exception/InvalidConfigurationException.php @@ -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; + } } \ No newline at end of file diff --git a/src/Symfony/Component/Config/Definition/PrototypedArrayNode.php b/src/Symfony/Component/Config/Definition/PrototypedArrayNode.php index ff68c092b5..713cf4b789 100644 --- a/src/Symfony/Component/Config/Definition/PrototypedArrayNode.php +++ b/src/Symfony/Component/Config/Definition/PrototypedArrayNode.php @@ -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; diff --git a/src/Symfony/Component/Config/Definition/ScalarNode.php b/src/Symfony/Component/Config/Definition/ScalarNode.php index 0814788229..eb975e0fad 100644 --- a/src/Symfony/Component/Config/Definition/ScalarNode.php +++ b/src/Symfony/Component/Config/Definition/ScalarNode.php @@ -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; } } } \ No newline at end of file diff --git a/src/Symfony/Component/Config/Definition/VariableNode.php b/src/Symfony/Component/Config/Definition/VariableNode.php index 7f597c881f..22f254ad07 100644 --- a/src/Symfony/Component/Config/Definition/VariableNode.php +++ b/src/Symfony/Component/Config/Definition/VariableNode.php @@ -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; diff --git a/src/Symfony/Component/Finder/Iterator/SortableIterator.php b/src/Symfony/Component/Finder/Iterator/SortableIterator.php index fd3748a370..14c3428009 100644 --- a/src/Symfony/Component/Finder/Iterator/SortableIterator.php +++ b/src/Symfony/Component/Finder/Iterator/SortableIterator.php @@ -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); } } diff --git a/src/Symfony/Component/Form/Extension/Core/CoreExtension.php b/src/Symfony/Component/Form/Extension/Core/CoreExtension.php index 748e86d6f7..b078379cd3 100644 --- a/src/Symfony/Component/Form/Extension/Core/CoreExtension.php +++ b/src/Symfony/Component/Form/Extension/Core/CoreExtension.php @@ -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; /** diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/ArrayToBooleanChoicesTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/ArrayToBooleanChoicesTransformer.php index 0c23086d16..9bbeee1b19 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/ArrayToBooleanChoicesTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/ArrayToBooleanChoicesTransformer.php @@ -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 diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/ArrayToChoicesTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/ArrayToChoicesTransformer.php index d79b2e44e2..94815d0a4a 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/ArrayToChoicesTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/ArrayToChoicesTransformer.php @@ -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 diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/BooleanToStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/BooleanToStringTransformer.php index 384c05f454..e349db62b3 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/BooleanToStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/BooleanToStringTransformer.php @@ -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; /** diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/FileToStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/FileToStringTransformer.php index 6bce7fca2e..e84f684b35 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/FileToStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/FileToStringTransformer.php @@ -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; diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/ScalarToBooleanChoicesTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/ScalarToBooleanChoicesTransformer.php index 57e15343df..3faa151f7d 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/ScalarToBooleanChoicesTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/ScalarToBooleanChoicesTransformer.php @@ -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 diff --git a/src/Symfony/Component/Form/Extension/Core/EventListener/FixFileUploadListener.php b/src/Symfony/Component/Form/Extension/Core/EventListener/FixFileUploadListener.php index 7c0b2f83d7..0fba50493a 100644 --- a/src/Symfony/Component/Form/Extension/Core/EventListener/FixFileUploadListener.php +++ b/src/Symfony/Component/Form/Extension/Core/EventListener/FixFileUploadListener.php @@ -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; diff --git a/src/Symfony/Component/Form/Extension/Core/Type/BirthdayType.php b/src/Symfony/Component/Form/Extension/Core/Type/BirthdayType.php index 06716d501b..ecf3e3532a 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/BirthdayType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/BirthdayType.php @@ -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 { diff --git a/src/Symfony/Component/Form/Extension/Core/Type/CountryType.php b/src/Symfony/Component/Form/Extension/Core/Type/CountryType.php index e79fed0ee6..2d4f87af3a 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/CountryType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/CountryType.php @@ -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 diff --git a/src/Symfony/Component/Form/Extension/Core/Type/EmailType.php b/src/Symfony/Component/Form/Extension/Core/Type/EmailType.php index 02bfde4d8e..1902af1814 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/EmailType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/EmailType.php @@ -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 { diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FieldType.php b/src/Symfony/Component/Form/Extension/Core/Type/FieldType.php index 0f9bc67423..963c9e2764 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FieldType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FieldType.php @@ -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 { diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php index 189eedd5a9..6595072ecc 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php @@ -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; diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FormType.php b/src/Symfony/Component/Form/Extension/Core/Type/FormType.php index f11b551660..786bd5855a 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FormType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FormType.php @@ -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 { diff --git a/src/Symfony/Component/Form/Extension/Core/Type/HiddenType.php b/src/Symfony/Component/Form/Extension/Core/Type/HiddenType.php index 427364584b..abce35042e 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/HiddenType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/HiddenType.php @@ -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 { diff --git a/src/Symfony/Component/Form/Extension/Core/Type/TextType.php b/src/Symfony/Component/Form/Extension/Core/Type/TextType.php index 98d2e9c38f..a0e56facbc 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/TextType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/TextType.php @@ -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 { diff --git a/src/Symfony/Component/Form/Extension/Core/Type/TextareaType.php b/src/Symfony/Component/Form/Extension/Core/Type/TextareaType.php index a3b585cc6d..fb6cee653b 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/TextareaType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/TextareaType.php @@ -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 { diff --git a/src/Symfony/Component/Form/Extension/Core/Type/TimezoneType.php b/src/Symfony/Component/Form/Extension/Core/Type/TimezoneType.php index 8f891340cc..53d92a33f0 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/TimezoneType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/TimezoneType.php @@ -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 diff --git a/src/Symfony/Component/Form/Form.php b/src/Symfony/Component/Form/Form.php index 7aa000bdaa..c56bedf6ed 100644 --- a/src/Symfony/Component/Form/Form.php +++ b/src/Symfony/Component/Form/Form.php @@ -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. diff --git a/src/Symfony/Component/Form/FormFactory.php b/src/Symfony/Component/Form/FormFactory.php index 8af465808c..30474a8f83 100644 --- a/src/Symfony/Component/Form/FormFactory.php +++ b/src/Symfony/Component/Form/FormFactory.php @@ -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; diff --git a/src/Symfony/Component/Security/Acl/Dbal/AclProvider.php b/src/Symfony/Component/Security/Acl/Dbal/AclProvider.php index 956fdd77f8..143dee6a4c 100644 --- a/src/Symfony/Component/Security/Acl/Dbal/AclProvider.php +++ b/src/Symfony/Component/Security/Acl/Dbal/AclProvider.php @@ -251,9 +251,10 @@ SELECTCLAUSE; { $sql = <<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; diff --git a/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php b/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php index 13da7c0ec7..2e6dd1df8c 100644 --- a/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php +++ b/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php @@ -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 01 - * From array("item" => array(0,1)); - */ + * Create nodes to append to $parentNode based on the $key of this array + * Produces 01 + * From array("item" => array(0,1)); + */ foreach ($data as $subData) { $append = $this->appendNode($parentNode, $subData, $key); } diff --git a/src/Symfony/Component/Serializer/Normalizer/CustomNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/CustomNormalizer.php index ecbf5f061e..1f1c6a0504 100644 --- a/src/Symfony/Component/Serializer/Normalizer/CustomNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/CustomNormalizer.php @@ -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'); } } diff --git a/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php index b4bf69e3df..3d61c14ad8 100644 --- a/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php @@ -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; } diff --git a/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php b/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php index 9a33861084..2350db7293 100644 --- a/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php +++ b/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php @@ -14,7 +14,7 @@ use Symfony\Component\Serializer\SerializerInterface; */ /** - * Defines the interface of serializers + * Defines the interface of normalizers. * * @author Jordi Boggiano */ @@ -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 diff --git a/src/Symfony/Component/Serializer/Serializer.php b/src/Symfony/Component/Serializer/Serializer.php index f7f012c110..123fd7f4b0 100644 --- a/src/Symfony/Component/Serializer/Serializer.php +++ b/src/Symfony/Component/Serializer/Serializer.php @@ -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} */ diff --git a/src/Symfony/Component/Serializer/SerializerInterface.php b/src/Symfony/Component/Serializer/SerializerInterface.php index 7f557221c5..262e06a893 100644 --- a/src/Symfony/Component/Serializer/SerializerInterface.php +++ b/src/Symfony/Component/Serializer/SerializerInterface.php @@ -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); } diff --git a/src/Symfony/Component/Validator/Constraints/CountryValidator.php b/src/Symfony/Component/Validator/Constraints/CountryValidator.php index f551f49027..9946344e10 100644 --- a/src/Symfony/Component/Validator/Constraints/CountryValidator.php +++ b/src/Symfony/Component/Validator/Constraints/CountryValidator.php @@ -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'); } diff --git a/src/Symfony/Component/Validator/Constraints/DateTimeValidator.php b/src/Symfony/Component/Validator/Constraints/DateTimeValidator.php index 8d86d40215..6114019563 100644 --- a/src/Symfony/Component/Validator/Constraints/DateTimeValidator.php +++ b/src/Symfony/Component/Validator/Constraints/DateTimeValidator.php @@ -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'); } diff --git a/src/Symfony/Component/Validator/Constraints/DateValidator.php b/src/Symfony/Component/Validator/Constraints/DateValidator.php index da437dbfdf..77cbb14ce5 100644 --- a/src/Symfony/Component/Validator/Constraints/DateValidator.php +++ b/src/Symfony/Component/Validator/Constraints/DateValidator.php @@ -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'); } diff --git a/src/Symfony/Component/Validator/Constraints/EmailValidator.php b/src/Symfony/Component/Validator/Constraints/EmailValidator.php index 3cbaa5a909..780272f94e 100644 --- a/src/Symfony/Component/Validator/Constraints/EmailValidator.php +++ b/src/Symfony/Component/Validator/Constraints/EmailValidator.php @@ -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'); } diff --git a/src/Symfony/Component/Validator/Constraints/FileValidator.php b/src/Symfony/Component/Validator/Constraints/FileValidator.php index d6c7a3bd42..ba2ee30eae 100644 --- a/src/Symfony/Component/Validator/Constraints/FileValidator.php +++ b/src/Symfony/Component/Validator/Constraints/FileValidator.php @@ -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'); } diff --git a/src/Symfony/Component/Validator/Constraints/IpValidator.php b/src/Symfony/Component/Validator/Constraints/IpValidator.php index d65b29c26f..e98e4ae302 100644 --- a/src/Symfony/Component/Validator/Constraints/IpValidator.php +++ b/src/Symfony/Component/Validator/Constraints/IpValidator.php @@ -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'); } diff --git a/src/Symfony/Component/Validator/Constraints/LanguageValidator.php b/src/Symfony/Component/Validator/Constraints/LanguageValidator.php index 4a1f1ac77a..f52fdaeff7 100644 --- a/src/Symfony/Component/Validator/Constraints/LanguageValidator.php +++ b/src/Symfony/Component/Validator/Constraints/LanguageValidator.php @@ -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'); } diff --git a/src/Symfony/Component/Validator/Constraints/LocaleValidator.php b/src/Symfony/Component/Validator/Constraints/LocaleValidator.php index 49eab5924b..b7cfaa6c8e 100644 --- a/src/Symfony/Component/Validator/Constraints/LocaleValidator.php +++ b/src/Symfony/Component/Validator/Constraints/LocaleValidator.php @@ -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'); } diff --git a/src/Symfony/Component/Validator/Constraints/MaxLengthValidator.php b/src/Symfony/Component/Validator/Constraints/MaxLengthValidator.php index 6ca764fc48..3b4745dfab 100644 --- a/src/Symfony/Component/Validator/Constraints/MaxLengthValidator.php +++ b/src/Symfony/Component/Validator/Constraints/MaxLengthValidator.php @@ -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'); } diff --git a/src/Symfony/Component/Validator/Constraints/MinLengthValidator.php b/src/Symfony/Component/Validator/Constraints/MinLengthValidator.php index 8c41db074d..97ee6eb619 100644 --- a/src/Symfony/Component/Validator/Constraints/MinLengthValidator.php +++ b/src/Symfony/Component/Validator/Constraints/MinLengthValidator.php @@ -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'); } diff --git a/src/Symfony/Component/Validator/Constraints/RegexValidator.php b/src/Symfony/Component/Validator/Constraints/RegexValidator.php index e63a4d3995..e8eb628f2c 100644 --- a/src/Symfony/Component/Validator/Constraints/RegexValidator.php +++ b/src/Symfony/Component/Validator/Constraints/RegexValidator.php @@ -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'); } diff --git a/src/Symfony/Component/Validator/Constraints/TimeValidator.php b/src/Symfony/Component/Validator/Constraints/TimeValidator.php index 58ced66ee4..dea2556625 100644 --- a/src/Symfony/Component/Validator/Constraints/TimeValidator.php +++ b/src/Symfony/Component/Validator/Constraints/TimeValidator.php @@ -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'); } diff --git a/src/Symfony/Component/Validator/Constraints/UrlValidator.php b/src/Symfony/Component/Validator/Constraints/UrlValidator.php index 2840cbb9f9..f83ed9f2f3 100644 --- a/src/Symfony/Component/Validator/Constraints/UrlValidator.php +++ b/src/Symfony/Component/Validator/Constraints/UrlValidator.php @@ -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'); } diff --git a/tests/Symfony/Tests/Component/DomCrawler/CrawlerTest.php b/tests/Symfony/Tests/Component/DomCrawler/CrawlerTest.php index 2ecff9962e..d825836db7 100644 --- a/tests/Symfony/Tests/Component/DomCrawler/CrawlerTest.php +++ b/tests/Symfony/Tests/Component/DomCrawler/CrawlerTest.php @@ -62,6 +62,11 @@ class CrawlerTest extends \PHPUnit_Framework_TestCase $crawler->addHtmlContent('
', 'UTF-8'); $this->assertEquals('foo', $crawler->filter('div')->attr('class'), '->addHtmlContent() adds nodes from an HTML string'); + + $crawler->addHtmlContent('', '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'); } /** diff --git a/tests/Symfony/Tests/Component/EventDispatcher/EventDispatcherTest.php b/tests/Symfony/Tests/Component/EventDispatcher/EventDispatcherTest.php index eef61fb90e..9abe423ac2 100644 --- a/tests/Symfony/Tests/Component/EventDispatcher/EventDispatcherTest.php +++ b/tests/Symfony/Tests/Component/EventDispatcher/EventDispatcherTest.php @@ -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() diff --git a/tests/Symfony/Tests/Component/Locale/Stub/StubNumberFormatterTest.php b/tests/Symfony/Tests/Component/Locale/Stub/StubNumberFormatterTest.php index 7ec762dce0..5ffc781721 100644 --- a/tests/Symfony/Tests/Component/Locale/Stub/StubNumberFormatterTest.php +++ b/tests/Symfony/Tests/Component/Locale/Stub/StubNumberFormatterTest.php @@ -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 diff --git a/tests/Symfony/Tests/Component/Serializer/Normalizer/CustomNormalizerTest.php b/tests/Symfony/Tests/Component/Serializer/Normalizer/CustomNormalizerTest.php index a441544b4d..4a98954dcc 100644 --- a/tests/Symfony/Tests/Component/Serializer/Normalizer/CustomNormalizerTest.php +++ b/tests/Symfony/Tests/Component/Serializer/Normalizer/CustomNormalizerTest.php @@ -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')); } } diff --git a/tests/Symfony/Tests/Component/Serializer/Normalizer/GetSetMethodNormalizerTest.php b/tests/Symfony/Tests/Component/Serializer/Normalizer/GetSetMethodNormalizerTest.php index 6544075598..2ac0b1c024 100644 --- a/tests/Symfony/Tests/Component/Serializer/Normalizer/GetSetMethodNormalizerTest.php +++ b/tests/Symfony/Tests/Component/Serializer/Normalizer/GetSetMethodNormalizerTest.php @@ -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()); } diff --git a/tests/Symfony/Tests/Component/Translation/Loader/CsvFileLoaderTest.php b/tests/Symfony/Tests/Component/Translation/Loader/CsvFileLoaderTest.php index 9eed61c318..e6724a87f7 100644 --- a/tests/Symfony/Tests/Component/Translation/Loader/CsvFileLoaderTest.php +++ b/tests/Symfony/Tests/Component/Translation/Loader/CsvFileLoaderTest.php @@ -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'); + } } diff --git a/tests/Symfony/Tests/Component/Translation/fixtures/resources.csv b/tests/Symfony/Tests/Component/Translation/fixtures/resources.csv index b6467f0653..374b9eb5eb 100644 --- a/tests/Symfony/Tests/Component/Translation/fixtures/resources.csv +++ b/tests/Symfony/Tests/Component/Translation/fixtures/resources.csv @@ -1 +1,4 @@ -"foo"; "bar" \ No newline at end of file +"foo"; "bar" +#"bar"; "foo" +"incorrect"; "number"; "columns"; "will"; "be"; "ignored" +"incorrect" \ No newline at end of file diff --git a/tests/Symfony/Tests/Component/Validator/ConstraintTest.php b/tests/Symfony/Tests/Component/Validator/ConstraintTest.php index c49e6c2ff5..79ddf95ee5 100644 --- a/tests/Symfony/Tests/Component/Validator/ConstraintTest.php +++ b/tests/Symfony/Tests/Component/Validator/ConstraintTest.php @@ -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')); diff --git a/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php b/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php new file mode 100644 index 0000000000..b2ab95660e --- /dev/null +++ b/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php @@ -0,0 +1,102 @@ + + * + * 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() + ); + } +} \ No newline at end of file diff --git a/tests/Symfony/Tests/Component/Validator/ValidatorTest.php b/tests/Symfony/Tests/Component/Validator/ValidatorTest.php index d48f591f70..ca30cc9848 100644 --- a/tests/Symfony/Tests/Component/Validator/ValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/ValidatorTest.php @@ -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() + ); + } } \ No newline at end of file