diff --git a/UPDATE.ja.md b/UPDATE.ja.md index f62cac80ec..3c4adc6f22 100644 --- a/UPDATE.ja.md +++ b/UPDATE.ja.md @@ -5,6 +5,71 @@ このドキュメントでは、フレームワークの "パブリックな" APIを使っている場合に必要な変更点についてのみ説明しています。 フレームワークのコアコードを "ハック" している場合は、変更履歴を注意深く追跡する必要があるでしょう。 +PR11 to PR12 +------------ + +* HttpFoundation\Cookie::getExpire() は getExpiresTime() に名前が変更されました。 + +* XMLのコンフィギュレーションの記述方法が変更されました。属性が1つしかないタグは、すべてタグのコンテンツとして記述するように変更されました。 + + 変更前: + + + + + + 変更後: + + MyBundle + twig + twig.extension.debug + +* SwitchUserListenerが有効な場合に、すべてのユーザーが任意のアカウントになりすませる致命的な脆弱性を修正しました。SwitchUserListenerを利用しない設定にしている場合は影響はありません。 + +PR10 から PR11 +-------------- + +* エクステンションのコンフィギュレーションクラスには、\ `Symfony\Component\Config\Definition\ConfigurationInterface`\ インターフェイスを実装する必要があります。この部分の後方互換性は維持されていますが、今後の開発のために、エクステンションにこのインターフェイスを実装しておいてください。 + +* Monologのオプション "fingerscrossed" は "fingers_crossed" に名前が変更されました。 + +PR9 から PR10 +------------- + +* バンドルの論理名には、再び `Bundle` サフィックスを付けるように修正されました: + + *コントローラ*: `Blog:Post:show` -> `BlogBundle:Post:show` + + *テンプレート*: `Blog:Post:show.html.twig` -> `BlogBundle:Post:show.html.twig` + + *リソース*: `@Blog/Resources/config/blog.xml` -> `@BlogBundle/Resources/config/blog.xml` + + *Doctrine*: `$em->find('Blog:Post', $id)` -> `$em->find('BlogBundle:Post', $id)` + +* `ZendBundle` は `MonologBundle` に置き換えられました。 + これに関するプロジェクトのアップデート方法は、Symfony Standard Edition の変更点を参考にしてください: + https://github.com/symfony/symfony-standard/pull/30/files + +* コアバンドルのパラメータは、ほぼすべて削除されました。 + 代わりにバンドルのエクステンションの設定で公開されている設定を使うようにしてください。 + +* 一貫性のために、いくつかのコアバンドルのサービス名が変更されました。 + +* バリデータの名前空間が `validation` から `assert` へ変更されました(PR9向けにアナウンスされていましたが、PR10での変更となりました): + + 変更前: + + @validation:NotNull + + 変更後: + + @assert:NotNull + + さらに、いくつかの制約で使われていた `Assert` プレフィックスは削除されました(`AssertTrue` から `True` へ変更) + +* `ApplicationTester::getDisplay()` と `CommandTester::getDisplay()` メソッドは、コマンドの終了コードを返すようになりました + + PR8 から PR9 ------------ @@ -28,13 +93,13 @@ PR8 から PR9 変更前: - profiler: - pattern: /_profiler/.* + pattern: /_profiler.* + pattern: /login 変更後: - profiler: - pattern: ^/_profiler + pattern: ^/_profiler + pattern: ^/login$ * `app/` ディレクトリ以下のグローバルテンプレートの位置が変更されました(古いディレクトリでは動作しなくなります): @@ -48,18 +113,6 @@ PR8 から PR9 app/Resources/views/base.html.twig app/Resources/AcmeDemo/views/base.html.twig -* バリデータの名前空間が `validation` から `assert` へ変更されました: - - 変更前: - - @validation:NotNull - - 変更後: - - @assert:NotNull - - さらに、いくつかの制約で使われていた `Assert` プレフィックスは削除されました(`AssertTrue` から `True` へ変更) - * バンドルの論理名に、`Bundle` サフィックスをつける必要がなくなりました: *コントローラ*: `BlogBundle:Post:show` -> `Blog:Post:show` @@ -69,3 +122,14 @@ PR8 から PR9 *リソース*: `@BlogBundle/Resources/config/blog.xml` -> `@Blog/Resources/config/blog.xml` *Doctrine*: `$em->find('BlogBundle:Post', $id)` -> `$em->find('Blog:Post', $id)` + +* Asseticのフィルターは明示的にロードする必要があります: + + assetic: + filters: + cssrewrite: ~ + yui_css: + jar: "/path/to/yuicompressor.jar" + my_filter: + resource: "%kernel.root_dir%/config/my_filter.xml" + foo: bar diff --git a/UPDATE.md b/UPDATE.md index 138d49f17d..916c669dfd 100644 --- a/UPDATE.md +++ b/UPDATE.md @@ -6,9 +6,100 @@ one. It only discusses changes that need to be done when using the "public" API of the framework. If you "hack" the core, you should probably follow the timeline closely anyway. -PR8 to PR10 +PR12 to beta1 +------------- + +* The `trans` tag does not accept a message as an argument anymore: + + {% trans "foo" %} + {% trans foo %} + + Use the long version the tags or the filter instead: + + {% trans %}foo{% endtrans %} + {{ foo|trans }} + + This has been done to clarify the usage of the tag and filter and also to + make it clearer when the automatic output escaping rules are applied (see + the doc for more information). + +* Some methods in the DependencyInjection component's ContainerBuilder and + Definition classes have been renamed to be more specific and consistent: + + Before: + + $container->remove('my_definition'); + $definition->setArgument(0, 'foo'); + + After: + + $container->removeDefinition('my_definition'); + $definition->replaceArgument(0, 'foo'); + +* In the rememberme configuration, the token_provider key now expects a real + service id instead of only a suffix. + +PR11 to PR12 +------------ + +* HttpFoundation\Cookie::getExpire() was renamed to getExpiresTime() + +* XML configurations have been normalized. All tags with only one attribute + have been converted to tag content: + + Before: + + + + + + After: + + MyBundle + twig + twig.extension.debug + +* 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 + 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). + +PR10 to PR11 +------------ + +* Extension configuration classes should now implement the + `Symfony\Component\Config\Definition\ConfigurationInterface` interface. Note + that the BC is kept but implementing this interface in your extensions will + allow for further developments. + +* The "fingerscrossed" Monolog option has been renamed to "fingers_crossed". + +PR9 to PR10 ----------- +* Bundle logical names earned back their `Bundle` suffix: + + *Controllers*: `Blog:Post:show` -> `BlogBundle:Post:show` + + *Templates*: `Blog:Post:show.html.twig` -> `BlogBundle:Post:show.html.twig` + + *Resources*: `@Blog/Resources/config/blog.xml` -> `@BlogBundle/Resources/config/blog.xml` + + *Doctrine*: `$em->find('Blog:Post', $id)` -> `$em->find('BlogBundle:Post', $id)` + +* `ZendBundle` has been replaced by `MonologBundle`. Have a look at the + changes made to Symfony SE to see how to upgrade your projects: + https://github.com/symfony/symfony-standard/pull/30/files + +* Almost all core bundles parameters have been removed. You should use the + settings exposed by the bundle extension configuration instead. + +* Some core bundles service names changed for better consistency. + * Namespace for validators has changed from `validation` to `assert` (it was announced for PR9 but it was not the case then): @@ -23,6 +114,9 @@ PR8 to PR10 Moreover, the `Assert` prefix used for some constraints has been removed (`AssertTrue` to `True`). +* `ApplicationTester::getDisplay()` and `CommandTester::getDisplay()` method + now return the command exit code + PR8 to PR9 ---------- @@ -47,13 +141,13 @@ PR8 to PR9 Before: - profiler: - pattern: /_profiler/.* + pattern: /_profiler.* + pattern: /login After: - profiler: - pattern: ^/_profiler + pattern: ^/_profiler + pattern: ^/login$ * Global templates under `app/` moved to a new location (old directory did not work anyway): @@ -77,3 +171,14 @@ PR8 to PR9 *Resources*: `@BlogBundle/Resources/config/blog.xml` -> `@Blog/Resources/config/blog.xml` *Doctrine*: `$em->find('BlogBundle:Post', $id)` -> `$em->find('Blog:Post', $id)` + +* Assetic filters must be now explicitly loaded: + + assetic: + filters: + cssrewrite: ~ + yui_css: + jar: "/path/to/yuicompressor.jar" + my_filter: + resource: "%kernel.root_dir%/config/my_filter.xml" + foo: bar diff --git a/autoload.php.dist b/autoload.php.dist index a5d826ba60..5c6f3c4764 100644 --- a/autoload.php.dist +++ b/autoload.php.dist @@ -15,8 +15,8 @@ $loader->registerNamespaces(array( 'Doctrine\\DBAL\\Migrations' => __DIR__.'/vendor/doctrine-migrations/lib', 'Doctrine\\DBAL' => __DIR__.'/vendor/doctrine-dbal/lib', 'Doctrine' => __DIR__.'/vendor/doctrine/lib', - 'Zend' => __DIR__.'/vendor/zend/library', 'Assetic' => __DIR__.'/vendor/assetic/src', + 'Monolog' => __DIR__.'/vendor/monolog/src', )); $loader->registerPrefixes(array( 'Swift_' => __DIR__.'/vendor/swiftmailer/lib/classes', diff --git a/src/Symfony/Bridge/Twig/Extension/TranslationExtension.php b/src/Symfony/Bridge/Twig/Extension/TranslationExtension.php index 7ad1674338..7cc5cc6b78 100644 --- a/src/Symfony/Bridge/Twig/Extension/TranslationExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/TranslationExtension.php @@ -41,6 +41,7 @@ class TranslationExtension extends \Twig_Extension { return array( 'trans' => new \Twig_Filter_Method($this, 'trans'), + 'transchoice' => new \Twig_Filter_Method($this, 'transchoice'), ); } @@ -52,7 +53,7 @@ class TranslationExtension extends \Twig_Extension public function getTokenParsers() { return array( - // {% trans "Symfony is great!" %} + // {% trans %}Symfony is great!{% endtrans %} new TransTokenParser(), // {% transchoice count %} @@ -67,6 +68,11 @@ class TranslationExtension extends \Twig_Extension return $this->translator->trans($message, $arguments, $domain); } + public function transchoice($message, $count, array $arguments = array(), $domain = "messages") + { + return $this->translator->transChoice($message, $count, array_merge(array('%count%' => $count), $arguments), $domain); + } + /** * Returns the name of the extension. * diff --git a/src/Symfony/Bridge/Twig/Node/TransNode.php b/src/Symfony/Bridge/Twig/Node/TransNode.php index 61f2073970..6ee554078c 100644 --- a/src/Symfony/Bridge/Twig/Node/TransNode.php +++ b/src/Symfony/Bridge/Twig/Node/TransNode.php @@ -12,13 +12,13 @@ namespace Symfony\Bridge\Twig\Node; /** - * + * * * @author Fabien Potencier */ class TransNode extends \Twig_Node { - public function __construct(\Twig_NodeInterface $body, \Twig_NodeInterface $domain, \Twig_Node_Expression $count = null, \Twig_Node_Expression $vars = null, $lineno, $tag = null) + public function __construct(\Twig_NodeInterface $body, \Twig_NodeInterface $domain, \Twig_Node_Expression $count = null, \Twig_Node_Expression $vars = null, $lineno = 0, $tag = null) { parent::__construct(array('count' => $count, 'body' => $body, 'domain' => $domain, 'vars' => $vars), array(), $lineno, $tag); } @@ -38,7 +38,6 @@ class TransNode extends \Twig_Node $defaults = $this->getNode('vars'); $vars = null; } - list($msg, $defaults) = $this->compileString($this->getNode('body'), $defaults); $method = null === $this->getNode('count') ? 'trans' : 'transChoice'; diff --git a/src/Symfony/Bridge/Twig/TokenParser/TransChoiceTokenParser.php b/src/Symfony/Bridge/Twig/TokenParser/TransChoiceTokenParser.php index 1a24396c54..351e660ccd 100644 --- a/src/Symfony/Bridge/Twig/TokenParser/TransChoiceTokenParser.php +++ b/src/Symfony/Bridge/Twig/TokenParser/TransChoiceTokenParser.php @@ -14,7 +14,7 @@ namespace Symfony\Bridge\Twig\TokenParser; use Symfony\Bridge\Twig\Node\TransNode; /** - * + * * * @author Fabien Potencier */ @@ -34,10 +34,17 @@ class TransChoiceTokenParser extends TransTokenParser $vars = new \Twig_Node_Expression_Array(array(), $lineno); + $body = null; $count = $this->parser->getExpressionParser()->parseExpression(); - $domain = new \Twig_Node_Expression_Constant('messages', $lineno); + if (!$stream->test(\Twig_Token::BLOCK_END_TYPE) && $stream->test('for')) { + // {% transchoice count for "message" %} + // {% transchoice count for message %} + $stream->next(); + $body = $this->parser->getExpressionParser()->parseExpression(); + } + if ($stream->test('with')) { // {% transchoice count with vars %} $stream->next(); @@ -50,12 +57,14 @@ class TransChoiceTokenParser extends TransTokenParser $domain = $this->parser->getExpressionParser()->parseExpression(); } - $stream->expect(\Twig_Token::BLOCK_END_TYPE); - - $body = $this->parser->subparse(array($this, 'decideTransChoiceFork'), true); + if (null === $body) { + // {% transchoice count %}message{% endtranschoice %} + $stream->expect(\Twig_Token::BLOCK_END_TYPE); + $body = $this->parser->subparse(array($this, 'decideTransChoiceFork'), true); + } if (!$body instanceof \Twig_Node_Text && !$body instanceof \Twig_Node_Expression) { - throw new \Twig_Error_Syntax(sprintf('A message must be a simple text (line %s)', $lineno), -1); + throw new \Twig_Error_Syntax('A message must be a simple text.'); } $stream->expect(\Twig_Token::BLOCK_END_TYPE); diff --git a/src/Symfony/Bridge/Twig/TokenParser/TransTokenParser.php b/src/Symfony/Bridge/Twig/TokenParser/TransTokenParser.php index 85a74845bc..c3450f67ab 100644 --- a/src/Symfony/Bridge/Twig/TokenParser/TransTokenParser.php +++ b/src/Symfony/Bridge/Twig/TokenParser/TransTokenParser.php @@ -14,7 +14,7 @@ namespace Symfony\Bridge\Twig\TokenParser; use Symfony\Bridge\Twig\Node\TransNode; /** - * + * * * @author Fabien Potencier */ @@ -36,35 +36,27 @@ class TransTokenParser extends \Twig_TokenParser $vars = new \Twig_Node_Expression_Array(array(), $lineno); $domain = new \Twig_Node_Expression_Constant('messages', $lineno); if (!$stream->test(\Twig_Token::BLOCK_END_TYPE)) { - if (!$stream->test('from') && !$stream->test('with')) { - // {% trans "message" %} - // {% trans message %} - $body = $this->parser->getExpressionParser()->parseExpression(); - } - if ($stream->test('with')) { - // {% trans "message" with vars %} + // {% trans with vars %} $stream->next(); $vars = $this->parser->getExpressionParser()->parseExpression(); } if ($stream->test('from')) { - // {% trans "message" from "messages" %} + // {% trans from "messages" %} $stream->next(); $domain = $this->parser->getExpressionParser()->parseExpression(); } elseif (!$stream->test(\Twig_Token::BLOCK_END_TYPE)) { - throw new \Twig_Error_Syntax(sprintf('Unexpected token. Twig was looking for the "from" keyword line %s)', $lineno), -1); + throw new \Twig_Error_Syntax('Unexpected token. Twig was looking for the "with" or "from" keyword.'); } } - if (null === $body) { - // {% trans %}message{% endtrans %} - $stream->expect(\Twig_Token::BLOCK_END_TYPE); - $body = $this->parser->subparse(array($this, 'decideTransFork'), true); - } + // {% trans %}message{% endtrans %} + $stream->expect(\Twig_Token::BLOCK_END_TYPE); + $body = $this->parser->subparse(array($this, 'decideTransFork'), true); if (!$body instanceof \Twig_Node_Text && !$body instanceof \Twig_Node_Expression) { - throw new \Twig_Error_Syntax('A message must be a simple text', -1); + throw new \Twig_Error_Syntax('A message must be a simple text'); } $stream->expect(\Twig_Token::BLOCK_END_TYPE); diff --git a/src/Symfony/Bundle/AsseticBundle/CacheWarmer/AssetManagerCacheWarmer.php b/src/Symfony/Bundle/AsseticBundle/CacheWarmer/AssetManagerCacheWarmer.php index 6adf66f2a2..35e7e8dc67 100644 --- a/src/Symfony/Bundle/AsseticBundle/CacheWarmer/AssetManagerCacheWarmer.php +++ b/src/Symfony/Bundle/AsseticBundle/CacheWarmer/AssetManagerCacheWarmer.php @@ -11,21 +11,22 @@ namespace Symfony\Bundle\AsseticBundle\CacheWarmer; -use Assetic\Factory\LazyAssetManager; use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmer; +use Symfony\Component\DependencyInjection\ContainerInterface; class AssetManagerCacheWarmer extends CacheWarmer { - protected $am; + private $container; - public function __construct(LazyAssetManager $am) + public function __construct(ContainerInterface $container) { - $this->am = $am; + $this->container = $container; } public function warmUp($cacheDir) { - $this->am->load(); + $am = $this->container->get('assetic.asset_manager'); + $am->load(); } public function isOptional() diff --git a/src/Symfony/Bundle/AsseticBundle/CacheWarmer/AssetWriterCacheWarmer.php b/src/Symfony/Bundle/AsseticBundle/CacheWarmer/AssetWriterCacheWarmer.php index 034a45a6e0..298ffd235d 100644 --- a/src/Symfony/Bundle/AsseticBundle/CacheWarmer/AssetWriterCacheWarmer.php +++ b/src/Symfony/Bundle/AsseticBundle/CacheWarmer/AssetWriterCacheWarmer.php @@ -11,24 +11,25 @@ namespace Symfony\Bundle\AsseticBundle\CacheWarmer; -use Assetic\AssetManager; use Assetic\AssetWriter; use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmer; +use Symfony\Component\DependencyInjection\ContainerInterface; class AssetWriterCacheWarmer extends CacheWarmer { - protected $am; - protected $writer; + private $container; + private $writer; - public function __construct(AssetManager $am, AssetWriter $writer) + public function __construct(ContainerInterface $container, AssetWriter $writer) { - $this->am = $am; + $this->container = $container; $this->writer = $writer; } public function warmUp($cacheDir) { - $this->writer->writeManagerAssets($this->am); + $am = $this->container->get('assetic.asset_manager'); + $this->writer->writeManagerAssets($am); } public function isOptional() diff --git a/src/Symfony/Bundle/AsseticBundle/Controller/AsseticController.php b/src/Symfony/Bundle/AsseticBundle/Controller/AsseticController.php index b34a845241..6ffd6fb95e 100644 --- a/src/Symfony/Bundle/AsseticBundle/Controller/AsseticController.php +++ b/src/Symfony/Bundle/AsseticBundle/Controller/AsseticController.php @@ -12,6 +12,7 @@ namespace Symfony\Bundle\AsseticBundle\Controller; use Assetic\Asset\AssetCache; +use Assetic\Asset\AssetInterface; use Assetic\Factory\LazyAssetManager; use Assetic\Cache\CacheInterface; use Symfony\Component\HttpFoundation\Request; @@ -36,13 +37,17 @@ class AsseticController $this->cache = $cache; } - public function render($name) + public function render($name, $pos = null) { if (!$this->am->has($name)) { - throw new NotFoundHttpException('Asset Not Found'); + throw new NotFoundHttpException(sprintf('The "%s" asset could not be found.', $name)); + } + + $asset = $this->am->get($name); + if (null !== $pos && !$asset = $this->findAssetLeaf($asset, $pos)) { + throw new NotFoundHttpException(sprintf('The "%s" asset does not include a leaf at position %d.', $name, $pos)); } - $asset = $this->getAsset($name); $response = $this->createResponse(); // last-modified @@ -63,7 +68,7 @@ class AsseticController return $response; } - $response->setContent($asset->dump()); + $response->setContent($this->cachifyAsset($asset)->dump()); return $response; } @@ -73,8 +78,17 @@ class AsseticController return new Response(); } - protected function getAsset($name) + protected function cachifyAsset(AssetInterface $asset) { - return new AssetCache($this->am->get($name), $this->cache); + return new AssetCache($asset, $this->cache); + } + + private function findAssetLeaf(AssetInterface $asset, $pos) + { + $leaves = array_values(iterator_to_array($asset)); + + if (isset($leaves[$pos])) { + return $leaves[$pos]; + } } } diff --git a/src/Symfony/Bundle/AsseticBundle/DependencyInjection/AsseticExtension.php b/src/Symfony/Bundle/AsseticBundle/DependencyInjection/AsseticExtension.php index 08ab9e8472..1284628dde 100644 --- a/src/Symfony/Bundle/AsseticBundle/DependencyInjection/AsseticExtension.php +++ b/src/Symfony/Bundle/AsseticBundle/DependencyInjection/AsseticExtension.php @@ -61,6 +61,11 @@ class AsseticExtension extends Extension $loader->load('filters/'.$name.'.xml'); } + if (isset($filter['file'])) { + $container->getDefinition('assetic.filter.'.$name)->setFile($filter['file']); + unset($filter['file']); + } + foreach ($filter as $key => $value) { $container->setParameter('assetic.filter.'.$name.'.'.$key, $value); } @@ -69,14 +74,12 @@ class AsseticExtension extends Extension // choose dynamic or static if ($parameterBag->resolveValue($parameterBag->get('assetic.use_controller'))) { $loader->load('controller.xml'); - $container->setParameter('assetic.twig_extension.class', '%assetic.twig_extension.dynamic.class%'); $container->getDefinition('assetic.helper.dynamic')->addTag('templating.helper', array('alias' => 'assetic')); - $container->remove('assetic.helper.static'); + $container->removeDefinition('assetic.helper.static'); } else { $loader->load('asset_writer.xml'); - $container->setParameter('assetic.twig_extension.class', '%assetic.twig_extension.static.class%'); $container->getDefinition('assetic.helper.static')->addTag('templating.helper', array('alias' => 'assetic')); - $container->remove('assetic.helper.dynamic'); + $container->removeDefinition('assetic.helper.dynamic'); } // register config resources @@ -94,11 +97,9 @@ class AsseticExtension extends Extension */ static protected function processConfigs(array $configs, $debug, array $bundles) { - $configuration = new Configuration(); - $tree = $configuration->getConfigTree($debug, $bundles); - $processor = new Processor(); - return $processor->process($tree, $configs); + $configuration = new Configuration($debug, $bundles); + return $processor->processConfiguration($configuration, $configs); } /** @@ -112,12 +113,7 @@ class AsseticExtension extends Extension static protected function registerFormulaResources(ContainerBuilder $container, array $bundles) { $map = $container->getParameter('kernel.bundles'); - - if ($diff = array_diff($bundles, array_keys($map))) { - throw new \InvalidArgumentException(sprintf('The following bundles are not registered: "%s"', implode('", "', $diff))); - } - - $am = $container->getDefinition('assetic.asset_manager'); + $am = $container->getDefinition('assetic.asset_manager'); // bundle views/ directories and kernel overrides foreach ($bundles as $name) { diff --git a/src/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/AssetManagerPass.php b/src/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/AssetManagerPass.php index 22454b83af..154f2ce553 100644 --- a/src/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/AssetManagerPass.php +++ b/src/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/AssetManagerPass.php @@ -48,7 +48,7 @@ class AssetManagerPass implements CompilerPassInterface } } } - $am->setArgument(1, $loaders); + $am->replaceArgument(1, $loaders); // add resources foreach ($container->findTaggedServiceIds('assetic.formula_resource') as $id => $attributes) { diff --git a/src/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/CheckClosureFilterPass.php b/src/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/CheckClosureFilterPass.php index fd14b0b400..251fb758f8 100644 --- a/src/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/CheckClosureFilterPass.php +++ b/src/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/CheckClosureFilterPass.php @@ -25,9 +25,9 @@ class CheckClosureFilterPass implements CompilerPassInterface { if ($container->hasDefinition('assetic.filter.closure.jar') && $container->getParameterBag()->resolveValue($container->getParameter('assetic.filter.closure.jar'))) { - $container->remove('assetic.filter.closure.api'); + $container->removeDefinition('assetic.filter.closure.api'); } elseif ($container->hasDefinition('assetic.filter.closure.api')) { - $container->remove('assetic.filter.closure.jar'); + $container->removeDefinition('assetic.filter.closure.jar'); } } } diff --git a/src/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/FilterManagerPass.php b/src/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/FilterManagerPass.php index b9c258774b..af04a6e214 100644 --- a/src/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/FilterManagerPass.php +++ b/src/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/FilterManagerPass.php @@ -39,6 +39,6 @@ class FilterManagerPass implements CompilerPassInterface $container ->getDefinition('assetic.filter_manager') - ->setArgument(1, $mapping); + ->replaceArgument(1, $mapping); } } diff --git a/src/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/TemplatingPass.php b/src/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/TemplatingPass.php index 852b488551..b0281261a7 100644 --- a/src/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/TemplatingPass.php +++ b/src/Symfony/Bundle/AsseticBundle/DependencyInjection/Compiler/TemplatingPass.php @@ -31,13 +31,13 @@ class TemplatingPass implements CompilerPassInterface if (!in_array('twig', $engines)) { foreach ($container->findTaggedServiceIds('assetic.templating.twig') as $id => $attr) { - $container->remove($id); + $container->removeDefinition($id); } } if (!in_array('php', $engines)) { foreach ($container->findTaggedServiceIds('assetic.templating.php') as $id => $attr) { - $container->remove($id); + $container->removeDefinition($id); } } } diff --git a/src/Symfony/Bundle/AsseticBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/AsseticBundle/DependencyInjection/Configuration.php index 1fe2e49af1..d0d2061276 100644 --- a/src/Symfony/Bundle/AsseticBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/AsseticBundle/DependencyInjection/Configuration.php @@ -12,6 +12,7 @@ namespace Symfony\Bundle\AsseticBundle\DependencyInjection; use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; /** * This class contains the configuration information for the bundle @@ -22,24 +23,36 @@ use Symfony\Component\Config\Definition\Builder\TreeBuilder; * @author Christophe Coevoet * @author Kris Wallsmith */ -class Configuration +class Configuration implements ConfigurationInterface { + private $bundles; + private $debug; + /** - * Generates the configuration tree. + * Constructor * * @param Boolean $debug Wether to use the debug mode * @param array $bundles An array of bundle names - * - * @return \Symfony\Component\Config\Definition\ArrayNode The config tree */ - public function getConfigTree($debug, array $bundles) + public function __construct($debug, array $bundles) { - $tree = new TreeBuilder(); + $this->debug = (Boolean) $debug; + $this->bundles = $bundles; + } - $tree->root('assetic') + /** + * Generates the configuration tree builder. + * + * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder + */ + public function getConfigTreeBuilder() + { + $builder = new TreeBuilder(); + + $builder->root('assetic') ->children() - ->booleanNode('debug')->defaultValue($debug)->end() - ->booleanNode('use_controller')->defaultValue($debug)->end() + ->booleanNode('debug')->defaultValue($this->debug)->end() + ->booleanNode('use_controller')->defaultValue($this->debug)->end() ->scalarNode('read_from')->defaultValue('%kernel.root_dir%/../web')->end() ->scalarNode('write_to')->defaultValue('%assetic.read_from%')->end() ->scalarNode('java')->defaultValue('/usr/bin/java')->end() @@ -51,16 +64,12 @@ class Configuration ->fixXmlConfig('bundle') ->children() ->arrayNode('bundles') - ->defaultValue($bundles) + ->defaultValue($this->bundles) ->requiresAtLeastOneElement() - ->beforeNormalization() - ->ifTrue(function($v) { return !is_array($v); }) - ->then(function($v) { return array($v); }) - ->end() ->prototype('scalar') - ->beforeNormalization() - ->ifTrue(function($v) { return is_array($v) && isset($v['name']); }) - ->then(function($v) { return $v['name']; }) + ->validate() + ->ifNotInArray($this->bundles) + ->thenInvalid('%s is not a valid bundle.') ->end() ->end() ->end() @@ -84,6 +93,6 @@ class Configuration ->end() ; - return $tree->buildTree(); + return $builder; } } diff --git a/src/Symfony/Bundle/AsseticBundle/Factory/Worker/UseControllerWorker.php b/src/Symfony/Bundle/AsseticBundle/Factory/Worker/UseControllerWorker.php new file mode 100644 index 0000000000..527c81d706 --- /dev/null +++ b/src/Symfony/Bundle/AsseticBundle/Factory/Worker/UseControllerWorker.php @@ -0,0 +1,33 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Factory\Worker; + +use Assetic\Asset\AssetInterface; +use Assetic\Factory\Worker\WorkerInterface; + +/** + * Prepends a fake front controller so the asset knows where it is-ish. + * + * @author Kris Wallsmith + */ +class UseControllerWorker implements WorkerInterface +{ + public function process(AssetInterface $asset) + { + $targetUrl = $asset->getTargetUrl(); + if ($targetUrl && '/' != $targetUrl[0] && 0 !== strpos($targetUrl, '_controller/')) { + $asset->setTargetUrl('_controller/'.$targetUrl); + } + + return $asset; + } +} diff --git a/src/Symfony/Bundle/AsseticBundle/Resources/config/asset_writer.xml b/src/Symfony/Bundle/AsseticBundle/Resources/config/asset_writer.xml index 855caa06ec..c4a9515396 100644 --- a/src/Symfony/Bundle/AsseticBundle/Resources/config/asset_writer.xml +++ b/src/Symfony/Bundle/AsseticBundle/Resources/config/asset_writer.xml @@ -12,7 +12,7 @@ - + diff --git a/src/Symfony/Bundle/AsseticBundle/Resources/config/assetic.xml b/src/Symfony/Bundle/AsseticBundle/Resources/config/assetic.xml index 2ef38f2616..23d67202d6 100644 --- a/src/Symfony/Bundle/AsseticBundle/Resources/config/assetic.xml +++ b/src/Symfony/Bundle/AsseticBundle/Resources/config/assetic.xml @@ -42,7 +42,7 @@ - + diff --git a/src/Symfony/Bundle/AsseticBundle/Resources/config/controller.xml b/src/Symfony/Bundle/AsseticBundle/Resources/config/controller.xml index 65a65732c2..1da0a603e5 100644 --- a/src/Symfony/Bundle/AsseticBundle/Resources/config/controller.xml +++ b/src/Symfony/Bundle/AsseticBundle/Resources/config/controller.xml @@ -8,6 +8,7 @@ Symfony\Bundle\AsseticBundle\Controller\AsseticController Symfony\Bundle\AsseticBundle\Routing\AsseticLoader Assetic\Cache\FilesystemCache + Symfony\Bundle\AsseticBundle\Factory\Worker\UseControllerWorker @@ -23,5 +24,8 @@ %assetic.cache_dir%/assets + + + diff --git a/src/Symfony/Bundle/AsseticBundle/Resources/config/templating_twig.xml b/src/Symfony/Bundle/AsseticBundle/Resources/config/templating_twig.xml index 5e3d070eb4..a2340dc316 100644 --- a/src/Symfony/Bundle/AsseticBundle/Resources/config/templating_twig.xml +++ b/src/Symfony/Bundle/AsseticBundle/Resources/config/templating_twig.xml @@ -5,8 +5,7 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - Symfony\Bundle\AsseticBundle\Twig\DynamicExtension - Symfony\Bundle\AsseticBundle\Twig\StaticExtension + Symfony\Bundle\AsseticBundle\Twig\AsseticExtension Assetic\Extension\Twig\TwigFormulaLoader @@ -16,6 +15,7 @@ %assetic.debug% + %assetic.use_controller% diff --git a/src/Symfony/Bundle/AsseticBundle/Routing/AsseticLoader.php b/src/Symfony/Bundle/AsseticBundle/Routing/AsseticLoader.php index 763ef31be4..9525fc8ff2 100644 --- a/src/Symfony/Bundle/AsseticBundle/Routing/AsseticLoader.php +++ b/src/Symfony/Bundle/AsseticBundle/Routing/AsseticLoader.php @@ -11,6 +11,7 @@ namespace Symfony\Bundle\AsseticBundle\Routing; +use Assetic\Asset\AssetInterface; use Assetic\Factory\LazyAssetManager; use Symfony\Component\Config\Loader\Loader; use Symfony\Component\Config\Resource\FileResource; @@ -62,22 +63,56 @@ class AsseticLoader extends Loader // routes foreach ($this->am->getNames() as $name) { $asset = $this->am->get($name); + $formula = $this->am->getFormula($name); - $defaults = array( - '_controller' => 'assetic.controller:render', - 'name' => $name, - ); + $this->loadRouteForAsset($routes, $asset, $name); - if ($extension = pathinfo($asset->getTargetUrl(), PATHINFO_EXTENSION)) { - $defaults['_format'] = $extension; + // add a route for each "leaf" in debug mode + if (isset($formula[2]['debug']) ? $formula[2]['debug'] : $this->am->isDebug()) { + $i = 0; + foreach ($asset as $leaf) { + $this->loadRouteForAsset($routes, $leaf, $name, $i++); + } } - - $routes->add('assetic_'.$name, new Route($asset->getTargetUrl(), $defaults)); } return $routes; } + /** + * Loads a route to serve an supplied asset. + * + * The fake front controller that {@link UseControllerWorker} adds to the + * target URL will be removed before set as a route pattern. + * + * @param RouteCollection $routes The route collection + * @param AssetInterface $asset The asset + * @param string $name The name to use + * @param integer $pos The leaf index + */ + private function loadRouteForAsset(RouteCollection $routes, AssetInterface $asset, $name, $pos = null) + { + $defaults = array( + '_controller' => 'assetic.controller:render', + 'name' => $name, + 'pos' => $pos, + ); + + // remove the fake front controller + $pattern = str_replace('_controller/', '', $asset->getTargetUrl()); + + if ($format = pathinfo($pattern, PATHINFO_EXTENSION)) { + $defaults['_format'] = $format; + } + + $route = '_assetic_'.$name; + if (null !== $pos) { + $route .= '_'.$pos; + } + + $routes->add($route, new Route($pattern, $defaults)); + } + public function supports($resource, $type = null) { return 'assetic' == $type; diff --git a/src/Symfony/Bundle/AsseticBundle/Templating/DynamicAsseticHelper.php b/src/Symfony/Bundle/AsseticBundle/Templating/DynamicAsseticHelper.php index e1ad188abe..a3dad04501 100644 --- a/src/Symfony/Bundle/AsseticBundle/Templating/DynamicAsseticHelper.php +++ b/src/Symfony/Bundle/AsseticBundle/Templating/DynamicAsseticHelper.php @@ -40,6 +40,6 @@ class DynamicAsseticHelper extends AsseticHelper protected function getAssetUrl(AssetInterface $asset, $options = array()) { - return $this->routerHelper->generate('assetic_'.$options['name']); + return $this->routerHelper->generate('_assetic_'.$options['name']); } } diff --git a/src/Symfony/Bundle/AsseticBundle/Tests/CacheWarmer/AssetManagerCacheWarmerTest.php b/src/Symfony/Bundle/AsseticBundle/Tests/CacheWarmer/AssetManagerCacheWarmerTest.php index 65b14bff26..02b959890c 100644 --- a/src/Symfony/Bundle/AsseticBundle/Tests/CacheWarmer/AssetManagerCacheWarmerTest.php +++ b/src/Symfony/Bundle/AsseticBundle/Tests/CacheWarmer/AssetManagerCacheWarmerTest.php @@ -24,13 +24,28 @@ class AssetManagerCacheWarmerTest extends \PHPUnit_Framework_TestCase public function testWarmUp() { - $am = $this->getMockBuilder('Assetic\\Factory\\LazyAssetManager') + $am = $this + ->getMockBuilder('Assetic\\Factory\\LazyAssetManager') ->disableOriginalConstructor() - ->getMock(); + ->getMock() + ; $am->expects($this->once())->method('load'); + + $container = $this + ->getMockBuilder('Symfony\\Component\\DependencyInjection\\Container') + ->setConstructorArgs(array()) + ->getMock() + ; + + $container + ->expects($this->once()) + ->method('get') + ->with('assetic.asset_manager') + ->will($this->returnValue($am)) + ; - $warmer = new AssetManagerCacheWarmer($am); + $warmer = new AssetManagerCacheWarmer($container); $warmer->warmUp('/path/to/cache'); } } diff --git a/src/Symfony/Bundle/AsseticBundle/Tests/CacheWarmer/AssetWriterCacheWarmerTest.php b/src/Symfony/Bundle/AsseticBundle/Tests/CacheWarmer/AssetWriterCacheWarmerTest.php index 35e67cd129..d8b78c0e6f 100644 --- a/src/Symfony/Bundle/AsseticBundle/Tests/CacheWarmer/AssetWriterCacheWarmerTest.php +++ b/src/Symfony/Bundle/AsseticBundle/Tests/CacheWarmer/AssetWriterCacheWarmerTest.php @@ -25,15 +25,33 @@ class AssetWriterCacheWarmerTest extends \PHPUnit_Framework_TestCase public function testWarmUp() { $am = $this->getMock('Assetic\\AssetManager'); - $writer = $this->getMockBuilder('Assetic\\AssetWriter') + + $writer = $this + ->getMockBuilder('Assetic\\AssetWriter') ->disableOriginalConstructor() - ->getMock(); + ->getMock() + ; - $writer->expects($this->once()) + $writer + ->expects($this->once()) ->method('writeManagerAssets') - ->with($am); + ->with($am) + ; + + $container = $this + ->getMockBuilder('Symfony\\Component\\DependencyInjection\\Container') + ->setConstructorArgs(array()) + ->getMock() + ; + + $container + ->expects($this->once()) + ->method('get') + ->with('assetic.asset_manager') + ->will($this->returnValue($am)) + ; - $warmer = new AssetWriterCacheWarmer($am, $writer); + $warmer = new AssetWriterCacheWarmer($container, $writer); $warmer->warmUp('/path/to/cache'); } } diff --git a/src/Symfony/Bundle/AsseticBundle/Tests/DependencyInjection/AsseticExtensionTest.php b/src/Symfony/Bundle/AsseticBundle/Tests/DependencyInjection/AsseticExtensionTest.php index 05f1b0ef29..e73793b863 100644 --- a/src/Symfony/Bundle/AsseticBundle/Tests/DependencyInjection/AsseticExtensionTest.php +++ b/src/Symfony/Bundle/AsseticBundle/Tests/DependencyInjection/AsseticExtensionTest.php @@ -46,9 +46,7 @@ class AsseticExtensionTest extends \PHPUnit_Framework_TestCase $this->markTestSkipped('Assetic is not available.'); } - $this->kernel = $this->getMockBuilder('Symfony\\Component\\HttpKernel\\Kernel') - ->disableOriginalConstructor() - ->getMock(); + $this->kernel = $this->getMock('Symfony\\Component\\HttpKernel\\KernelInterface'); $this->container = new ContainerBuilder(); $this->container->addScope(new Scope('request')); @@ -61,6 +59,7 @@ class AsseticExtensionTest extends \PHPUnit_Framework_TestCase $this->container->setParameter('kernel.cache_dir', __DIR__); $this->container->setParameter('kernel.debug', false); $this->container->setParameter('kernel.root_dir', __DIR__); + $this->container->set('kernel', $this->kernel); } /** diff --git a/src/Symfony/Bundle/AsseticBundle/Tests/Factory/AssetFactoryTest.php b/src/Symfony/Bundle/AsseticBundle/Tests/Factory/AssetFactoryTest.php index f6bd04d5b1..dcb3ef94e8 100644 --- a/src/Symfony/Bundle/AsseticBundle/Tests/Factory/AssetFactoryTest.php +++ b/src/Symfony/Bundle/AsseticBundle/Tests/Factory/AssetFactoryTest.php @@ -30,7 +30,7 @@ class AssetFactoryTest extends \PHPUnit_Framework_TestCase public function testBundleNotation() { - $input = '@My/Resources/css/main.css'; + $input = '@MyBundle/Resources/css/main.css'; $this->kernel->expects($this->once()) ->method('locateResource') @@ -47,7 +47,7 @@ class AssetFactoryTest extends \PHPUnit_Framework_TestCase { $this->kernel->expects($this->once()) ->method('locateResource') - ->with('@My/Resources/css/') + ->with('@MyBundle/Resources/css/') ->will($this->returnValue('/path/to/bundle/Resources/css/')); $this->factory->createAsset($input); @@ -56,8 +56,8 @@ class AssetFactoryTest extends \PHPUnit_Framework_TestCase public function getGlobs() { return array( - array('@My/Resources/css/*'), - array('@My/Resources/css/*/*.css'), + array('@MyBundle/Resources/css/*'), + array('@MyBundle/Resources/css/*/*.css'), ); } } diff --git a/src/Symfony/Bundle/AsseticBundle/Tests/FunctionalTest.php b/src/Symfony/Bundle/AsseticBundle/Tests/FunctionalTest.php index 76a6c600a0..3c9ba424ff 100644 --- a/src/Symfony/Bundle/AsseticBundle/Tests/FunctionalTest.php +++ b/src/Symfony/Bundle/AsseticBundle/Tests/FunctionalTest.php @@ -44,7 +44,7 @@ class FunctionalTest extends \PHPUnit_Framework_TestCase } /** - * @dataProvider provideDebugAndAssetCount + * @dataProvider provideAmDebugAndAssetCount */ public function testKernel($debug, $count) { @@ -55,7 +55,7 @@ class FunctionalTest extends \PHPUnit_Framework_TestCase } /** - * @dataProvider provideDebugAndAssetCount + * @dataProvider provideRouterDebugAndAssetCount */ public function testRoutes($debug, $count) { @@ -64,7 +64,7 @@ class FunctionalTest extends \PHPUnit_Framework_TestCase $matches = 0; foreach (array_keys($kernel->getContainer()->get('router')->getRouteCollection()->all()) as $name) { - if (0 === strpos($name, 'assetic_')) { + if (0 === strpos($name, '_assetic_')) { ++$matches; } } @@ -102,11 +102,18 @@ class FunctionalTest extends \PHPUnit_Framework_TestCase $this->assertEquals(2, count($crawler->filter('script[src$=".js"]'))); } - public function provideDebugAndAssetCount() + public function provideAmDebugAndAssetCount() { - // totals include assets defined in both php and twig templates return array( - array(true, 6), + array(true, 3), + array(false, 3), + ); + } + + public function provideRouterDebugAndAssetCount() + { + return array( + array(true, 9), array(false, 3), ); } diff --git a/src/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/layout.html.php b/src/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/layout.html.php index 3044a45c80..bd70943211 100644 --- a/src/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/layout.html.php +++ b/src/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/layout.html.php @@ -1,7 +1,7 @@ extend('::base.html.php') ?> start('stylesheets') ?> - stylesheets('stylesheet1.css, stylesheet2.css, @Test/Resources/css/bundle.css') as $url): ?> + stylesheets('stylesheet1.css, stylesheet2.css, @TestBundle/Resources/css/bundle.css') as $url): ?> stop() ?> diff --git a/src/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/layout.html.twig b/src/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/layout.html.twig index 7215ae8494..24cb963f4d 100644 --- a/src/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/layout.html.twig +++ b/src/Symfony/Bundle/AsseticBundle/Tests/Resources/Resources/views/layout.html.twig @@ -1,7 +1,7 @@ {% extends '::base.html.twig' %} {% block stylesheets %} - {% stylesheets 'stylesheet1.css' 'stylesheet2.css' '@Test/Resources/css/bundle.css' %} + {% stylesheets 'stylesheet1.css' 'stylesheet2.css' '@TestBundle/Resources/css/bundle.css' %} {% endstylesheets %} {% endblock %} diff --git a/src/Symfony/Bundle/AsseticBundle/Tests/Resources/config/config.yml b/src/Symfony/Bundle/AsseticBundle/Tests/Resources/config/config.yml index 3303ae5980..1049c0e4a7 100644 --- a/src/Symfony/Bundle/AsseticBundle/Tests/Resources/config/config.yml +++ b/src/Symfony/Bundle/AsseticBundle/Tests/Resources/config/config.yml @@ -19,4 +19,4 @@ twig: assetic: use_controller: true read_from: "%kernel.root_dir%/web" - bundles: [Test] + bundles: [TestBundle] diff --git a/src/Symfony/Bundle/AsseticBundle/Twig/AsseticExtension.php b/src/Symfony/Bundle/AsseticBundle/Twig/AsseticExtension.php new file mode 100644 index 0000000000..e5302ed71c --- /dev/null +++ b/src/Symfony/Bundle/AsseticBundle/Twig/AsseticExtension.php @@ -0,0 +1,49 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Twig; + +use Assetic\Extension\Twig\AsseticExtension as BaseAsseticExtension; +use Assetic\Factory\AssetFactory; + +/** + * Assetic extension. + * + * @author Kris Wallsmith + */ +class AsseticExtension extends BaseAsseticExtension +{ + private $useController; + + public function __construct(AssetFactory $factory, $debug = false, $useController = false) + { + parent::__construct($factory, $debug); + + $this->useController = $useController; + } + + public function getTokenParsers() + { + return array( + new AsseticTokenParser($this->factory, 'javascripts', 'js/*.js', false, array('package')), + new AsseticTokenParser($this->factory, 'stylesheets', 'css/*.css', false, array('package')), + new AsseticTokenParser($this->factory, 'image', 'images/*', true, array('package')), + ); + } + + public function getGlobals() + { + $globals = parent::getGlobals(); + $globals['assetic']['use_controller'] = $this->useController; + + return $globals; + } +} diff --git a/src/Symfony/Bundle/AsseticBundle/Twig/AsseticNode.php b/src/Symfony/Bundle/AsseticBundle/Twig/AsseticNode.php new file mode 100644 index 0000000000..1202b4abe0 --- /dev/null +++ b/src/Symfony/Bundle/AsseticBundle/Twig/AsseticNode.php @@ -0,0 +1,57 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Twig; + +use Assetic\Asset\AssetInterface; +use Assetic\Extension\Twig\AsseticNode as BaseAsseticNode; + +/** + * Assetic node. + * + * @author Kris Wallsmith + */ +class AsseticNode extends BaseAsseticNode +{ + protected function compileAssetUrl(\Twig_Compiler $compiler, AssetInterface $asset, $name) + { + $compiler + ->raw('isset($context[\'assetic\'][\'use_controller\']) && $context[\'assetic\'][\'use_controller\'] ? ') + ->subcompile($this->getPathFunction($name)) + ->raw(' : ') + ->subcompile($this->getAssetFunction($asset->getTargetUrl())) + ; + } + + private function getPathFunction($name) + { + return new \Twig_Node_Expression_Function( + new \Twig_Node_Expression_Name('path', $this->getLine()), + new \Twig_Node(array(new \Twig_Node_Expression_Constant('_assetic_'.$name, $this->getLine()))), + $this->getLine() + ); + } + + private function getAssetFunction($path) + { + $arguments = array(new \Twig_Node_Expression_Constant($path, $this->getLine())); + + if ($this->hasAttribute('package')) { + $arguments[] = new \Twig_Node_Expression_Constant($this->getAttribute('package'), $this->getLine()); + } + + return new \Twig_Node_Expression_Function( + new \Twig_Node_Expression_Name('asset', $this->getLine()), + new \Twig_Node($arguments), + $this->getLine() + ); + } +} diff --git a/src/Symfony/Bundle/AsseticBundle/Twig/AsseticTokenParser.php b/src/Symfony/Bundle/AsseticBundle/Twig/AsseticTokenParser.php new file mode 100644 index 0000000000..fc0673ea24 --- /dev/null +++ b/src/Symfony/Bundle/AsseticBundle/Twig/AsseticTokenParser.php @@ -0,0 +1,28 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Bundle\AsseticBundle\Twig; + +use Assetic\Asset\AssetInterface; +use Assetic\Extension\Twig\AsseticTokenParser as BaseAsseticTokenParser; + +/** + * Assetic token parser. + * + * @author Kris Wallsmith + */ +class AsseticTokenParser extends BaseAsseticTokenParser +{ + protected function createNode(AssetInterface $asset, \Twig_NodeInterface $body, array $inputs, array $filters, $name, array $attributes = array(), $lineno = 0, $tag = null) + { + return new AsseticNode($asset, $body, $inputs, $filters, $name, $attributes, $lineno, $tag); + } +} diff --git a/src/Symfony/Bundle/AsseticBundle/Twig/DynamicExtension.php b/src/Symfony/Bundle/AsseticBundle/Twig/DynamicExtension.php deleted file mode 100644 index fc95aec740..0000000000 --- a/src/Symfony/Bundle/AsseticBundle/Twig/DynamicExtension.php +++ /dev/null @@ -1,32 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Symfony\Bundle\AsseticBundle\Twig; - -use Assetic\Extension\Twig\AsseticExtension; -use Assetic\Factory\AssetFactory; - -/** - * The dynamic extension is used when use_controllers is enabled. - * - * @author Kris Wallsmith - */ -class DynamicExtension extends AsseticExtension -{ - public function getTokenParsers() - { - return array( - new DynamicTokenParser($this->factory, 'javascripts', 'js/*.js', $this->debug, false, array('package')), - new DynamicTokenParser($this->factory, 'stylesheets', 'css/*.css', $this->debug, false, array('package')), - new DynamicTokenParser($this->factory, 'image', 'images/*', $this->debug, true, array('package')), - ); - } -} diff --git a/src/Symfony/Bundle/AsseticBundle/Twig/DynamicNode.php b/src/Symfony/Bundle/AsseticBundle/Twig/DynamicNode.php deleted file mode 100644 index b17c0d0541..0000000000 --- a/src/Symfony/Bundle/AsseticBundle/Twig/DynamicNode.php +++ /dev/null @@ -1,36 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Symfony\Bundle\AsseticBundle\Twig; - -use Assetic\Extension\Twig\AsseticNode; - -/** - * The "dynamic" node uses a controller to render assets. - * - * @author Kris Wallsmith - */ -class DynamicNode extends AsseticNode -{ - /** - * Renders the asset URL using Symfony's path() function. - */ - protected function getAssetUrlNode(\Twig_NodeInterface $body) - { - return new \Twig_Node_Expression_Function( - new \Twig_Node_Expression_Name('path', $body->getLine()), - new \Twig_Node(array( - new \Twig_Node_Expression_Constant('assetic_'.$this->getAttribute('name'), $body->getLine()), - )), - $body->getLine() - ); - } -} diff --git a/src/Symfony/Bundle/AsseticBundle/Twig/DynamicTokenParser.php b/src/Symfony/Bundle/AsseticBundle/Twig/DynamicTokenParser.php deleted file mode 100644 index 418b48d50e..0000000000 --- a/src/Symfony/Bundle/AsseticBundle/Twig/DynamicTokenParser.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Symfony\Bundle\AsseticBundle\Twig; - -use Assetic\Extension\Twig\AsseticTokenParser; - -/** - * Parses an Assetic tag. - * - * @author Kris Wallsmith - */ -class DynamicTokenParser extends AsseticTokenParser -{ - static protected function createNode(\Twig_NodeInterface $body, array $inputs, array $filters, array $attributes, $lineno = 0, $tag = null) - { - return new DynamicNode($body, $inputs, $filters, $attributes, $lineno, $tag); - } -} diff --git a/src/Symfony/Bundle/AsseticBundle/Twig/StaticExtension.php b/src/Symfony/Bundle/AsseticBundle/Twig/StaticExtension.php deleted file mode 100644 index 884e6c7f24..0000000000 --- a/src/Symfony/Bundle/AsseticBundle/Twig/StaticExtension.php +++ /dev/null @@ -1,32 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Symfony\Bundle\AsseticBundle\Twig; - -use Assetic\Extension\Twig\AsseticExtension; -use Assetic\Factory\AssetFactory; - -/** - * The static extension is used when use_controllers is disabled. - * - * @author Kris Wallsmith - */ -class StaticExtension extends AsseticExtension -{ - public function getTokenParsers() - { - return array( - new StaticTokenParser($this->factory, 'javascripts', 'js/*.js', $this->debug, false, array('package')), - new StaticTokenParser($this->factory, 'stylesheets', 'css/*.css', $this->debug, false, array('package')), - new StaticTokenParser($this->factory, 'image', 'images/*', $this->debug, true, array('package')), - ); - } -} diff --git a/src/Symfony/Bundle/AsseticBundle/Twig/StaticNode.php b/src/Symfony/Bundle/AsseticBundle/Twig/StaticNode.php deleted file mode 100644 index 73f0fe383f..0000000000 --- a/src/Symfony/Bundle/AsseticBundle/Twig/StaticNode.php +++ /dev/null @@ -1,37 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Symfony\Bundle\AsseticBundle\Twig; - -use Assetic\Extension\Twig\AsseticNode; - -/** - * The "static" node references a file in the web directory. - * - * @author Kris Wallsmith - */ -class StaticNode extends AsseticNode -{ - /** - * Renders the asset URL using Symfony's asset() function. - */ - protected function getAssetUrlNode(\Twig_NodeInterface $body) - { - return new \Twig_Node_Expression_Function( - new \Twig_Node_Expression_Name('asset', $body->getLine()), - new \Twig_Node(array( - new \Twig_Node_Expression_Constant($this->getAttribute('output'), $body->getLine()), - new \Twig_Node_Expression_Constant($this->hasAttribute('package') ? $this->getAttribute('package') : null, $body->getLine()), - )), - $body->getLine() - ); - } -} diff --git a/src/Symfony/Bundle/AsseticBundle/Twig/StaticTokenParser.php b/src/Symfony/Bundle/AsseticBundle/Twig/StaticTokenParser.php deleted file mode 100644 index 5ee21b8ec7..0000000000 --- a/src/Symfony/Bundle/AsseticBundle/Twig/StaticTokenParser.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Symfony\Bundle\AsseticBundle\Twig; - -use Assetic\Extension\Twig\AsseticTokenParser; - -/** - * Parses an Assetic tag. - * - * @author Kris Wallsmith - */ -class StaticTokenParser extends AsseticTokenParser -{ - static protected function createNode(\Twig_NodeInterface $body, array $inputs, array $filters, array $attributes, $lineno = 0, $tag = null) - { - return new StaticNode($body, $inputs, $filters, $attributes, $lineno, $tag); - } -} diff --git a/src/Symfony/Bundle/DoctrineBundle/Command/CreateDatabaseDoctrineCommand.php b/src/Symfony/Bundle/DoctrineBundle/Command/CreateDatabaseDoctrineCommand.php index 7a67cdcd35..2be80fb775 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Command/CreateDatabaseDoctrineCommand.php +++ b/src/Symfony/Bundle/DoctrineBundle/Command/CreateDatabaseDoctrineCommand.php @@ -48,7 +48,7 @@ EOT protected function execute(InputInterface $input, OutputInterface $output) { $connection = $this->getDoctrineConnection($input->getOption('connection')); - + $params = $connection->getParams(); $name = isset($params['path']) ? $params['path']:$params['dbname']; diff --git a/src/Symfony/Bundle/DoctrineBundle/Command/DoctrineCommand.php b/src/Symfony/Bundle/DoctrineBundle/Command/DoctrineCommand.php index f7b390cc60..041f7b472a 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Command/DoctrineCommand.php +++ b/src/Symfony/Bundle/DoctrineBundle/Command/DoctrineCommand.php @@ -39,7 +39,7 @@ abstract class DoctrineCommand extends Command { /** * Convenience method to push the helper sets of a given entity manager into the application. - * + * * @param Application $application * @param string $emName */ @@ -165,10 +165,11 @@ abstract class DoctrineCommand extends Command protected function findBasePathForBundle($bundle) { $path = str_replace('\\', '/', $bundle->getNamespace()); - $destination = str_replace('/'.$path, "", $bundle->getPath(), $c); + $search = str_replace('\\', '/', $bundle->getPath()); + $destination = str_replace('/'.$path, '', $search, $c); if ($c != 1) { - throw new \RuntimeException("Something went terribly wrong."); + throw new \RuntimeException(sprintf('Can\'t find base path for bundle (path: "%s", destination: "%s").', $path, $destination)); } return $destination; diff --git a/src/Symfony/Bundle/DoctrineBundle/Command/DropDatabaseDoctrineCommand.php b/src/Symfony/Bundle/DoctrineBundle/Command/DropDatabaseDoctrineCommand.php index 572c1e829c..2f7579d2b5 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Command/DropDatabaseDoctrineCommand.php +++ b/src/Symfony/Bundle/DoctrineBundle/Command/DropDatabaseDoctrineCommand.php @@ -53,7 +53,7 @@ EOT protected function execute(InputInterface $input, OutputInterface $output) { $connection = $this->getDoctrineConnection($input->getOption('connection')); - + $params = $connection->getParams(); $name = isset($params['path'])?$params['path']:(isset($params['dbname'])?$params['dbname']:false); diff --git a/src/Symfony/Bundle/DoctrineBundle/Command/GenerateEntitiesDoctrineCommand.php b/src/Symfony/Bundle/DoctrineBundle/Command/GenerateEntitiesDoctrineCommand.php index 365f87ccd4..d2e4025cc1 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Command/GenerateEntitiesDoctrineCommand.php +++ b/src/Symfony/Bundle/DoctrineBundle/Command/GenerateEntitiesDoctrineCommand.php @@ -60,7 +60,7 @@ EOT $entityGenerator = $this->getEntityGenerator(); foreach ($metadatas as $metadata) { - if ($filterEntity && $metadata->reflClass->getShortName() !== $filterEntity) { + if ($filterEntity && $metadata->getReflClass()->getShortName() !== $filterEntity) { continue; } diff --git a/src/Symfony/Bundle/DoctrineBundle/Command/GenerateRepositoriesDoctrineCommand.php b/src/Symfony/Bundle/DoctrineBundle/Command/GenerateRepositoriesDoctrineCommand.php index 72d3ba2897..6c9e46930a 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Command/GenerateRepositoriesDoctrineCommand.php +++ b/src/Symfony/Bundle/DoctrineBundle/Command/GenerateRepositoriesDoctrineCommand.php @@ -51,7 +51,7 @@ EOT if ($metadatas = $this->getBundleMetadatas($foundBundle)) { $output->writeln(sprintf('Generating entity repositories for "%s"', $foundBundle->getName())); $generator = new EntityRepositoryGenerator(); - + foreach ($metadatas as $metadata) { if ($filterEntity && $filterEntity !== $metadata->reflClass->getShortname()) { continue; diff --git a/src/Symfony/Bundle/DoctrineBundle/Command/ImportMappingDoctrineCommand.php b/src/Symfony/Bundle/DoctrineBundle/Command/ImportMappingDoctrineCommand.php index 7e889bcb36..5a34a963d9 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Command/ImportMappingDoctrineCommand.php +++ b/src/Symfony/Bundle/DoctrineBundle/Command/ImportMappingDoctrineCommand.php @@ -77,7 +77,7 @@ EOT $em = $this->getEntityManager($this->container, $input->getOption('em')); $databaseDriver = new DatabaseDriver($em->getConnection()->getSchemaManager()); $em->getConfiguration()->setMetadataDriverImpl($databaseDriver); - + $emName = $input->getOption('em'); $emName = $emName ? $emName : 'default'; diff --git a/src/Symfony/Bundle/DoctrineBundle/Command/InfoDoctrineCommand.php b/src/Symfony/Bundle/DoctrineBundle/Command/InfoDoctrineCommand.php index 7399ac344e..fa357ad84a 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Command/InfoDoctrineCommand.php +++ b/src/Symfony/Bundle/DoctrineBundle/Command/InfoDoctrineCommand.php @@ -69,7 +69,7 @@ EOT $output->write(sprintf("Found %d entities mapped in entity manager %s:\n", count($entityClassNames), $entityManagerName), true); - + foreach ($entityClassNames as $entityClassName) { try { $cm = $entityManager->getClassMetadata($entityClassName); diff --git a/src/Symfony/Bundle/DoctrineBundle/Command/LoadDataFixturesDoctrineCommand.php b/src/Symfony/Bundle/DoctrineBundle/Command/LoadDataFixturesDoctrineCommand.php index 99b5af1893..5a21e5169c 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Command/LoadDataFixturesDoctrineCommand.php +++ b/src/Symfony/Bundle/DoctrineBundle/Command/LoadDataFixturesDoctrineCommand.php @@ -40,7 +40,7 @@ class LoadDataFixturesDoctrineCommand extends DoctrineCommand ->setName('doctrine:data:load') ->setDescription('Load data fixtures to your database.') ->addOption('fixtures', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The directory or file to load data fixtures from.') - ->addOption('append', null, InputOption::VALUE_OPTIONAL, 'Whether or not to append the data fixtures.', false) + ->addOption('append', null, InputOption::VALUE_NONE, 'Append the data fixtures instead of flushing the database first.') ->addOption('em', null, InputOption::VALUE_REQUIRED, 'The entity manager to use for this command.') ->setHelp(<<doctrine:data:load command loads data fixtures from your bundles: diff --git a/src/Symfony/Bundle/DoctrineBundle/Command/RunDqlDoctrineCommand.php b/src/Symfony/Bundle/DoctrineBundle/Command/RunDqlDoctrineCommand.php index 1db7d4f0d6..69a81a7ccf 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Command/RunDqlDoctrineCommand.php +++ b/src/Symfony/Bundle/DoctrineBundle/Command/RunDqlDoctrineCommand.php @@ -36,15 +36,15 @@ class RunDqlDoctrineCommand extends RunDqlCommand ->setHelp(<<doctrine:query:dql command executes the given DQL query and outputs the results: - ./app/console doctrine:query:dql "SELECT u FROM User:User u" + ./app/console doctrine:query:dql "SELECT u FROM UserBundle:User u" You can also optional specify some additional options like what type of hydration to use when executing the query: - ./app/console doctrine:query:dql "SELECT u FROM User:User u" --hydrate=array + ./app/console doctrine:query:dql "SELECT u FROM UserBundle:User u" --hydrate=array Additionally you can specify the first result and maximum amount of results to show: - ./app/console doctrine:query:dql "SELECT u FROM User:User u" --first-result=0 --max-result=30 + ./app/console doctrine:query:dql "SELECT u FROM UserBundle:User u" --first-result=0 --max-result=30 EOT ); } diff --git a/src/Symfony/Bundle/DoctrineBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/DoctrineBundle/DependencyInjection/Configuration.php index 4774e0abb6..9ecd176db3 100644 --- a/src/Symfony/Bundle/DoctrineBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/DoctrineBundle/DependencyInjection/Configuration.php @@ -13,6 +13,7 @@ namespace Symfony\Bundle\DoctrineBundle\DependencyInjection; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; /** * This class contains the configuration information for the bundle @@ -22,28 +23,34 @@ use Symfony\Component\Config\Definition\Builder\TreeBuilder; * * @author Christophe Coevoet */ -class Configuration +class Configuration implements ConfigurationInterface { - private $kernelDebug; + private $debug; /** - * Generates the configuration tree. + * Constructor * - * @param Boolean $kernelDebug - * - * @return \Symfony\Component\Config\Definition\ArrayNode The config tree + * @param Boolean $debug Wether to use the debug mode */ - public function getConfigTree($kernelDebug) + public function __construct($debug) { - $this->kernelDebug = (bool) $kernelDebug; + $this->debug = (Boolean) $debug; + } + /** + * Generates the configuration tree builder. + * + * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder + */ + public function getConfigTreeBuilder() + { $treeBuilder = new TreeBuilder(); $rootNode = $treeBuilder->root('doctrine'); $this->addDbalSection($rootNode); $this->addOrmSection($rootNode); - return $treeBuilder->buildTree(); + return $treeBuilder; } private function addDbalSection(ArrayNodeDefinition $node) @@ -63,12 +70,7 @@ class Configuration ->children() ->arrayNode('types') ->useAttributeAsKey('name') - ->prototype('scalar') - ->beforeNormalization() - ->ifTrue(function($v) { return is_array($v) && isset($v['class']); }) - ->then(function($v) { return $v['class']; }) - ->end() - ->end() + ->prototype('scalar')->end() ->end() ->end() ->fixXmlConfig('connection') @@ -98,7 +100,7 @@ class Configuration ->scalarNode('unix_socket')->end() ->scalarNode('platform_service')->end() ->scalarNode('charset')->end() - ->booleanNode('logging')->defaultValue($this->kernelDebug)->end() + ->booleanNode('logging')->defaultValue($this->debug)->end() ->end() ->fixXmlConfig('driver_class', 'driverClass') ->children() @@ -125,7 +127,7 @@ class Configuration { $node ->children() - ->arrayNode('orm') + ->arrayNode('orm') ->children() ->scalarNode('default_entity_manager')->end() ->booleanNode('auto_generate_proxy_classes')->defaultFalse()->end() @@ -156,6 +158,13 @@ class Configuration ->scalarNode('connection')->end() ->scalarNode('class_metadata_factory_name')->defaultValue('%doctrine.orm.class_metadata_factory_name%')->end() ->end() + ->fixXmlConfig('hydrator') + ->children() + ->arrayNode('hydrators') + ->useAttributeAsKey('name') + ->prototype('scalar')->end() + ->end() + ->end() ->fixXmlConfig('mapping') ->children() ->arrayNode('mappings') @@ -185,30 +194,15 @@ class Configuration ->children() ->arrayNode('string_functions') ->useAttributeAsKey('name') - ->prototype('scalar') - ->beforeNormalization() - ->ifTrue(function($v) { return is_array($v) && isset($v['class']); }) - ->then(function($v) { return $v['class']; }) - ->end() - ->end() + ->prototype('scalar')->end() ->end() ->arrayNode('numeric_functions') ->useAttributeAsKey('name') - ->prototype('scalar') - ->beforeNormalization() - ->ifTrue(function($v) { return is_array($v) && isset($v['class']); }) - ->then(function($v) { return $v['class']; }) - ->end() - ->end() + ->prototype('scalar')->end() ->end() ->arrayNode('datetime_functions') ->useAttributeAsKey('name') - ->prototype('scalar') - ->beforeNormalization() - ->ifTrue(function($v) { return is_array($v) && isset($v['class']); }) - ->then(function($v) { return $v['class']; }) - ->end() - ->end() + ->prototype('scalar')->end() ->end() ->end() ->end() diff --git a/src/Symfony/Bundle/DoctrineBundle/DependencyInjection/DoctrineExtension.php b/src/Symfony/Bundle/DoctrineBundle/DependencyInjection/DoctrineExtension.php index 740f435c14..fcfe01091a 100755 --- a/src/Symfony/Bundle/DoctrineBundle/DependencyInjection/DoctrineExtension.php +++ b/src/Symfony/Bundle/DoctrineBundle/DependencyInjection/DoctrineExtension.php @@ -31,9 +31,9 @@ class DoctrineExtension extends AbstractDoctrineExtension { public function load(array $configs, ContainerBuilder $container) { - $configuration = new Configuration(); $processor = new Processor(); - $config = $processor->process($configuration->getConfigTree($container->getParameter('kernel.debug')), $configs); + $configuration = new Configuration($container->getParameter('kernel.debug')); + $config = $processor->processConfiguration($configuration, $configs); if (!empty($config['dbal'])) { $this->dbalLoad($config['dbal'], $container); @@ -197,6 +197,10 @@ class DoctrineExtension extends AbstractDoctrineExtension $ormConfigDef->addMethodCall($method, array($arg)); } + foreach ($entityManager['hydrators'] as $name => $class) { + $ormConfigDef->addMethodCall('addCustomHydrationMode', array ($name, $class)); + } + if (!empty($entityManager['dql'])) { foreach ($entityManager['dql']['string_functions'] as $name => $function) { $ormConfigDef->addMethodCall('addCustomStringFunction', array ($name, $function)); diff --git a/src/Symfony/Bundle/DoctrineBundle/Resources/config/dbal.xml b/src/Symfony/Bundle/DoctrineBundle/Resources/config/dbal.xml index 957fd84f80..6207f9e068 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Resources/config/dbal.xml +++ b/src/Symfony/Bundle/DoctrineBundle/Resources/config/dbal.xml @@ -20,11 +20,12 @@ + - + diff --git a/src/Symfony/Bundle/DoctrineBundle/Resources/config/schema/doctrine-1.0.xsd b/src/Symfony/Bundle/DoctrineBundle/Resources/config/schema/doctrine-1.0.xsd index f1ae69e2f0..99021559ee 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Resources/config/schema/doctrine-1.0.xsd +++ b/src/Symfony/Bundle/DoctrineBundle/Resources/config/schema/doctrine-1.0.xsd @@ -43,8 +43,11 @@ - - + + + + + @@ -93,6 +96,7 @@ + @@ -111,7 +115,10 @@ - - + + + + + diff --git a/src/Symfony/Bundle/DoctrineBundle/Resources/views/Collector/db.html.twig b/src/Symfony/Bundle/DoctrineBundle/Resources/views/Collector/db.html.twig index 314eb3cb07..b90a1d91bb 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Resources/views/Collector/db.html.twig +++ b/src/Symfony/Bundle/DoctrineBundle/Resources/views/Collector/db.html.twig @@ -1,4 +1,4 @@ -{% extends 'WebProfiler:Profiler:layout.html.twig' %} +{% extends 'WebProfilerBundle:Profiler:layout.html.twig' %} {% block toolbar %} {% set icon %} @@ -7,7 +7,7 @@ {% set text %} {{ collector.querycount }} {% endset %} - {% include 'WebProfiler:Profiler:toolbar_item.html.twig' with { 'link': profiler_url } %} + {% include 'WebProfilerBundle:Profiler:toolbar_item.html.twig' with { 'link': profiler_url } %} {% endblock %} {% block menu %} diff --git a/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php b/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php index 8248188cd1..5ded6f3423 100755 --- a/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php +++ b/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php @@ -112,7 +112,7 @@ abstract class AbstractDoctrineExtensionTest extends TestCase $container = $this->getContainer(); $loader = new DoctrineExtension(); - $loader->load(array(array('dbal' => null, 'orm' => array('default_entity_manager' => 'default', 'entity_managers' => array('default' => array('mappings' => array('Yaml' => array())))))), $container); + $loader->load(array(array('dbal' => null, 'orm' => array('default_entity_manager' => 'default', 'entity_managers' => array('default' => array('mappings' => array('YamlBundle' => array())))))), $container); $this->assertFalse($container->getParameter('doctrine.orm.auto_generate_proxy_classes')); $this->assertEquals('Doctrine\ORM\Configuration', $container->getParameter('doctrine.orm.configuration_class')); @@ -137,7 +137,7 @@ abstract class AbstractDoctrineExtensionTest extends TestCase 'default_entity_manager' => 'default', 'entity_managers' => array( 'default' => array( - 'mappings' => array('Yaml' => array()), + 'mappings' => array('YamlBundle' => array()), ) ) ); @@ -171,7 +171,7 @@ abstract class AbstractDoctrineExtensionTest extends TestCase $definition = $container->getDefinition('doctrine.orm.default_configuration'); $calls = array_values($definition->getMethodCalls()); - $this->assertEquals(array('Yaml' => 'Fixtures\Bundles\YamlBundle\Entity'), $calls[0][1][0]); + $this->assertEquals(array('YamlBundle' => 'Fixtures\Bundles\YamlBundle\Entity'), $calls[0][1][0]); $this->assertEquals('doctrine.orm.default_metadata_cache', (string) $calls[1][1][0]); $this->assertEquals('doctrine.orm.default_query_cache', (string) $calls[2][1][0]); $this->assertEquals('doctrine.orm.default_result_cache', (string) $calls[3][1][0]); @@ -191,7 +191,7 @@ abstract class AbstractDoctrineExtensionTest extends TestCase $container = $this->getContainer(); $loader = new DoctrineExtension(); - $loader->load(array(array('dbal' => null, 'orm' => array('default_entity_manager' => 'default', 'entity_managers' => array('default' => array('mappings' => array('Yaml' => array())))))), $container); + $loader->load(array(array('dbal' => null, 'orm' => array('default_entity_manager' => 'default', 'entity_managers' => array('default' => array('mappings' => array('YamlBundle' => array())))))), $container); $definition = $container->getDefinition('doctrine.dbal.default_connection'); $this->assertEquals('Doctrine\DBAL\Connection', $definition->getClass()); @@ -362,11 +362,11 @@ abstract class AbstractDoctrineExtensionTest extends TestCase $container = $this->getContainer(); $loader = new DoctrineExtension(); - $loader->load(array(array('orm' => array('default_entity_manager' => 'default', 'entity_managers' => array('default' => array('mappings' => array('Yaml' => array())))))), $container); + $loader->load(array(array('orm' => array('default_entity_manager' => 'default', 'entity_managers' => array('default' => array('mappings' => array('YamlBundle' => array())))))), $container); $definition = $container->getDefinition('doctrine.orm.default_configuration'); $this->assertDICDefinitionMethodCallOnce($definition, 'setEntityNamespaces', - array(array('Yaml' => 'Fixtures\Bundles\YamlBundle\Entity')) + array(array('YamlBundle' => 'Fixtures\Bundles\YamlBundle\Entity')) ); } @@ -375,7 +375,7 @@ abstract class AbstractDoctrineExtensionTest extends TestCase $container = $this->getContainer(); $loader = new DoctrineExtension(); - $loader->load(array(array('orm' => array('default_entity_manager' => 'default', 'entity_managers' => array('default' => array('mappings' => array('Yaml' => array('alias' => 'yml'))))))), $container); + $loader->load(array(array('orm' => array('default_entity_manager' => 'default', 'entity_managers' => array('default' => array('mappings' => array('YamlBundle' => array('alias' => 'yml'))))))), $container); $definition = $container->getDefinition('doctrine.orm.default_configuration'); $this->assertDICDefinitionMethodCallOnce($definition, 'setEntityNamespaces', @@ -388,7 +388,7 @@ abstract class AbstractDoctrineExtensionTest extends TestCase $container = $this->getContainer('YamlBundle'); $loader = new DoctrineExtension(); - $loader->load(array(array('orm' => array('default_entity_manager' => 'default', 'entity_managers' => array('default' => array('mappings' => array('Yaml' => array())))))), $container); + $loader->load(array(array('orm' => array('default_entity_manager' => 'default', 'entity_managers' => array('default' => array('mappings' => array('YamlBundle' => array())))))), $container); $definition = $container->getDefinition('doctrine.orm.default_metadata_driver'); $this->assertDICDefinitionMethodCallOnce($definition, 'addDriver', array( @@ -402,7 +402,7 @@ abstract class AbstractDoctrineExtensionTest extends TestCase $container = $this->getContainer('XmlBundle'); $loader = new DoctrineExtension(); - $loader->load(array(array('orm' => array('default_entity_manager' => 'default', 'entity_managers' => array('default' => array('mappings' => array('Xml' => array())))))), $container); + $loader->load(array(array('orm' => array('default_entity_manager' => 'default', 'entity_managers' => array('default' => array('mappings' => array('XmlBundle' => array())))))), $container); $definition = $container->getDefinition('doctrine.orm.default_metadata_driver'); $this->assertDICDefinitionMethodCallOnce($definition, 'addDriver', array( @@ -416,7 +416,7 @@ abstract class AbstractDoctrineExtensionTest extends TestCase $container = $this->getContainer('AnnotationsBundle'); $loader = new DoctrineExtension(); - $loader->load(array(array('orm' => array('default_entity_manager' => 'default', 'entity_managers' => array('default' => array('mappings' => array('Annotations' => array())))))), $container); + $loader->load(array(array('orm' => array('default_entity_manager' => 'default', 'entity_managers' => array('default' => array('mappings' => array('AnnotationsBundle' => array())))))), $container); $definition = $container->getDefinition('doctrine.orm.default_metadata_driver'); $this->assertDICDefinitionMethodCallOnce($definition, 'addDriver', array( @@ -434,13 +434,13 @@ abstract class AbstractDoctrineExtensionTest extends TestCase 'auto_generate_proxy_classes' => true, 'default_entity_manager' => 'default', 'entity_managers' => array( - 'default' => array('mappings' => array('Annotations' => array())) + 'default' => array('mappings' => array('AnnotationsBundle' => array())) ))), array('orm' => array( 'auto_generate_proxy_classes' => false, 'default_entity_manager' => 'default', 'entity_managers' => array( - 'default' => array('mappings' => array('Xml' => array())) + 'default' => array('mappings' => array('XmlBundle' => array())) )))), $container); $definition = $container->getDefinition('doctrine.orm.default_metadata_driver'); @@ -628,7 +628,7 @@ abstract class AbstractDoctrineExtensionTest extends TestCase $container = $this->getContainer('AnnotationsBundle', 'Vendor'); $loader = new DoctrineExtension(); - $loader->load(array(array('orm' => array('default_entity_manager' => 'default', 'entity_managers' => array('default' => array('mappings' => array('Annotations' => array())))))), $container); + $loader->load(array(array('orm' => array('default_entity_manager' => 'default', 'entity_managers' => array('default' => array('mappings' => array('AnnotationsBundle' => array())))))), $container); $calls = $container->getDefinition('doctrine.orm.default_metadata_driver')->getMethodCalls(); $this->assertEquals('doctrine.orm.default_annotation_metadata_driver', (string) $calls[0][1][0]); @@ -669,6 +669,21 @@ abstract class AbstractDoctrineExtensionTest extends TestCase $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomDatetimeFunction', array('test_datetime', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestDatetimeFunction')); } + public function testAddCustomHydrationMode() + { + $container = $this->getContainer(array('YamlBundle')); + + $loader = new DoctrineExtension(); + $container->registerExtension($loader); + $this->loadFromFile($container, 'orm_hydration_mode'); + $container->getCompilerPassConfig()->setOptimizationPasses(array()); + $container->getCompilerPassConfig()->setRemovingPasses(array()); + $container->compile(); + + $definition = $container->getDefinition('doctrine.orm.default_configuration'); + $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomHydrationMode', array('test_hydrator', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestHydrator')); + } + protected function getContainer($bundles = 'YamlBundle', $vendor = null) { if (!is_array($bundles)) { @@ -679,7 +694,7 @@ abstract class AbstractDoctrineExtensionTest extends TestCase foreach ($bundles as $bundle) { require_once __DIR__.'/Fixtures/Bundles/'.($vendor ? $vendor.'/' : '').$bundle.'/'.$bundle.'.php'; - $map[substr($bundle, 0, -6)] = 'Fixtures\\Bundles\\'.($vendor ? $vendor.'\\' : '').$bundle.'\\'.$bundle; + $map[$bundle] = 'Fixtures\\Bundles\\'.($vendor ? $vendor.'\\' : '').$bundle.'\\'.$bundle; } return new ContainerBuilder(new ParameterBag(array( diff --git a/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_types.xml b/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_types.xml index 7bbad12c7f..368cc890e1 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_types.xml +++ b/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_types.xml @@ -8,7 +8,7 @@ - + Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestType diff --git a/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_functions.xml b/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_functions.xml index 072a5aa2a5..07814ab913 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_functions.xml +++ b/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_functions.xml @@ -10,11 +10,11 @@ - + - - - + Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestStringFunction + Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestNumericFunction + Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestDatetimeFunction diff --git a/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_hydration_mode.xml b/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_hydration_mode.xml new file mode 100644 index 0000000000..03e8a766de --- /dev/null +++ b/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_hydration_mode.xml @@ -0,0 +1,18 @@ + + + + + + + + + Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestHydrator + + + + + diff --git a/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_imports_import.xml b/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_imports_import.xml index 4368b1ebab..f8a514f198 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_imports_import.xml +++ b/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_imports_import.xml @@ -12,7 +12,7 @@ default-entity-manager="default" > - + diff --git a/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_multiple_em_bundle_mappings.xml b/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_multiple_em_bundle_mappings.xml index 0ec0959667..58569052ea 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_multiple_em_bundle_mappings.xml +++ b/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_multiple_em_bundle_mappings.xml @@ -9,10 +9,10 @@ - + - + - + - + diff --git a/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_service_simple_single_entity_manager.xml b/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_service_simple_single_entity_manager.xml index f18807fec9..8ecceb4bc7 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_service_simple_single_entity_manager.xml +++ b/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_service_simple_single_entity_manager.xml @@ -16,7 +16,7 @@ 11211 Memcache - + diff --git a/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_service_single_entity_manager.xml b/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_service_single_entity_manager.xml index deba0e813e..d73955f9ee 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_service_single_entity_manager.xml +++ b/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_service_single_entity_manager.xml @@ -32,7 +32,7 @@ 11211 Memcache - + diff --git a/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_single_em_bundle_mappings.xml b/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_single_em_bundle_mappings.xml index 0a8640998f..273d368acd 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_single_em_bundle_mappings.xml +++ b/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_single_em_bundle_mappings.xml @@ -9,8 +9,8 @@ - - + + false, - 'kernel.bundles' => array('Yaml' => 'Fixtures\Bundles\YamlBundle\YamlBundle'), + 'kernel.bundles' => array('YamlBundle' => 'Fixtures\Bundles\YamlBundle\YamlBundle'), 'kernel.cache_dir' => sys_get_temp_dir(), 'kernel.root_dir' => __DIR__ . "/../../../../" // src dir ))); @@ -74,7 +74,7 @@ class TestCase extends \PHPUnit_Framework_TestCase 'default_entity_manager' => 'default', 'entity_managers' => array ( 'default' => array( - 'mappings' => array('Yaml' => array( + 'mappings' => array('YamlBundle' => array( 'type' => 'yml', 'dir' => __DIR__ . "/DependencyInjection/Fixtures/Bundles/YamlBundle/Resources/config/doctrine/metadata/orm", 'prefix' => 'Fixtures\Bundles\YamlBundle', diff --git a/src/Symfony/Bundle/DoctrineMigrationsBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/DoctrineMigrationsBundle/DependencyInjection/Configuration.php index 55da72709c..93d56b12e1 100644 --- a/src/Symfony/Bundle/DoctrineMigrationsBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/DoctrineMigrationsBundle/DependencyInjection/Configuration.php @@ -3,20 +3,21 @@ namespace Symfony\Bundle\DoctrineMigrationsBundle\DependencyInjection; use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; /** * DoctrineMigrationsExtension configuration structure. * * @author Lukas Kahwe Smith */ -class Configuration +class Configuration implements ConfigurationInterface { /** - * Generates the configuration tree. + * Generates the configuration tree builder. * - * @return \Symfony\Component\Config\Definition\ArrayNode The config tree + * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder */ - public function getConfigTree() + public function getConfigTreeBuilder() { $treeBuilder = new TreeBuilder(); $rootNode = $treeBuilder->root('doctrine_migrations', 'array'); @@ -30,6 +31,6 @@ class Configuration ->end() ; - return $treeBuilder->buildTree(); + return $treeBuilder; } } diff --git a/src/Symfony/Bundle/DoctrineMigrationsBundle/DependencyInjection/DoctrineMigrationsExtension.php b/src/Symfony/Bundle/DoctrineMigrationsBundle/DependencyInjection/DoctrineMigrationsExtension.php index af9a9cbf55..d9c6e332f3 100644 --- a/src/Symfony/Bundle/DoctrineMigrationsBundle/DependencyInjection/DoctrineMigrationsExtension.php +++ b/src/Symfony/Bundle/DoctrineMigrationsBundle/DependencyInjection/DoctrineMigrationsExtension.php @@ -11,9 +11,9 @@ namespace Symfony\Bundle\DoctrineMigrationsBundle\DependencyInjection; -use Symfony\Component\Config\Definition\Processor; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\DependencyInjection\Extension; +use Symfony\Component\Config\Definition\Processor; /** * DoctrineMigrationsExtension. @@ -33,7 +33,7 @@ class DoctrineMigrationsExtension extends Extension $processor = new Processor(); $configuration = new Configuration(); - $config = $processor->process($configuration->getConfigTree(), $configs); + $config = $processor->processConfiguration($configuration, $configs); foreach ($config as $key => $value) { $container->setParameter($this->getAlias().'.'.$key, $value); diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/CacheWarmer/HydratorCacheWarmer.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/CacheWarmer/HydratorCacheWarmer.php deleted file mode 100644 index ca875c01a0..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/CacheWarmer/HydratorCacheWarmer.php +++ /dev/null @@ -1,76 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\CacheWarmer; - -use Symfony\Component\DependencyInjection\Container; -use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface; - -/** - * The hydrator generator cache warmer generates all document hydrators. - * - * In the process of generating hydrators the cache for all the metadata is primed also, - * since this information is necessary to build the hydrators in the first place. - * - * @author Benjamin Eberlei - * @author Jonathan H. Wage - */ -class HydratorCacheWarmer implements CacheWarmerInterface -{ - /** - * @var Container - */ - private $container; - - /** - * @param Container $container - */ - public function __construct(Container $container) - { - $this->container = $container; - } - - /** - * This cache warmer is not optional, without hydrators fatal error occurs! - * - * @return false - */ - public function isOptional() - { - return false; - } - - public function warmUp($cacheDir) - { - // we need the directory no matter the hydrator cache generation strategy. - $hydratorCacheDir = $this->container->getParameter('doctrine.odm.mongodb.hydrator_dir'); - if (!file_exists($hydratorCacheDir)) { - if (false === @mkdir($hydratorCacheDir, 0777, true)) { - throw new \RuntimeException(sprintf('Unable to create the Doctrine Hydrator directory (%s)', dirname($hydratorCacheDir))); - } - } else if (!is_writable($hydratorCacheDir)) { - throw new \RuntimeException(sprintf('Doctrine Hydrator directory (%s) is not writeable for the current system user.', $hydratorCacheDir)); - } - - // if hydrators are autogenerated we don't need to generate them in the cache warmer. - if ($this->container->getParameter('doctrine.odm.mongodb.auto_generate_hydrator_classes') === true) { - return; - } - - $documentManagers = $this->container->getParameter('doctrine.odm.mongodb.document_managers'); - foreach ($documentManagers as $documentManagerName) { - $dm = $this->container->get(sprintf('doctrine.odm.mongodb.%s_document_manager', $documentManagerName)); - /* @var $dm Doctrine\ODM\MongoDB\DocumentManager */ - $classes = $dm->getMetadataFactory()->getAllMetadata(); - $dm->getHydratorFactory()->generateHydratorClasses($classes); - } - } -} \ No newline at end of file diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/CacheWarmer/ProxyCacheWarmer.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/CacheWarmer/ProxyCacheWarmer.php deleted file mode 100644 index 0fb7870521..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/CacheWarmer/ProxyCacheWarmer.php +++ /dev/null @@ -1,76 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\CacheWarmer; - -use Symfony\Component\DependencyInjection\Container; -use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface; - -/** - * The proxy generator cache warmer generates all document proxies. - * - * In the process of generating proxies the cache for all the metadata is primed also, - * since this information is necessary to build the proxies in the first place. - * - * @author Benjamin Eberlei - * @author Jonathan H. Wage - */ -class ProxyCacheWarmer implements CacheWarmerInterface -{ - /** - * @var Container - */ - private $container; - - /** - * @param Container $container - */ - public function __construct(Container $container) - { - $this->container = $container; - } - - /** - * This cache warmer is not optional, without proxies fatal error occurs! - * - * @return false - */ - public function isOptional() - { - return false; - } - - public function warmUp($cacheDir) - { - // we need the directory no matter the proxy cache generation strategy. - $proxyCacheDir = $this->container->getParameter('doctrine.odm.mongodb.proxy_dir'); - if (!file_exists($proxyCacheDir)) { - if (false === @mkdir($proxyCacheDir, 0777, true)) { - throw new \RuntimeException(sprintf('Unable to create the Doctrine Proxy directory (%s)', dirname($proxyCacheDir))); - } - } else if (!is_writable($proxyCacheDir)) { - throw new \RuntimeException(sprintf('Doctrine Proxy directory (%s) is not writeable for the current system user.', $proxyCacheDir)); - } - - // if proxies are autogenerated we don't need to generate them in the cache warmer. - if ($this->container->getParameter('doctrine.odm.mongodb.auto_generate_proxy_classes') === true) { - return; - } - - $documentManagers = $this->container->getParameter('doctrine.odm.mongodb.document_managers'); - foreach ($documentManagers as $documentManagerName) { - $dm = $this->container->get(sprintf('doctrine.odm.mongodb.%s_document_manager', $documentManagerName)); - /* @var $dm Doctrine\ODM\MongoDB\DocumentManager */ - $classes = $dm->getMetadataFactory()->getAllMetadata(); - $dm->getProxyFactory()->generateProxyClasses($classes); - } - } -} \ No newline at end of file diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/ClearMetadataCacheDoctrineODMCommand.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/ClearMetadataCacheDoctrineODMCommand.php deleted file mode 100644 index be10a906d2..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/ClearMetadataCacheDoctrineODMCommand.php +++ /dev/null @@ -1,54 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\Command; - -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Doctrine\ODM\MongoDB\Tools\Console\Command\ClearCache\MetadataCommand; - -/** - * Command to clear the metadata cache of the various cache drivers. - * - * @author Fabien Potencier - * @author Jonathan H. Wage - * @author Henrik Westphal - */ -class ClearMetadataCacheDoctrineODMCommand extends MetadataCommand -{ - protected function configure() - { - parent::configure(); - - $this - ->setName('doctrine:mongodb:cache:clear-metadata') - ->setDescription('Clear all metadata cache for a document manager.') - ->addOption('dm', null, InputOption::VALUE_OPTIONAL, 'The document manager to use for this command.') - ->setHelp(<<doctrine:mongodb:cache:clear-metadata command clears all metadata cache for the default document manager: - - ./app/console doctrine:mongodb:cache:clear-metadata - -You can also optionally specify the --dm option to specify which document manager to clear the cache for: - - ./app/console doctrine:mongodb:cache:clear-metadata --dm=default -EOT - ); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - DoctrineODMCommand::setApplicationDocumentManager($this->getApplication(), $input->getOption('dm')); - - return parent::execute($input, $output); - } -} \ No newline at end of file diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/CreateSchemaDoctrineODMCommand.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/CreateSchemaDoctrineODMCommand.php deleted file mode 100644 index 78cc32e702..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/CreateSchemaDoctrineODMCommand.php +++ /dev/null @@ -1,53 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\Command; - -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Output\Output; -use Doctrine\ODM\MongoDB\Tools\Console\Command\Schema\CreateCommand; - -/** - * Command to create the database schema for a set of classes based on their mappings. - * - * @author Justin Hileman - */ -class CreateSchemaDoctrineODMCommand extends CreateCommand -{ - protected function configure() - { - parent::configure(); - - $this - ->setName('doctrine:mongodb:schema:create') - ->addOption('dm', null, InputOption::VALUE_REQUIRED, 'The document manager to use for this command.') - ->setHelp(<<doctrine:mongodb:schema:create command creates the default document manager's schema: - - ./app/console doctrine:mongodb:schema:create - -You can also optionally specify the name of a document manager to create the schema for: - - ./app/console doctrine:mongodb:schema:create --dm=default -EOT - ); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - DoctrineODMCommand::setApplicationDocumentManager($this->getApplication(), $input->getOption('dm')); - - parent::execute($input, $output); - } -} \ No newline at end of file diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/DoctrineODMCommand.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/DoctrineODMCommand.php deleted file mode 100644 index 61f1c1f221..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/DoctrineODMCommand.php +++ /dev/null @@ -1,120 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\Command; - -use Symfony\Bundle\FrameworkBundle\Command\Command; -use Symfony\Bundle\FrameworkBundle\Console\Application; -use Doctrine\ODM\MongoDB\Tools\Console\Helper\DocumentManagerHelper; -use Symfony\Component\HttpKernel\Bundle\Bundle; -use Doctrine\ODM\MongoDB\Tools\DisconnectedClassMetadataFactory; -use Doctrine\ODM\MongoDB\Tools\DocumentGenerator; - -/** - * Base class for Doctrine ODM console commands to extend. - * - * @author Justin Hileman - */ -abstract class DoctrineODMCommand extends Command -{ - public static function setApplicationDocumentManager(Application $application, $dmName) - { - $container = $application->getKernel()->getContainer(); - $dmName = $dmName ? $dmName : 'default'; - $dmServiceName = sprintf('doctrine.odm.mongodb.%s_document_manager', $dmName); - if (!$container->has($dmServiceName)) { - throw new \InvalidArgumentException(sprintf('Could not find Doctrine ODM DocumentManager named "%s"', $dmName)); - } - - $dm = $container->get($dmServiceName); - $helperSet = $application->getHelperSet(); - $helperSet->set(new DocumentManagerHelper($dm), 'dm'); - } - - protected function getDocumentGenerator() - { - $documentGenerator = new DocumentGenerator(); - $documentGenerator->setAnnotationPrefix('mongodb:'); - $documentGenerator->setGenerateAnnotations(false); - $documentGenerator->setGenerateStubMethods(true); - $documentGenerator->setRegenerateDocumentIfExists(false); - $documentGenerator->setUpdateDocumentIfExists(true); - $documentGenerator->setNumSpaces(4); - return $documentGenerator; - } - - protected function getDoctrineDocumentManagers() - { - $documentManagerNames = $this->container->getParameter('doctrine.odm.mongodb.document_managers'); - $documentManagers = array(); - foreach ($documentManagerNames as $documentManagerName) { - $dm = $this->container->get(sprintf('doctrine.odm.mongodb.%s_document_manager', $documentManagerName)); - $documentManagers[] = $dm; - } - return $documentManagers; - } - - protected function getBundleMetadatas(Bundle $bundle) - { - $namespace = $bundle->getNamespace(); - $bundleMetadatas = array(); - $documentManagers = $this->getDoctrineDocumentManagers(); - foreach ($documentManagers as $key => $dm) { - $cmf = new DisconnectedClassMetadataFactory(); - $cmf->setDocumentManager($dm); - $cmf->setConfiguration($dm->getConfiguration()); - $metadatas = $cmf->getAllMetadata(); - foreach ($metadatas as $metadata) { - if (strpos($metadata->name, $namespace) === 0) { - $bundleMetadatas[$metadata->name] = $metadata; - } - } - } - - return $bundleMetadatas; - } - - protected function findBundle($bundleName) - { - $foundBundle = false; - foreach ($this->getApplication()->getKernel()->getBundles() as $bundle) { - /* @var $bundle Bundle */ - if (strtolower($bundleName) == strtolower($bundle->getName())) { - $foundBundle = $bundle; - break; - } - } - - if (!$foundBundle) { - throw new \InvalidArgumentException("No bundle " . $bundleName . " was found."); - } - - return $foundBundle; - } - - /** - * Transform classname to a path $foundBundle substract it to get the destination - * - * @param Bundle $bundle - * @return string - */ - protected function findBasePathForBundle($bundle) - { - $path = str_replace('\\', '/', $bundle->getNamespace()); - $destination = str_replace('/'.$path, "", $bundle->getPath(), $c); - - if ($c != 1) { - throw new \RuntimeException("Something went terribly wrong."); - } - - return $destination; - } -} \ No newline at end of file diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/DropSchemaDoctrineODMCommand.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/DropSchemaDoctrineODMCommand.php deleted file mode 100644 index cb1ab9e888..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/DropSchemaDoctrineODMCommand.php +++ /dev/null @@ -1,53 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\Command; - -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Output\Output; -use Doctrine\ODM\MongoDB\Tools\Console\Command\Schema\DropCommand; - -/** - * Command to create the database schema for a set of classes based on their mappings. - * - * @author Justin Hileman - */ -class DropSchemaDoctrineODMCommand extends DropCommand -{ - protected function configure() - { - parent::configure(); - - $this - ->setName('doctrine:mongodb:schema:drop') - ->addOption('dm', null, InputOption::VALUE_REQUIRED, 'The document manager to use for this command.') - ->setHelp(<<doctrine:mongodb:schema:drop command drops the default document manager's schema: - - ./app/console doctrine:mongodb:schema:drop - -You can also optionally specify the name of a document manager to drop the schema for: - - ./app/console doctrine:mongodb:schema:drop --dm=default -EOT - ); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - DoctrineODMCommand::setApplicationDocumentManager($this->getApplication(), $input->getOption('dm')); - - parent::execute($input, $output); - } -} \ No newline at end of file diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/GenerateDocumentsDoctrineODMCommand.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/GenerateDocumentsDoctrineODMCommand.php deleted file mode 100644 index fabb536b59..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/GenerateDocumentsDoctrineODMCommand.php +++ /dev/null @@ -1,80 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\Command; - -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Output\Output; - -/** - * Generate document classes from mapping information - * - * @author Fabien Potencier - * @author Jonathan H. Wage - */ -class GenerateDocumentsDoctrineODMCommand extends DoctrineODMCommand -{ - protected function configure() - { - $this - ->setName('doctrine:mongodb:generate:documents') - ->setDescription('Generate document classes and method stubs from your mapping information.') - ->addArgument('bundle', InputArgument::REQUIRED, 'The bundle to initialize the document or documents in.') - ->addOption('document', null, InputOption::VALUE_OPTIONAL, 'The document class to initialize (shortname without namespace).') - ->setHelp(<<doctrine:mongodb:generate:documents command generates document classes and method stubs from your mapping information: - -You have to limit generation of documents to an individual bundle: - - ./app/console doctrine:mongodb:generate:documents MyCustomBundle - -Alternatively, you can limit generation to a single document within a bundle: - - ./app/console doctrine:mongodb:generate:documents "MyCustomBundle" --document="User" - -You have to specify the shortname (without namespace) of the document you want to filter for. -EOT - ); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $bundleName = $input->getArgument('bundle'); - $filterDocument = $input->getOption('document'); - - $foundBundle = $this->findBundle($bundleName); - - if ($metadatas = $this->getBundleMetadatas($foundBundle)) { - $output->writeln(sprintf('Generating documents for "%s"', $foundBundle->getName())); - $documentGenerator = $this->getDocumentGenerator(); - - foreach ($metadatas as $metadata) { - if ($filterDocument && $metadata->reflClass->getShortName() == $filterDocument) { - continue; - } - - if (strpos($metadata->name, $foundBundle->getNamespace()) === false) { - throw new \RuntimeException( - "Document " . $metadata->name . " and bundle don't have a common namespace, ". - "generation failed because the target directory cannot be detected."); - } - - $output->writeln(sprintf(' > generating %s', $metadata->name)); - $documentGenerator->generate(array($metadata), $this->findBasePathForBundle($foundBundle)); - } - } else { - throw new \RuntimeException("Bundle " . $bundleName . " does not contain any mapped documents."); - } - } -} diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/GenerateHydratorsDoctrineODMCommand.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/GenerateHydratorsDoctrineODMCommand.php deleted file mode 100644 index c025fae963..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/GenerateHydratorsDoctrineODMCommand.php +++ /dev/null @@ -1,54 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\Command; - -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Output\Output; -use Doctrine\ODM\MongoDB\Tools\Console\Command\GenerateHydratorsCommand; - -/** - * Generate the Doctrine ORM document hydrators to your cache directory. - * - * @author Fabien Potencier - * @author Jonathan H. Wage - */ -class GenerateHydratorsDoctrineODMCommand extends GenerateHydratorsCommand -{ - protected function configure() - { - parent::configure(); - - $this - ->setName('doctrine:mongodb:generate:hydrators') - ->addOption('dm', null, InputOption::VALUE_OPTIONAL, 'The document manager to use for this command.') - ->setHelp(<<doctrine:mongodb:generate:hydrators command generates hydrator classes for your documents: - - ./app/console doctrine:mongodb:generate:hydrators - -You can specify the document manager you want to generate the hydrators for: - - ./app/console doctrine:mongodb:generate:hydrators --dm=name -EOT - ); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - DoctrineODMCommand::setApplicationDocumentManager($this->getApplication(), $input->getOption('dm')); - - return parent::execute($input, $output); - } -} diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/GenerateProxiesDoctrineODMCommand.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/GenerateProxiesDoctrineODMCommand.php deleted file mode 100644 index ecf8b650b2..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/GenerateProxiesDoctrineODMCommand.php +++ /dev/null @@ -1,54 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\Command; - -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Output\Output; -use Doctrine\ODM\MongoDB\Tools\Console\Command\GenerateProxiesCommand; - -/** - * Generate the Doctrine ORM document proxies to your cache directory. - * - * @author Fabien Potencier - * @author Jonathan H. Wage - */ -class GenerateProxiesDoctrineODMCommand extends GenerateProxiesCommand -{ - protected function configure() - { - parent::configure(); - - $this - ->setName('doctrine:mongodb:generate:proxies') - ->addOption('dm', null, InputOption::VALUE_OPTIONAL, 'The document manager to use for this command.') - ->setHelp(<<doctrine:mongodb:generate:proxies command generates proxy classes for your default document manager: - - ./app/console doctrine:mongodb:generate:proxies - -You can specify the document manager you want to generate the proxies for: - - ./app/console doctrine:mongodb:generate:proxies --dm=name -EOT - ); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - DoctrineODMCommand::setApplicationDocumentManager($this->getApplication(), $input->getOption('dm')); - - return parent::execute($input, $output); - } -} diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/GenerateRepositoriesDoctrineODMCommand.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/GenerateRepositoriesDoctrineODMCommand.php deleted file mode 100644 index 3233cbab82..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/GenerateRepositoriesDoctrineODMCommand.php +++ /dev/null @@ -1,77 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\Command; - -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Output\Output; -use Doctrine\ODM\MongoDB\Tools\DocumentRepositoryGenerator; - -/** - * Command to generate repository classes for mapping information. - * - * @author Fabien Potencier - * @author Jonathan H. Wage - */ -class GenerateRepositoriesDoctrineODMCommand extends DoctrineODMCommand -{ - protected function configure() - { - $this - ->setName('doctrine:mongodb:generate:repositories') - ->setDescription('Generate repository classes from your mapping information.') - ->addArgument('bundle', InputArgument::REQUIRED, 'The bundle to initialize the repositories in.') - ->addOption('document', null, InputOption::VALUE_OPTIONAL, 'The document class to generate the repository for (shortname without namespace).') - ->setHelp(<<doctrine:mongodb:generate:repositories command generates the configured document repository classes from your mapping information: - - ./app/console doctrine:mongodb:generate:repositories -EOT - ); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $bundleName = $input->getArgument('bundle'); - $filterDocument = $input->getOption('document'); - - $foundBundle = $this->findBundle($bundleName); - - if ($metadatas = $this->getBundleMetadatas($foundBundle)) { - $output->writeln(sprintf('Generating document repositories for "%s"', $foundBundle->getName())); - $generator = new DocumentRepositoryGenerator(); - - foreach ($metadatas as $metadata) { - if ($filterDocument && $filterDocument !== $metadata->reflClass->getShortname()) { - continue; - } - - if ($metadata->customRepositoryClassName) { - if (strpos($metadata->customRepositoryClassName, $foundBundle->getNamespace()) === false) { - throw new \RuntimeException( - "Repository " . $metadata->customRepositoryClassName . " and bundle don't have a common namespace, ". - "generation failed because the target directory cannot be detected."); - } - - $output->writeln(sprintf(' > OK generating %s', $metadata->customRepositoryClassName)); - $generator->writeDocumentRepositoryClass($metadata->customRepositoryClassName, $this->findBasePathForBundle($foundBundle)); - } else { - $output->writeln(sprintf(' > SKIP no custom repository for %s', $metadata->name)); - } - } - } else { - throw new \RuntimeException("Bundle " . $bundleName . " does not contain any mapped documents."); - } - } -} diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/InfoDoctrineODMCommand.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/InfoDoctrineODMCommand.php deleted file mode 100644 index 51779b22d6..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/InfoDoctrineODMCommand.php +++ /dev/null @@ -1,84 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\Command; - -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * Show information about mapped documents - * - * @author Benjamin Eberlei - * @author Jonathan H. Wage - */ -class InfoDoctrineODMCommand extends DoctrineODMCommand -{ - protected function configure() - { - $this - ->setName('doctrine:mongodb:mapping:info') - ->addOption('dm', null, InputOption::VALUE_OPTIONAL, 'The document manager to use for this command.') - ->setDescription('Show basic information about all mapped documents.') - ->setHelp(<<doctrine:mongodb:mapping:info shows basic information about which -documents exist and possibly if their mapping information contains errors or not. - - ./app/console doctrine:mongodb:mapping:info - -If you are using multiple document managers you can pick your choice with the --dm option: - - ./app/console doctrine:mongodb:mapping:info --dm=default -EOT - ); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $documentManagerName = $input->getOption('dm') ? - $input->getOption('dm') : - $this->container->getParameter('doctrine.odm.mongodb.default_document_manager'); - - $documentManagerService = sprintf('doctrine.odm.mongodb.%s_document_manager', $documentManagerName); - - /* @var $documentManager Doctrine\ODM\MongoDB\DocumentManager */ - $documentManager = $this->container->get($documentManagerService); - - $documentClassNames = $documentManager->getConfiguration() - ->getMetadataDriverImpl() - ->getAllClassNames(); - - if (!$documentClassNames) { - throw new \Exception( - 'You do not have any mapped Doctrine MongoDB ODM documents for any of your bundles. '. - 'Create a class inside the Document namespace of any of your bundles and provide '. - 'mapping information for it with Annotations directly in the classes doc blocks '. - 'or with XML/YAML in your bundles Resources/config/doctrine/metadata/mongodb directory.' - ); - } - - $output->write(sprintf("Found %d documents mapped in document manager %s:\n", - count($documentClassNames), $documentManagerName), true); - - foreach ($documentClassNames AS $documentClassName) { - try { - $cm = $documentManager->getClassMetadata($documentClassName); - $output->write("[OK] " . $documentClassName, true); - } catch(\Exception $e) { - $output->write("[FAIL] " . $documentClassName, true); - $output->write("" . $e->getMessage()."", true); - $output->write("", true); - } - } - } -} diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/LoadDataFixturesDoctrineODMCommand.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/LoadDataFixturesDoctrineODMCommand.php deleted file mode 100644 index f7ec8481db..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/LoadDataFixturesDoctrineODMCommand.php +++ /dev/null @@ -1,108 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\Command; - -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Output\Output; -use Symfony\Component\Finder\Finder; -use Symfony\Component\HttpKernel\Util\Filesystem; -use Symfony\Bundle\DoctrineAbstractBundle\Common\DataFixtures\Loader as DataFixturesLoader; -use Doctrine\Common\DataFixtures\Executor\MongoDBExecutor; -use Doctrine\Common\DataFixtures\Purger\MongoDBPurger; -use Doctrine\ODM\MongoDB\DocumentManager; -use Doctrine\ODM\MongoDB\Internal\CommitOrderCalculator; -use Doctrine\ODM\MongoDB\Mapping\ClassMetadata; -use InvalidArgumentException; - -/** - * Load data fixtures from bundles. - * - * @author Fabien Potencier - * @author Jonathan H. Wage - */ -class LoadDataFixturesDoctrineODMCommand extends DoctrineODMCommand -{ - protected function configure() - { - $this - ->setName('doctrine:mongodb:data:load') - ->setDescription('Load data fixtures to your database.') - ->addOption('fixtures', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The directory or file to load data fixtures from.') - ->addOption('append', null, InputOption::VALUE_OPTIONAL, 'Whether or not to append the data fixtures.', false) - ->addOption('dm', null, InputOption::VALUE_REQUIRED, 'The document manager to use for this command.') - ->setHelp(<<doctrine:mongodb:data:load command loads data fixtures from your bundles: - - ./app/console doctrine:mongodb:data:load - -You can also optionally specify the path to fixtures with the --fixtures option: - - ./app/console doctrine:mongodb:data:load --fixtures=/path/to/fixtures1 --fixtures=/path/to/fixtures2 - -If you want to append the fixtures instead of flushing the database first you can use the --append option: - - ./app/console doctrine:mongodb:data:load --append -EOT - ); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $dmName = $input->getOption('dm'); - $dmName = $dmName ? $dmName : 'default'; - $dmServiceName = sprintf('doctrine.odm.mongodb.%s_document_manager', $dmName); - - if (!$this->container->has($dmServiceName)) { - throw new InvalidArgumentException( - sprintf( - 'Could not find a document manager configured with the name "%s". Check your '. - 'application configuration to configure your Doctrine document managers.', $dmName - ) - ); - } - - $dm = $this->container->get($dmServiceName); - $dirOrFile = $input->getOption('fixtures'); - if ($dirOrFile) { - $paths = is_array($dirOrFile) ? $dirOrFile : array($dirOrFile); - } else { - $paths = array(); - foreach ($this->container->get('kernel')->getBundles() as $bundle) { - $paths[] = $bundle->getPath().'/DataFixtures/MongoDB'; - } - } - - $loader = new DataFixturesLoader($this->container); - foreach ($paths as $path) { - if (is_dir($path)) { - $loader->loadFromDirectory($path); - } - } - - $fixtures = $loader->getFixtures(); - if (!$fixtures) { - throw new InvalidArgumentException( - sprintf('Could not find any fixtures to load in: %s', "\n\n- ".implode("\n- ", $paths)) - ); - } - - $purger = new MongoDBPurger($dm); - $executor = new MongoDBExecutor($dm, $purger); - $executor->setLogger(function($message) use ($output) { - $output->writeln(sprintf(' > %s', $message)); - }); - $executor->execute($fixtures, $input->getOption('append')); - } -} \ No newline at end of file diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/QueryDoctrineODMCommand.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/QueryDoctrineODMCommand.php deleted file mode 100644 index fdacd39768..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Command/QueryDoctrineODMCommand.php +++ /dev/null @@ -1,44 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\Command; - -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Output\Output; -use Doctrine\ODM\MongoDB\Tools\Console\Command\QueryCommand; - -/** - * Execute a Doctrine MongoDB ODM query and output the results. - * - * @author Fabien Potencier - * @author Jonathan H. Wage - */ -class QueryDoctrineODMCommand extends QueryCommand -{ - protected function configure() - { - parent::configure(); - - $this - ->setName('doctrine:mongodb:query') - ->addOption('dm', null, InputOption::VALUE_OPTIONAL, 'The document manager to use for this command.'); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - DoctrineODMCommand::setApplicationDocumentManager($this->getApplication(), $input->getOption('dm')); - - return parent::execute($input, $output); - } -} \ No newline at end of file diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/DataCollector/DoctrineMongoDBDataCollector.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/DataCollector/DoctrineMongoDBDataCollector.php deleted file mode 100644 index e6c14eca15..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/DataCollector/DoctrineMongoDBDataCollector.php +++ /dev/null @@ -1,59 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\DataCollector; - -use Symfony\Component\HttpKernel\DataCollector\DataCollector; -use Symfony\Bundle\DoctrineMongoDBBundle\Logger\DoctrineMongoDBLogger; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Data collector for the Doctrine MongoDB ODM. - * - * @author Kris Wallsmith - */ -class DoctrineMongoDBDataCollector extends DataCollector -{ - protected $logger; - - public function __construct(DoctrineMongoDBLogger $logger) - { - $this->logger = $logger; - } - - /** - * {@inheritdoc} - */ - public function collect(Request $request, Response $response, \Exception $exception = null) - { - $this->data['nb_queries'] = $this->logger->getNbQueries(); - $this->data['queries'] = $this->logger->getQueries(); - } - - public function getQueryCount() - { - return $this->data['nb_queries']; - } - - public function getQueries() - { - return $this->data['queries']; - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return 'mongodb'; - } -} diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/DependencyInjection/Compiler/CreateHydratorDirectoryPass.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/DependencyInjection/Compiler/CreateHydratorDirectoryPass.php deleted file mode 100644 index 1855c4e827..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/DependencyInjection/Compiler/CreateHydratorDirectoryPass.php +++ /dev/null @@ -1,30 +0,0 @@ -hasParameter('doctrine.odm.mongodb.hydrator_dir')) { - return; - } - // Don't do anything if auto_generate_hydrator_classes is false - if (!$container->getParameter('doctrine.odm.mongodb.auto_generate_hydrator_classes')) { - return; - } - // Create document proxy directory - $hydratorCacheDir = $container->getParameter('doctrine.odm.mongodb.hydrator_dir'); - if (!is_dir($hydratorCacheDir)) { - if (false === @mkdir($hydratorCacheDir, 0777, true)) { - exit(sprintf('Unable to create the Doctrine Hydrator directory (%s)', dirname($hydratorCacheDir))); - } - } elseif (!is_writable($hydratorCacheDir)) { - exit(sprintf('Unable to write in the Doctrine Hydrator directory (%s)', $hydratorCacheDir)); - } - } - -} diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/DependencyInjection/Compiler/CreateProxyDirectoryPass.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/DependencyInjection/Compiler/CreateProxyDirectoryPass.php deleted file mode 100644 index e14cc9e503..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/DependencyInjection/Compiler/CreateProxyDirectoryPass.php +++ /dev/null @@ -1,30 +0,0 @@ -hasParameter('doctrine.odm.mongodb.proxy_dir')) { - return; - } - // Don't do anything if auto_generate_proxy_classes is false - if (!$container->getParameter('doctrine.odm.mongodb.auto_generate_proxy_classes')) { - return; - } - // Create document proxy directory - $proxyCacheDir = $container->getParameter('doctrine.odm.mongodb.proxy_dir'); - if (!is_dir($proxyCacheDir)) { - if (false === @mkdir($proxyCacheDir, 0777, true)) { - exit(sprintf('Unable to create the Doctrine Proxy directory (%s)', dirname($proxyCacheDir))); - } - } elseif (!is_writable($proxyCacheDir)) { - exit(sprintf('Unable to write in the Doctrine Proxy directory (%s)', $proxyCacheDir)); - } - } - -} diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/DependencyInjection/Compiler/RegisterEventListenersAndSubscribersPass.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/DependencyInjection/Compiler/RegisterEventListenersAndSubscribersPass.php deleted file mode 100644 index b104c57845..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/DependencyInjection/Compiler/RegisterEventListenersAndSubscribersPass.php +++ /dev/null @@ -1,59 +0,0 @@ -container = $container; - foreach ($container->findTaggedServiceIds('doctrine.odm.mongodb.event_manager') as $id => $tag) { - $definition = $container->getDefinition($id); - $prefix = substr($id, 0, -1 * strlen('_event_manager')); - $this->registerListeners($prefix, $definition); - $this->registerSubscribers($prefix, $definition); - } - } - - protected function registerSubscribers($prefix, $definition) - { - $subscribers = array_merge( - $this->container->findTaggedServiceIds('doctrine.common.event_subscriber'), - $this->container->findTaggedServiceIds($prefix.'_event_subscriber') - ); - - foreach ($subscribers as $id => $instances) { - $definition->addMethodCall('addEventSubscriber', array(new Reference($id))); - } - } - - protected function registerListeners($prefix, $definition) - { - $listeners = array_merge( - $this->container->findTaggedServiceIds('doctrine.common.event_listener'), - $this->container->findTaggedServiceIds($prefix.'_event_listener') - ); - - foreach ($listeners as $listenerId => $instances) { - $events = array(); - foreach ($instances as $attributes) { - if (isset($attributes['event'])) { - $events[] = $attributes['event']; - } - } - - if (0 < count($events)) { - $definition->addMethodCall('addEventListener', array( - $events, - new Reference($listenerId), - )); - } - } - } -} diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/DependencyInjection/Configuration.php deleted file mode 100644 index d422917059..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/DependencyInjection/Configuration.php +++ /dev/null @@ -1,190 +0,0 @@ - - */ -class Configuration -{ - private $debug; - - /** - * Constructor. - * - * @param Boolean $debug The kernel.debug value - */ - public function __construct($debug) - { - $this->debug = (Boolean) $debug; - } - - /** - * Generates the configuration tree. - * - * @return \Symfony\Component\Config\Definition\ArrayNode The config tree - */ - public function getConfigTree() - { - $treeBuilder = new TreeBuilder(); - $rootNode = $treeBuilder->root('doctrine_mongo_db'); - - $this->addDocumentManagersSection($rootNode); - $this->addConnectionsSection($rootNode); - - $rootNode - ->children() - ->scalarNode('proxy_namespace')->defaultValue('Proxies')->end() - ->scalarNode('auto_generate_proxy_classes')->defaultValue(false)->end() - ->scalarNode('hydrator_namespace')->defaultValue('Hydrators')->end() - ->scalarNode('auto_generate_hydrator_classes')->defaultValue(false)->end() - ->scalarNode('default_document_manager')->end() - ->scalarNode('default_connection')->end() - ->scalarNode('default_database')->defaultValue('default')->end() - ->end() - ; - - return $treeBuilder->buildTree(); - } - - /** - * Configures the "document_managers" section - */ - private function addDocumentManagersSection(ArrayNodeDefinition $rootNode) - { - $rootNode - ->fixXmlConfig('document_manager') - ->children() - ->arrayNode('document_managers') - ->useAttributeAsKey('id') - ->prototype('array') - //->performNoDeepMerging() - ->treatNullLike(array()) - ->append($this->getMetadataCacheDriverNode()) - ->children() - ->scalarNode('connection')->end() - ->scalarNode('database')->end() - ->booleanNode('logging')->defaultValue($this->debug)->end() - ->end() - ->fixXmlConfig('mapping') - ->append($this->getMappingsNode()) - ->end() - ->end() - ->end() - ; - } - - /** - * Adds the configuration for the "connections" key - */ - private function addConnectionsSection(ArrayNodeDefinition $rootNode) - { - $rootNode - ->fixXmlConfig('connection') - ->children() - ->arrayNode('connections') - ->useAttributeAsKey('id') - ->prototype('array') - ->performNoDeepMerging() - ->children() - ->scalarNode('server')->defaultNull()->end() - ->end() - ->append($this->addConnectionOptionsNode()) - ->end() - ->end() - ->end() - ; - } - - /** - * Returns the array node used for "mappings". - * - * This is used in two different parts of the tree. - * - * @param NodeBuilder $rootNode The parent node - * @return NodeBuilder - */ - protected function getMappingsNode() - { - $builder = new TreeBuilder(); - $node = $builder->root('mappings'); - - $node - ->useAttributeAsKey('name') - ->prototype('array') - ->beforeNormalization() - // if it's not an array, then the scalar is the type key - ->ifString() - ->then(function($v) { return array ('type' => $v); }) - ->end() - // I believe that "null" should *not* set the type - // it's guessed in AbstractDoctrineExtension::detectMetadataDriver - ->treatNullLike(array()) - ->children() - ->scalarNode('type')->end() - ->scalarNode('dir')->end() - ->scalarNode('prefix')->end() - ->scalarNode('alias')->end() - ->booleanNode('is_bundle')->end() - ->end() - ->performNoDeepMerging() - ->end() - ; - - return $node; - } - - /** - * Adds the NodeBuilder for the "options" key of a connection. - */ - private function addConnectionOptionsNode() - { - $builder = new TreeBuilder(); - $node = $builder->root('options'); - - $node - ->performNoDeepMerging() - ->addDefaultsIfNotSet() // adds an empty array of omitted - // options go into the Mongo constructor - // http://www.php.net/manual/en/mongo.construct.php - ->children() - ->booleanNode('connect')->end() - ->scalarNode('persist')->end() - ->scalarNode('timeout')->end() - ->booleanNode('replicaSet')->end() - ->scalarNode('username')->end() - ->scalarNode('password')->end() - ->end() - ->end(); - - return $node; - } - - private function getMetadataCacheDriverNode() - { - $builder = new TreeBuilder(); - $node = $builder->root('metadata_cache_driver'); - - $node - ->beforeNormalization() - // if scalar - ->ifTrue(function($v) { return !is_array($v); }) - ->then(function($v) { return array('type' => $v); }) - ->end() - ->children() - ->scalarNode('type')->end() - ->scalarNode('class')->end() - ->scalarNode('host')->end() - ->scalarNode('port')->end() - ->scalarNode('instance_class')->end() - ->end() - ->end(); - - return $node; - } -} diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/DependencyInjection/DoctrineMongoDBExtension.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/DependencyInjection/DoctrineMongoDBExtension.php deleted file mode 100644 index 6e565acf9f..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/DependencyInjection/DoctrineMongoDBExtension.php +++ /dev/null @@ -1,357 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\DependencyInjection; - -use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Alias; -use Symfony\Component\DependencyInjection\Reference; -use Symfony\Component\DependencyInjection\Definition; -use Symfony\Component\Config\FileLocator; -use Symfony\Bundle\DoctrineAbstractBundle\DependencyInjection\AbstractDoctrineExtension; -use Symfony\Component\Config\Definition\Processor; - -/** - * Doctrine MongoDB ODM extension. - * - * @author Bulat Shakirzyanov - * @author Kris Wallsmith - * @author Jonathan H. Wage - */ -class DoctrineMongoDBExtension extends AbstractDoctrineExtension -{ - /** - * Responds to the doctrine_mongo_db configuration parameter. - */ - public function load(array $configs, ContainerBuilder $container) - { - // Load DoctrineMongoDBBundle/Resources/config/mongodb.xml - $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); - $loader->load('mongodb.xml'); - - $processor = new Processor(); - $configuration = new Configuration($container->getParameter('kernel.debug')); - $config = $processor->process($configuration->getConfigTree(), $configs); - - // can't currently default this correctly in Configuration - if (!isset($config['metadata_cache_driver'])) { - $config['metadata_cache_driver'] = array('type' => 'array'); - } - - if (empty ($config['default_connection'])) { - $keys = array_keys($config['connections']); - $config['default_connection'] = reset($keys); - } - - if (empty ($config['default_document_manager'])) { - $keys = array_keys($config['document_managers']); - $config['default_document_manager'] = reset($keys); - } - - // set some options as parameters and unset them - $config = $this->overrideParameters($config, $container); - - // load the connections - $this->loadConnections($config['connections'], $container); - - // load the document managers - $this->loadDocumentManagers( - $config['document_managers'], - $config['default_document_manager'], - $config['default_database'], - $config['metadata_cache_driver'], - $container - ); - - $this->loadConstraints($container); - } - - /** - * Uses some of the extension options to override DI extension parameters. - * - * @param array $options The available configuration options - * @param ContainerBuilder $container A ContainerBuilder instance - */ - protected function overrideParameters($options, ContainerBuilder $container) - { - $overrides = array( - 'proxy_namespace', - 'auto_generate_proxy_classes', - 'hydrator_namespace', - 'auto_generate_hydrator_classes', - ); - - foreach ($overrides as $key) { - if (isset($options[$key])) { - $container->setParameter('doctrine.odm.mongodb.'.$key, $options[$key]); - - // the option should not be used, the parameter should be referenced - unset($options[$key]); - } - } - - return $options; - } - - /** - * Loads the document managers configuration. - * - * @param array $dmConfigs An array of document manager configs - * @param string $defaultDM The default document manager name - * @param string $defaultDB The default db name - * @param string $defaultMetadataCache The default metadata cache configuration - * @param ContainerBuilder $container A ContainerBuilder instance - */ - protected function loadDocumentManagers(array $dmConfigs, $defaultDM, $defaultDB, $defaultMetadataCache, ContainerBuilder $container) - { - foreach ($dmConfigs as $name => $documentManager) { - $documentManager['name'] = $name; - $this->loadDocumentManager( - $documentManager, - $defaultDM, - $defaultDB, - $defaultMetadataCache, - $container - ); - } - $container->setParameter('doctrine.odm.mongodb.document_managers', array_keys($dmConfigs)); - } - - /** - * Loads a document manager configuration. - * - * @param array $documentManager A document manager configuration array - * @param string $defaultDM The default document manager name - * @param string $defaultDB The default db name - * @param string $defaultMetadataCache The default metadata cache configuration - * @param ContainerBuilder $container A ContainerBuilder instance - */ - protected function loadDocumentManager(array $documentManager, $defaultDM, $defaultDB, $defaultMetadataCache, ContainerBuilder $container) - { - $defaultDatabase = isset($documentManager['default_database']) ? $documentManager['default_database'] : $defaultDB; - $configServiceName = sprintf('doctrine.odm.mongodb.%s_configuration', $documentManager['name']); - - if ($container->hasDefinition($configServiceName)) { - $odmConfigDef = $container->getDefinition($configServiceName); - } else { - $odmConfigDef = new Definition('%doctrine.odm.mongodb.configuration_class%'); - $container->setDefinition($configServiceName, $odmConfigDef); - } - - $this->loadDocumentManagerBundlesMappingInformation($documentManager, $odmConfigDef, $container); - $this->loadDocumentManagerMetadataCacheDriver($documentManager, $container, $defaultMetadataCache); - - $methods = array( - 'setMetadataCacheImpl' => new Reference(sprintf('doctrine.odm.mongodb.%s_metadata_cache', $documentManager['name'])), - 'setMetadataDriverImpl' => new Reference(sprintf('doctrine.odm.mongodb.%s_metadata_driver', $documentManager['name'])), - 'setProxyDir' => '%kernel.cache_dir%'.'/doctrine/odm/mongodb/Proxies', - 'setProxyNamespace' => '%doctrine.odm.mongodb.proxy_namespace%', - 'setAutoGenerateProxyClasses' => '%doctrine.odm.mongodb.auto_generate_proxy_classes%', - 'setHydratorDir' => '%kernel.cache_dir%'.'/doctrine/odm/mongodb/Hydrators', - 'setHydratorNamespace' => '%doctrine.odm.mongodb.hydrator_namespace%', - 'setAutoGenerateHydratorClasses' => '%doctrine.odm.mongodb.auto_generate_hydrator_classes%', - 'setDefaultDB' => $defaultDatabase, - ); - - if ($documentManager['logging']) { - $methods['setLoggerCallable'] = array(new Reference('doctrine.odm.mongodb.logger'), 'logQuery'); - } - - foreach ($methods as $method => $arg) { - if ($odmConfigDef->hasMethodCall($method)) { - $odmConfigDef->removeMethodCall($method); - } - $odmConfigDef->addMethodCall($method, array($arg)); - } - - // event manager - $eventManagerName = isset($documentManager['event_manager']) ? $documentManager['event_manager'] : $documentManager['name']; - $eventManagerId = sprintf('doctrine.odm.mongodb.%s_event_manager', $eventManagerName); - if (!$container->hasDefinition($eventManagerId)) { - $eventManagerDef = new Definition('%doctrine.odm.mongodb.event_manager_class%'); - $eventManagerDef->addTag('doctrine.odm.mongodb.event_manager'); - $eventManagerDef->setPublic(false); - $container->setDefinition($eventManagerId, $eventManagerDef); - } - - $odmDmArgs = array( - new Reference(sprintf('doctrine.odm.mongodb.%s_connection', isset($documentManager['connection']) ? $documentManager['connection'] : $documentManager['name'])), - new Reference(sprintf('doctrine.odm.mongodb.%s_configuration', $documentManager['name'])), - new Reference($eventManagerId), - ); - $odmDmDef = new Definition('%doctrine.odm.mongodb.document_manager_class%', $odmDmArgs); - $odmDmDef->setFactoryClass('%doctrine.odm.mongodb.document_manager_class%'); - $odmDmDef->setFactoryMethod('create'); - $odmDmDef->addTag('doctrine.odm.mongodb.document_manager'); - $container->setDefinition(sprintf('doctrine.odm.mongodb.%s_document_manager', $documentManager['name']), $odmDmDef); - - if ($documentManager['name'] == $defaultDM) { - $container->setAlias( - 'doctrine.odm.mongodb.document_manager', - new Alias(sprintf('doctrine.odm.mongodb.%s_document_manager', $documentManager['name'])) - ); - $container->setAlias( - 'doctrine.odm.mongodb.event_manager', - new Alias(sprintf('doctrine.odm.mongodb.%s_event_manager', $documentManager['name'])) - ); - } - } - - /** - * Loads the configured document manager metadata cache driver. - * - * @param array $config A configured document manager array - * @param ContainerBuilder $container A ContainerBuilder instance - * @param array $defaultMetadataCache The default metadata cache configuration array - */ - protected function loadDocumentManagerMetadataCacheDriver(array $documentManager, ContainerBuilder $container, $defaultMetadataCache) - { - $dmMetadataCacheDriver = isset($documentManager['metadata_cache_driver']) ? $documentManager['metadata_cache_driver'] : $defaultMetadataCache; - $type = $dmMetadataCacheDriver['type']; - - if ('memcache' === $type) { - $memcacheClass = isset($dmMetadataCacheDriver['class']) ? $dmMetadataCacheDriver['class'] : sprintf('%%doctrine.odm.mongodb.cache.%s_class%%', $type); - $cacheDef = new Definition($memcacheClass); - $memcacheHost = isset($dmMetadataCacheDriver['host']) ? $dmMetadataCacheDriver['host'] : '%doctrine.odm.mongodb.cache.memcache_host%'; - $memcachePort = isset($dmMetadataCacheDriver['port']) ? $dmMetadataCacheDriver['port'] : '%doctrine.odm.mongodb.cache.memcache_port%'; - $memcacheInstanceClass = isset($dmMetadataCacheDriver['instance-class']) ? $dmMetadataCacheDriver['instance-class'] : (isset($dmMetadataCacheDriver['instance_class']) ? $dmMetadataCacheDriver['instance_class'] : '%doctrine.odm.mongodb.cache.memcache_instance_class%'); - $memcacheInstance = new Definition($memcacheInstanceClass); - $memcacheInstance->addMethodCall('connect', array($memcacheHost, $memcachePort)); - $container->setDefinition(sprintf('doctrine.odm.mongodb.%s_memcache_instance', $documentManager['name']), $memcacheInstance); - $cacheDef->addMethodCall('setMemcache', array(new Reference(sprintf('doctrine.odm.mongodb.%s_memcache_instance', $documentManager['name'])))); - } else { - $cacheDef = new Definition(sprintf('%%doctrine.odm.mongodb.cache.%s_class%%', $type)); - } - - $container->setDefinition(sprintf('doctrine.odm.mongodb.%s_metadata_cache', $documentManager['name']), $cacheDef); - } - - /** - * Loads the configured connections. - * - * @param array $config An array of connections configurations - * @param ContainerBuilder $container A ContainerBuilder instance - */ - protected function loadConnections(array $connections, ContainerBuilder $container) - { - foreach ($connections as $name => $connection) { - $odmConnArgs = array( - isset($connection['server']) ? $connection['server'] : null, - isset($connection['options']) ? $connection['options'] : array(), - new Reference(sprintf('doctrine.odm.mongodb.%s_configuration', $name)) - ); - $odmConnDef = new Definition('%doctrine.odm.mongodb.connection_class%', $odmConnArgs); - $container->setDefinition(sprintf('doctrine.odm.mongodb.%s_connection', $name), $odmConnDef); - } - } - - /** - * Loads an ODM document managers bundle mapping information. - * - * There are two distinct configuration possibilities for mapping information: - * - * 1. Specify a bundle and optionally details where the entity and mapping information reside. - * 2. Specify an arbitrary mapping location. - * - * @example - * - * doctrine.orm: - * mappings: - * MyBundle1: ~ - * MyBundle2: yml - * MyBundle3: { type: annotation, dir: Documents/ } - * MyBundle4: { type: xml, dir: Resources/config/doctrine/mapping } - * MyBundle5: - * type: yml - * dir: [bundle-mappings1/, bundle-mappings2/] - * alias: BundleAlias - * arbitrary_key: - * type: xml - * dir: %kernel.dir%/../src/vendor/DoctrineExtensions/lib/DoctrineExtensions/Documents - * prefix: DoctrineExtensions\Documents\ - * alias: DExt - * - * In the case of bundles everything is really optional (which leads to autodetection for this bundle) but - * in the mappings key everything except alias is a required argument. - * - * @param array $documentManager A configured ODM entity manager. - * @param Definition A Definition instance - * @param ContainerBuilder $container A ContainerBuilder instance - */ - protected function loadDocumentManagerBundlesMappingInformation(array $documentManager, Definition $odmConfigDef, ContainerBuilder $container) - { - // reset state of drivers and alias map. They are only used by this methods and children. - $this->drivers = array(); - $this->aliasMap = array(); - - $this->loadMappingInformation($documentManager, $container); - $this->registerMappingDrivers($documentManager, $container); - - if ($odmConfigDef->hasMethodCall('setDocumentNamespaces')) { - // TODO: Can we make a method out of it on Definition? replaceMethodArguments() or something. - $calls = $odmConfigDef->getMethodCalls(); - foreach ($calls as $call) { - if ($call[0] == 'setDocumentNamespaces') { - $this->aliasMap = array_merge($call[1][0], $this->aliasMap); - } - } - $method = $odmConfigDef->removeMethodCall('setDocumentNamespaces'); - } - $odmConfigDef->addMethodCall('setDocumentNamespaces', array($this->aliasMap)); - } - - protected function loadConstraints(ContainerBuilder $container) - { - // FIXME: the validator.annotations.namespaces parameter does not exist anymore - // and anyway, it was not available in the FrameworkExtension code - // as each bundle is isolated from the others - if ($container->hasParameter('validator.annotations.namespaces')) { - $container->setParameter('validator.annotations.namespaces', array_merge( - $container->getParameter('validator.annotations.namespaces'), - array('mongodb' => 'Symfony\Bundle\DoctrineMongoDBBundle\Validator\Constraints\\') - )); - } - } - - protected function getObjectManagerElementName($name) - { - return 'doctrine.odm.mongodb.' . $name; - } - - protected function getMappingObjectDefaultName() - { - return 'Document'; - } - - protected function getMappingResourceConfigDirectory() - { - return 'Resources/config/doctrine/metadata/mongodb'; - } - - /** - * Returns the namespace to be used for this extension (XML namespace). - * - * @return string The XML namespace - */ - public function getNamespace() - { - return 'http://symfony.com/schema/dic/doctrine/odm/mongodb'; - } - - /** - * @return string - */ - public function getXsdValidationBasePath() - { - return __DIR__.'/../Resources/config/schema'; - } -} diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/DoctrineMongoDBBundle.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/DoctrineMongoDBBundle.php deleted file mode 100755 index 105267515f..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/DoctrineMongoDBBundle.php +++ /dev/null @@ -1,38 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle; - -use Symfony\Component\DependencyInjection\Compiler\PassConfig; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\HttpKernel\Bundle\Bundle; -use Symfony\Bundle\DoctrineMongoDBBundle\DependencyInjection\Compiler\CreateHydratorDirectoryPass; -use Symfony\Bundle\DoctrineMongoDBBundle\DependencyInjection\Compiler\CreateProxyDirectoryPass; -use Symfony\Bundle\DoctrineMongoDBBundle\DependencyInjection\Compiler\RegisterEventListenersAndSubscribersPass; - -/** - * Doctrine MongoDB ODM bundle. - * - * @author Bulat Shakirzyanov - * @author Kris Wallsmith - * @author Jonathan H. Wage - */ -class DoctrineMongoDBBundle extends Bundle -{ - public function build(ContainerBuilder $container) - { - parent::build($container); - - $container->addCompilerPass(new RegisterEventListenersAndSubscribersPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION); - $container->addCompilerPass(new CreateProxyDirectoryPass(), PassConfig::TYPE_BEFORE_REMOVING); - $container->addCompilerPass(new CreateHydratorDirectoryPass(), PassConfig::TYPE_BEFORE_REMOVING); - } -} diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Logger/DoctrineMongoDBLogger.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Logger/DoctrineMongoDBLogger.php deleted file mode 100644 index 3d3dbe752f..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Logger/DoctrineMongoDBLogger.php +++ /dev/null @@ -1,299 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\Logger; - -use Doctrine\MongoDB\GridFSFile; -use Symfony\Component\HttpKernel\Log\LoggerInterface; - -/** - * Logger for the Doctrine MongoDB ODM. - * - * The {@link logQuery()} method is configured as the logger callable in the - * service container. - * - * @author Kris Wallsmith - */ -class DoctrineMongoDBLogger -{ - protected $logger; - - protected $prefix; - protected $queries; - - protected $processed; - protected $formattedQueries; - protected $nbRealQueries; - - /** - * Constructor. - * - * @param LoggerInterface $logger The Symfony logger - * @param string $prefix A prefix for messages sent to the Symfony logger - */ - public function __construct(LoggerInterface $logger = null, $prefix = 'MongoDB query: ') - { - $this->logger = $logger; - $this->prefix = $prefix; - $this->queries = array(); - $this->processed = false; - } - - /** - * Logs a query. - * - * This method is configured as the logger callable in the service - * container. - * - * @param array $query A query log array from Doctrine - */ - public function logQuery(array $query) - { - $this->queries[] = $query; - $this->processed = false; - - if (null !== $this->logger) { - $this->logger->info($this->prefix.static::bsonEncode($query)); - } - } - - /** - * Returns the number of queries that have been logged. - * - * @return integer The number of queries logged - */ - public function getNbQueries() - { - if (!$this->processed) { - $this->processQueries(); - } - - return $this->nbRealQueries; - } - - /** - * Returns a human-readable array of queries logged. - * - * @return array An array of queries - */ - public function getQueries() - { - if (!$this->processed) { - $this->processQueries(); - } - - return $this->formattedQueries; - } - - /** - * Groups and formats query arrays. - * - * @param array $queries An array of query arrays - * - * @return array An array of human-readable queries - */ - protected function processQueries() - { - $this->formattedQueries = array(); - $this->nbRealQueries = 0; - - $grouped = array(); - $ordered = array(); - foreach ($this->queries as $query) { - if (!isset($query['query']) || !isset($query['fields'])) { - // no grouping necessary - $ordered[] = array($query); - continue; - } - - $cursor = serialize($query['query']).serialize($query['fields']); - - // append if issued from cursor (currently just "sort") - if (isset($query['sort'])) { - unset($query['query'], $query['fields']); - $grouped[$cursor][count($grouped[$cursor]) - 1][] = $query; - } else { - $grouped[$cursor][] = array($query); - $ordered[] =& $grouped[$cursor][count($grouped[$cursor]) - 1]; - } - } - - $i = 0; - $db = ''; - $query = ''; - foreach ($ordered as $logs) { - foreach ($logs as $log) { - if (isset($log['db']) && $db != $log['db']) { - // for readability - $this->formattedQueries[$i++] = 'use '.$log['db'].';'; - $db = $log['db']; - } - - if (isset($log['collection'])) { - // flush the previous and start a new query - if (!empty($query)) { - if ('.' == $query[0]) { - $query = 'db'.$query; - } - - $this->formattedQueries[$i++] = $query.';'; - ++$this->nbRealQueries; - } - - $query = 'db.'.$log['collection']; - } - - // format the method call - if (isset($log['authenticate'])) { - $query .= '.authenticate()'; - } elseif (isset($log['batchInsert'])) { - $query .= '.batchInsert(**'.$log['num'].' item(s)**)'; - } elseif (isset($log['command'])) { - $query .= '.command()'; - } elseif (isset($log['count'])) { - $query .= '.count('; - if ($log['query'] || $log['limit'] || $log['skip']) { - $query .= static::bsonEncode($log['query']); - if ($log['limit'] || $log['skip']) { - $query .= ', '.static::bsonEncode($log['limit']); - if ($log['skip']) { - $query .= ', '.static::bsonEncode($log['skip']); - } - } - } - $query .= ')'; - } elseif (isset($log['createCollection'])) { - $query .= '.createCollection()'; - } elseif (isset($log['createDBRef'])) { - $query .= '.createDBRef()'; - } elseif (isset($log['deleteIndex'])) { - $query .= '.dropIndex('.static::bsonEncode($log['keys']).')'; - } elseif (isset($log['deleteIndexes'])) { - $query .= '.dropIndexes()'; - } elseif (isset($log['drop'])) { - $query .= '.drop()'; - } elseif (isset($log['dropDatabase'])) { - $query .= '.dropDatabase()'; - } elseif (isset($log['ensureIndex'])) { - $query .= '.ensureIndex('.static::bsonEncode($log['keys']).', '.static::bsonEncode($log['options']).')'; - } elseif (isset($log['execute'])) { - $query .= '.execute()'; - } elseif (isset($log['find'])) { - $query .= '.find('; - if ($log['query'] || $log['fields']) { - $query .= static::bsonEncode($log['query']); - if ($log['fields']) { - $query .= ', '.static::bsonEncode($log['fields']); - } - } - $query .= ')'; - } elseif (isset($log['findOne'])) { - $query .= '.findOne('; - if ($log['query'] || $log['fields']) { - $query .= static::bsonEncode($log['query']); - if ($log['fields']) { - $query .= ', '.static::bsonEncode($log['fields']); - } - } - $query .= ')'; - } elseif (isset($log['getDBRef'])) { - $query .= '.getDBRef()'; - } elseif (isset($log['group'])) { - $query .= '.group('.static::bsonEncode(array( - 'keys' => $log['keys'], - 'initial' => $log['initial'], - 'reduce' => $log['reduce'], - )).')'; - } elseif (isset($log['insert'])) { - $query .= '.insert('.static::bsonEncode($log['document']).')'; - } elseif (isset($log['remove'])) { - $query .= '.remove('.static::bsonEncode($log['query']).')'; - } elseif (isset($log['save'])) { - $query .= '.save('.static::bsonEncode($log['document']).')'; - } elseif (isset($log['sort'])) { - $query .= '.sort('.static::bsonEncode($log['sortFields']).')'; - } elseif (isset($log['update'])) { - // todo: include $log['options'] - $query .= '.update('.static::bsonEncode($log['query']).', '.static::bsonEncode($log['newObj']).')'; - } elseif (isset($log['validate'])) { - $query .= '.validate()'; - } - } - } - - if (!empty($query)) { - if ('.' == $query[0]) { - $query = 'db'.$query; - } - - $this->formattedQueries[$i++] = $query.';'; - ++$this->nbRealQueries; - } - } - - static protected function bsonEncode($query, $array = true) - { - $parts = array(); - - foreach ($query as $key => $value) { - if (!is_numeric($key)) { - $array = false; - } - - if (is_bool($value)) { - $formatted = $value ? 'true' : 'false'; - } elseif (is_numeric($value)) { - $formatted = $value; - } elseif (is_scalar($value)) { - $formatted = '"'.$value.'"'; - } elseif (is_array($value)) { - $formatted = static::bsonEncode($value); - } elseif ($value instanceof \MongoId) { - $formatted = 'ObjectId("'.$value.'")'; - } elseif ($value instanceof \MongoDate) { - $formatted = 'new Date("'.date('r', $value->sec).'")'; - } elseif ($value instanceof \DateTime) { - $formatted = 'new Date("'.date('r', $value->getTimestamp()).'")'; - } elseif ($value instanceof \MongoRegex) { - $formatted = 'new RegExp("'.$value->regex.'", "'.$value->flags.'")'; - } elseif ($value instanceof \MongoMinKey) { - $formatted = 'new MinKey()'; - } elseif ($value instanceof \MongoMaxKey) { - $formatted = 'new MaxKey()'; - } elseif ($value instanceof \MongoBinData) { - $formatted = 'new BinData("'.$value->bin.'", "'.$value->type.'")'; - } elseif ($value instanceof \MongoGridFSFile || $value instanceof GridFSFile) { - $formatted = 'new MongoGridFSFile("'.$value->getFilename().'")'; - } elseif ($value instanceof \stdClass) { - $formatted = static::bsonEncode((array) $value); - } else { - $formatted = (string) $value; - } - - $parts['"'.$key.'"'] = $formatted; - } - - if (0 == count($parts)) { - return $array ? '[ ]' : '{ }'; - } - - if ($array) { - return '[ '.implode(', ', $parts).' ]'; - } else { - $mapper = function($key, $value) - { - return $key.': '.$value; - }; - - return '{ '.implode(', ', array_map($mapper, array_keys($parts), array_values($parts))).' }'; - } - } -} diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Resources/config/mongodb.xml b/src/Symfony/Bundle/DoctrineMongoDBBundle/Resources/config/mongodb.xml deleted file mode 100755 index 8281f5d0c4..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Resources/config/mongodb.xml +++ /dev/null @@ -1,118 +0,0 @@ - - - - - - Doctrine\MongoDB\Connection - Doctrine\ODM\MongoDB\Configuration - Doctrine\ODM\MongoDB\DocumentManager - Symfony\Bundle\DoctrineMongoDBBundle\Logger\DoctrineMongoDBLogger - Symfony\Bundle\DoctrineMongoDBBundle\DataCollector\DoctrineMongoDBDataCollector - Doctrine\Common\EventManager - - - Proxies - %kernel.cache_dir%/doctrine/odm/mongodb/Proxies - false - - - Hydrators - %kernel.cache_dir%/doctrine/odm/mongodb/Hydrators - false - - - Doctrine\Common\Cache\ArrayCache - Doctrine\Common\Cache\ApcCache - Doctrine\Common\Cache\MemcacheCache - localhost - 11211 - Memcache - Doctrine\Common\Cache\XcacheCache - - - Doctrine\ODM\MongoDB\Mapping\Driver\DriverChain - Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver - Doctrine\Common\Annotations\AnnotationReader - Doctrine\ODM\MongoDB\Mapping\Driver\XmlDriver - Doctrine\ODM\MongoDB\Mapping\Driver\YamlDriver - - - - %doctrine.odm.mongodb.mapping_dirs% - %doctrine.odm.mongodb.mapping_dirs% - - - - Symfony\Bundle\DoctrineMongoDBBundle\Security\DocumentUserProvider - - - Symfony\Bundle\DoctrineMongoDBBundle\CacheWarmer\ProxyCacheWarmer - - - Symfony\Bundle\DoctrineMongoDBBundle\CacheWarmer\HydratorCacheWarmer - - - Symfony\Bundle\DoctrineMongoDBBundle\Validator\Constraints\UniqueValidator - - - - - - - - - - - %doctrine.odm.mongodb.document_dirs% - - - - - Doctrine\ODM\MongoDB\Mapping\ - mongodb - - - - %doctrine.odm.mongodb.xml_mapping_dirs% - - - %doctrine.odm.mongodb.yml_mapping_dirs% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Resources/config/schema/mongodb-1.0.xsd b/src/Symfony/Bundle/DoctrineMongoDBBundle/Resources/config/schema/mongodb-1.0.xsd deleted file mode 100644 index f214496b5b..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Resources/config/schema/mongodb-1.0.xsd +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Resources/views/Collector/mongodb.html.twig b/src/Symfony/Bundle/DoctrineMongoDBBundle/Resources/views/Collector/mongodb.html.twig deleted file mode 100644 index b57c85a411..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Resources/views/Collector/mongodb.html.twig +++ /dev/null @@ -1,45 +0,0 @@ -{% extends 'WebProfiler:Profiler:layout.html.twig' %} - -{% block toolbar %} - {% set icon %} - Mongo - {% endset %} - {% set text %} - {{ collector.querycount }} - {% endset %} - {% include 'WebProfiler:Profiler:toolbar_item.html.twig' with { 'link': profiler_url } %} -{% endblock %} - -{% block menu %} - - - Doctrine MongoDB - - {{ collector.querycount }} - - -{% endblock %} - -{% block panel %} -

Queries

- - {% if not collector.queries %} -

- Query logging is disabled. -

- {% elseif not collector.querycount %} -

- No queries. -

- {% else %} -
    - {% for query in collector.queries %} -
  • -
    - {{ query }} -
    -
  • - {% endfor %} -
- {% endif %} -{% endblock %} diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Security/DocumentUserProvider.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Security/DocumentUserProvider.php deleted file mode 100644 index 651c21c554..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Security/DocumentUserProvider.php +++ /dev/null @@ -1,78 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\Security; - -use Symfony\Component\Security\Core\User\UserInterface; -use Symfony\Component\Security\Core\User\UserProviderInterface; -use Symfony\Component\Security\Core\Exception\UnsupportedUserException; -use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; - -class DocumentUserProvider implements UserProviderInterface -{ - protected $class; - protected $repository; - protected $property; - - public function __construct($em, $class, $property = null) - { - $this->class = $class; - - if (false !== strpos($this->class, ':')) { - $this->class = $em->getClassMetadata($class)->getName(); - } - - $this->repository = $em->getRepository($class); - $this->property = $property; - } - - /** - * {@inheritdoc} - */ - public function loadUserByUsername($username) - { - if (null !== $this->property) { - $user = $this->repository->findOneBy(array($this->property => $username)); - } else { - if (!$this->repository instanceof UserProviderInterface) { - throw new \InvalidArgumentException(sprintf('The Doctrine repository "%s" must implement UserProviderInterface.', get_class($this->repository))); - } - - $user = $this->repository->loadUserByUsername($username); - } - - if (null === $user) { - throw new UsernameNotFoundException(sprintf('User "%s" not found.', $username)); - } - - return $user; - } - - /** - * {@inheritDoc} - */ - public function loadUser(UserInterface $user) - { - if (!$user instanceof $this->class) { - throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user))); - } - - return $this->loadUserByUsername($user->getUsername()); - } - - /** - * {@inheritDoc} - */ - public function supportsClass($class) - { - return $class === $this->class; - } -} diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/CacheWarmer/HydratorCacheWarmerTest.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/CacheWarmer/HydratorCacheWarmerTest.php deleted file mode 100644 index 6444c6b7b9..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/CacheWarmer/HydratorCacheWarmerTest.php +++ /dev/null @@ -1,97 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\Tests\CacheWarmer; - -use Symfony\Bundle\DoctrineMongoDBBundle\CacheWarmer\HydratorCacheWarmer; - -class HydratorCacheWarmerTest extends \Symfony\Bundle\DoctrineMongoDBBundle\Tests\TestCase -{ - /** - * This is not necessarily a good test, it doesn't generate any hydrators - * because there are none in the AnnotationsBundle. However that is - * rather a task of doctrine to test. We touch the lines here and - * verify that the container is called correctly for the relevant information. - * - * @group DoctrineODMMongoDBHydrator - */ - public function testWarmCache() - { - $testManager = $this->createTestDocumentManager(array( - __DIR__ . "/../DependencyInjection/Fixtures/Bundles/AnnotationsBundle/Document") - ); - - $container = $this->getMock('Symfony\Component\DependencyInjection\Container'); - $container->expects($this->at(0)) - ->method('getParameter') - ->with($this->equalTo('doctrine.odm.mongodb.hydrator_dir')) - ->will($this->returnValue(sys_get_temp_dir())); - $container->expects($this->at(1)) - ->method('getParameter') - ->with($this->equalTo('doctrine.odm.mongodb.auto_generate_hydrator_classes')) - ->will($this->returnValue(false)); - $container->expects($this->at(2)) - ->method('getParameter') - ->with($this->equalTo('doctrine.odm.mongodb.document_managers')) - ->will($this->returnValue(array('default', 'foo'))); - $container->expects($this->at(3)) - ->method('get') - ->with($this->equalTo('doctrine.odm.mongodb.default_document_manager')) - ->will($this->returnValue($testManager)); - $container->expects($this->at(4)) - ->method('get') - ->with($this->equalTo('doctrine.odm.mongodb.foo_document_manager')) - ->will($this->returnValue($testManager)); - - $cacheWarmer = new HydratorCacheWarmer($container); - $cacheWarmer->warmUp(sys_get_temp_dir()); - } - - /** - * @group DoctrineODMMongoDBHydrator - */ - public function testSkipWhenHydratorsAreAutoGenerated() - { - $testManager = $this->createTestDocumentManager(array( - __DIR__ . "/../DependencyInjection/Fixtures/Bundles/AnnotationsBundle/Document") - ); - - $container = $this->getMock('Symfony\Component\DependencyInjection\Container'); - $container->expects($this->at(0)) - ->method('getParameter') - ->with($this->equalTo('doctrine.odm.mongodb.hydrator_dir')) - ->will($this->returnValue(sys_get_temp_dir())); - $container->expects($this->at(1)) - ->method('getParameter') - ->with($this->equalTo('doctrine.odm.mongodb.auto_generate_hydrator_classes')) - ->will($this->returnValue(true)); - $container->expects($this->at(2)) - ->method('getParameter') - ->with($this->equalTo('assertion')) - ->will($this->returnValue(true)); - - $cacheWarmer = new HydratorCacheWarmer($container); - $cacheWarmer->warmUp(sys_get_temp_dir()); - - $container->getParameter('assertion'); // check that the assertion is really the third call. - } - - /** - * @group DoctrineODMMongoDBHydrator - */ - public function testHydratorCacheWarmingIsNotOptional() - { - $container = $this->getMock('Symfony\Component\DependencyInjection\Container'); - $cacheWarmer = new HydratorCacheWarmer($container); - - $this->assertFalse($cacheWarmer->isOptional()); - } -} \ No newline at end of file diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/CacheWarmer/ProxyCacheWarmerTest.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/CacheWarmer/ProxyCacheWarmerTest.php deleted file mode 100644 index 9184b2f35b..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/CacheWarmer/ProxyCacheWarmerTest.php +++ /dev/null @@ -1,97 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\Tests\CacheWarmer; - -use Symfony\Bundle\DoctrineMongoDBBundle\CacheWarmer\ProxyCacheWarmer; - -class ProxyCacheWarmerTest extends \Symfony\Bundle\DoctrineMongoDBBundle\Tests\TestCase -{ - /** - * This is not necessarily a good test, it doesn't generate any proxies - * because there are none in the AnnotationsBundle. However that is - * rather a task of doctrine to test. We touch the lines here and - * verify that the container is called correctly for the relevant information. - * - * @group DoctrineODMMongoDBProxy - */ - public function testWarmCache() - { - $testManager = $this->createTestDocumentManager(array( - __DIR__ . "/../DependencyInjection/Fixtures/Bundles/AnnotationsBundle/Document") - ); - - $container = $this->getMock('Symfony\Component\DependencyInjection\Container'); - $container->expects($this->at(0)) - ->method('getParameter') - ->with($this->equalTo('doctrine.odm.mongodb.proxy_dir')) - ->will($this->returnValue(sys_get_temp_dir())); - $container->expects($this->at(1)) - ->method('getParameter') - ->with($this->equalTo('doctrine.odm.mongodb.auto_generate_proxy_classes')) - ->will($this->returnValue(false)); - $container->expects($this->at(2)) - ->method('getParameter') - ->with($this->equalTo('doctrine.odm.mongodb.document_managers')) - ->will($this->returnValue(array('default', 'foo'))); - $container->expects($this->at(3)) - ->method('get') - ->with($this->equalTo('doctrine.odm.mongodb.default_document_manager')) - ->will($this->returnValue($testManager)); - $container->expects($this->at(4)) - ->method('get') - ->with($this->equalTo('doctrine.odm.mongodb.foo_document_manager')) - ->will($this->returnValue($testManager)); - - $cacheWarmer = new ProxyCacheWarmer($container); - $cacheWarmer->warmUp(sys_get_temp_dir()); - } - - /** - * @group DoctrineODMMongoDBProxy - */ - public function testSkipWhenProxiesAreAutoGenerated() - { - $testManager = $this->createTestDocumentManager(array( - __DIR__ . "/../DependencyInjection/Fixtures/Bundles/AnnotationsBundle/Document") - ); - - $container = $this->getMock('Symfony\Component\DependencyInjection\Container'); - $container->expects($this->at(0)) - ->method('getParameter') - ->with($this->equalTo('doctrine.odm.mongodb.proxy_dir')) - ->will($this->returnValue(sys_get_temp_dir())); - $container->expects($this->at(1)) - ->method('getParameter') - ->with($this->equalTo('doctrine.odm.mongodb.auto_generate_proxy_classes')) - ->will($this->returnValue(true)); - $container->expects($this->at(2)) - ->method('getParameter') - ->with($this->equalTo('assertion')) - ->will($this->returnValue(true)); - - $cacheWarmer = new ProxyCacheWarmer($container); - $cacheWarmer->warmUp(sys_get_temp_dir()); - - $container->getParameter('assertion'); // check that the assertion is really the third call. - } - - /** - * @group DoctrineODMMongoDBProxy - */ - public function testProxyCacheWarmingIsNotOptional() - { - $container = $this->getMock('Symfony\Component\DependencyInjection\Container'); - $cacheWarmer = new ProxyCacheWarmer($container); - - $this->assertFalse($cacheWarmer->isOptional()); - } -} \ No newline at end of file diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/ContainerTest.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/ContainerTest.php deleted file mode 100644 index 701d7ba7dc..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/ContainerTest.php +++ /dev/null @@ -1,60 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\Tests; - -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; -use Symfony\Bundle\DoctrineMongoDBBundle\DependencyInjection\DoctrineMongoDBExtension; -use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; - -class ContainerTest extends TestCase -{ - public function getContainer() - { - require_once __DIR__.'/DependencyInjection/Fixtures/Bundles/YamlBundle/YamlBundle.php'; - - $container = new ContainerBuilder(new ParameterBag(array( - 'kernel.bundles' => array('Yaml' => 'DoctrineMongoDBBundle\Tests\DependencyInjection\Fixtures\Bundles\YamlBundle\YamlBundle'), - 'kernel.cache_dir' => sys_get_temp_dir(), - 'kernel.debug' => false, - ))); - $loader = new DoctrineMongoDBExtension(); - $container->registerExtension($loader); - - $configs = array(); - $configs[] = array('connections' => array('default' => array()), 'document_managers' => array('default' => array('mappings' => array('Yaml' => array())))); - $loader->load($configs, $container); - - return $container; - } - - public function testContainer() - { - $container = $this->getContainer(); - $this->assertInstanceOf('Doctrine\ODM\MongoDB\Mapping\Driver\DriverChain', $container->get('doctrine.odm.mongodb.metadata.chain')); - $this->assertInstanceOf('Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver', $container->get('doctrine.odm.mongodb.metadata.annotation')); - $this->assertInstanceOf('Doctrine\Common\Annotations\AnnotationReader', $container->get('doctrine.odm.mongodb.metadata.annotation_reader')); - $this->assertInstanceOf('Doctrine\ODM\MongoDB\Mapping\Driver\XmlDriver', $container->get('doctrine.odm.mongodb.metadata.xml')); - $this->assertInstanceOf('Doctrine\ODM\MongoDB\Mapping\Driver\YamlDriver', $container->get('doctrine.odm.mongodb.metadata.yml')); - $this->assertInstanceOf('Doctrine\Common\Cache\ArrayCache', $container->get('doctrine.odm.mongodb.cache.array')); - $this->assertInstanceOf('Symfony\Bundle\DoctrineMongoDBBundle\Logger\DoctrineMongoDBLogger', $container->get('doctrine.odm.mongodb.logger')); - $this->assertInstanceOf('Symfony\Bundle\DoctrineMongoDBBundle\DataCollector\DoctrineMongoDBDataCollector', $container->get('doctrine.odm.mongodb.data_collector')); - $this->assertInstanceOf('Doctrine\MongoDB\Connection', $container->get('doctrine.odm.mongodb.default_connection')); - $this->assertInstanceOf('Doctrine\ODM\MongoDB\Configuration', $container->get('doctrine.odm.mongodb.default_configuration')); - $this->assertInstanceOf('Doctrine\ODM\MongoDB\Mapping\Driver\DriverChain', $container->get('doctrine.odm.mongodb.default_metadata_driver')); - $this->assertInstanceOf('Doctrine\Common\Cache\ArrayCache', $container->get('doctrine.odm.mongodb.default_metadata_cache')); - $this->assertInstanceOf('Doctrine\ODM\MongoDB\DocumentManager', $container->get('doctrine.odm.mongodb.default_document_manager')); - $this->assertInstanceOf('Doctrine\Common\Cache\ArrayCache', $container->get('doctrine.odm.mongodb.cache')); - $this->assertInstanceOf('Doctrine\ODM\MongoDB\DocumentManager', $container->get('doctrine.odm.mongodb.document_manager')); - $this->assertInstanceof('Doctrine\Common\EventManager', $container->get('doctrine.odm.mongodb.event_manager')); - } -} diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/AbstractMongoDBExtensionTest.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/AbstractMongoDBExtensionTest.php deleted file mode 100644 index 9c19eebebd..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/AbstractMongoDBExtensionTest.php +++ /dev/null @@ -1,361 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\Tests\DependencyInjection; - -use Symfony\Bundle\DoctrineMongoDBBundle\Tests\TestCase; -use Symfony\Bundle\DoctrineMongoDBBundle\DependencyInjection\DoctrineMongoDBExtension; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; -use Symfony\Component\DependencyInjection\Reference; - -abstract class AbstractMongoDBExtensionTest extends TestCase -{ - abstract protected function loadFromFile(ContainerBuilder $container, $file); - - public function testDependencyInjectionConfigurationDefaults() - { - $container = $this->getContainer(); - $loader = new DoctrineMongoDBExtension(); - - $loader->load(array(array()), $container); - - $this->assertEquals('Doctrine\MongoDB\Connection', $container->getParameter('doctrine.odm.mongodb.connection_class')); - $this->assertEquals('Doctrine\ODM\MongoDB\Configuration', $container->getParameter('doctrine.odm.mongodb.configuration_class')); - $this->assertEquals('Doctrine\ODM\MongoDB\DocumentManager', $container->getParameter('doctrine.odm.mongodb.document_manager_class')); - $this->assertEquals('Proxies', $container->getParameter('doctrine.odm.mongodb.proxy_namespace')); - $this->assertEquals(false, $container->getParameter('doctrine.odm.mongodb.auto_generate_proxy_classes')); - $this->assertEquals('Doctrine\Common\Cache\ArrayCache', $container->getParameter('doctrine.odm.mongodb.cache.array_class')); - $this->assertEquals('Doctrine\Common\Cache\ApcCache', $container->getParameter('doctrine.odm.mongodb.cache.apc_class')); - $this->assertEquals('Doctrine\Common\Cache\MemcacheCache', $container->getParameter('doctrine.odm.mongodb.cache.memcache_class')); - $this->assertEquals('localhost', $container->getParameter('doctrine.odm.mongodb.cache.memcache_host')); - $this->assertEquals('11211', $container->getParameter('doctrine.odm.mongodb.cache.memcache_port')); - $this->assertEquals('Memcache', $container->getParameter('doctrine.odm.mongodb.cache.memcache_instance_class')); - $this->assertEquals('Doctrine\Common\Cache\XcacheCache', $container->getParameter('doctrine.odm.mongodb.cache.xcache_class')); - $this->assertEquals('Doctrine\ODM\MongoDB\Mapping\Driver\DriverChain', $container->getParameter('doctrine.odm.mongodb.metadata.driver_chain_class')); - $this->assertEquals('Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver', $container->getParameter('doctrine.odm.mongodb.metadata.annotation_class')); - $this->assertEquals('Doctrine\Common\Annotations\AnnotationReader', $container->getParameter('doctrine.odm.mongodb.metadata.annotation_reader_class')); - $this->assertEquals('Doctrine\ODM\MongoDB\Mapping\Driver\XmlDriver', $container->getParameter('doctrine.odm.mongodb.metadata.xml_class')); - $this->assertEquals('Doctrine\ODM\MongoDB\Mapping\Driver\YamlDriver', $container->getParameter('doctrine.odm.mongodb.metadata.yml_class')); - - $this->assertEquals('Symfony\Bundle\DoctrineMongoDBBundle\Validator\Constraints\UniqueValidator', $container->getParameter('doctrine_odm.mongodb.validator.unique.class')); - - $config = array( - 'proxy_namespace' => 'MyProxies', - 'auto_generate_proxy_classes' => true, - 'connections' => array('default' => array()), - 'document_managers' => array('default' => array()) - ); - $loader->load(array($config), $container); - - $this->assertEquals('MyProxies', $container->getParameter('doctrine.odm.mongodb.proxy_namespace')); - $this->assertEquals(true, $container->getParameter('doctrine.odm.mongodb.auto_generate_proxy_classes')); - - $definition = $container->getDefinition('doctrine.odm.mongodb.default_connection'); - $this->assertEquals('%doctrine.odm.mongodb.connection_class%', $definition->getClass()); - $this->assertEquals(array(null, array(), new Reference('doctrine.odm.mongodb.default_configuration')), $definition->getArguments()); - - $definition = $container->getDefinition('doctrine.odm.mongodb.default_document_manager'); - $this->assertEquals('%doctrine.odm.mongodb.document_manager_class%', $definition->getClass()); - $this->assertEquals('%doctrine.odm.mongodb.document_manager_class%', $definition->getFactoryClass()); - $this->assertEquals('create', $definition->getFactoryMethod()); - $this->assertArrayHasKey('doctrine.odm.mongodb.document_manager', $definition->getTags()); - - $arguments = $definition->getArguments(); - $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[0]); - $this->assertEquals('doctrine.odm.mongodb.default_connection', (string) $arguments[0]); - $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[1]); - $this->assertEquals('doctrine.odm.mongodb.default_configuration', (string) $arguments[1]); - } - - public function testSingleDocumentManagerConfiguration() - { - $container = $this->getContainer(); - $loader = new DoctrineMongoDBExtension(); - - $config = array( - 'connections' => array( - 'default' => array( - 'server' => 'mongodb://localhost:27017', - 'options' => array('connect' => true) - ) - ), - 'document_managers' => array('default' => array()) - ); - $loader->load(array($config), $container); - - $definition = $container->getDefinition('doctrine.odm.mongodb.default_connection'); - $this->assertEquals('%doctrine.odm.mongodb.connection_class%', $definition->getClass()); - $this->assertEquals(array('mongodb://localhost:27017', array('connect' => true), new Reference('doctrine.odm.mongodb.default_configuration')), $definition->getArguments()); - - $definition = $container->getDefinition('doctrine.odm.mongodb.default_document_manager'); - $this->assertEquals('%doctrine.odm.mongodb.document_manager_class%', $definition->getClass()); - $this->assertEquals('%doctrine.odm.mongodb.document_manager_class%', $definition->getFactoryClass()); - $this->assertEquals('create', $definition->getFactoryMethod()); - $this->assertArrayHasKey('doctrine.odm.mongodb.document_manager', $definition->getTags()); - - $arguments = $definition->getArguments(); - $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[0]); - $this->assertEquals('doctrine.odm.mongodb.default_connection', (string) $arguments[0]); - $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[1]); - $this->assertEquals('doctrine.odm.mongodb.default_configuration', (string) $arguments[1]); - } - - public function testLoadSimpleSingleConnection() - { - $container = $this->getContainer(); - $loader = new DoctrineMongoDBExtension(); - $container->registerExtension($loader); - - $this->loadFromFile($container, 'mongodb_service_simple_single_connection'); - - $container->getCompilerPassConfig()->setOptimizationPasses(array()); - $container->getCompilerPassConfig()->setRemovingPasses(array()); - $container->compile(); - - $definition = $container->getDefinition('doctrine.odm.mongodb.default_connection'); - $this->assertEquals('%doctrine.odm.mongodb.connection_class%', $definition->getClass()); - $this->assertEquals(array('mongodb://localhost:27017', array('connect' => true), new Reference('doctrine.odm.mongodb.default_configuration')), $definition->getArguments()); - - $definition = $container->getDefinition('doctrine.odm.mongodb.default_configuration'); - $methodCalls = $definition->getMethodCalls(); - $methodNames = array_map(function($call) { return $call[0]; }, $methodCalls); - $this->assertInternalType('integer', $pos = array_search('setDefaultDB', $methodNames)); - $this->assertEquals('mydb', $methodCalls[$pos][1][0]); - - $definition = $container->getDefinition('doctrine.odm.mongodb.default_document_manager'); - $this->assertEquals('%doctrine.odm.mongodb.document_manager_class%', $definition->getClass()); - $this->assertEquals('%doctrine.odm.mongodb.document_manager_class%', $definition->getFactoryClass()); - $this->assertEquals('create', $definition->getFactoryMethod()); - $this->assertArrayHasKey('doctrine.odm.mongodb.document_manager', $definition->getTags()); - - $arguments = $definition->getArguments(); - $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[0]); - $this->assertEquals('doctrine.odm.mongodb.default_connection', (string) $arguments[0]); - $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[1]); - $this->assertEquals('doctrine.odm.mongodb.default_configuration', (string) $arguments[1]); - } - - public function testLoadSingleConnection() - { - $container = $this->getContainer(); - $loader = new DoctrineMongoDBExtension(); - $container->registerExtension($loader); - - $this->loadFromFile($container, 'mongodb_service_single_connection'); - - $container->getCompilerPassConfig()->setOptimizationPasses(array()); - $container->getCompilerPassConfig()->setRemovingPasses(array()); - $container->compile(); - - $definition = $container->getDefinition('doctrine.odm.mongodb.default_connection'); - $this->assertEquals('%doctrine.odm.mongodb.connection_class%', $definition->getClass()); - $this->assertEquals(array('mongodb://localhost:27017', array('connect' => true), new Reference('doctrine.odm.mongodb.default_configuration')), $definition->getArguments()); - - $definition = $container->getDefinition('doctrine.odm.mongodb.default_document_manager'); - $this->assertEquals('%doctrine.odm.mongodb.document_manager_class%', $definition->getClass()); - $this->assertEquals('%doctrine.odm.mongodb.document_manager_class%', $definition->getFactoryClass()); - $this->assertEquals('create', $definition->getFactoryMethod()); - $this->assertArrayHasKey('doctrine.odm.mongodb.document_manager', $definition->getTags()); - - $arguments = $definition->getArguments(); - $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[0]); - $this->assertEquals('doctrine.odm.mongodb.default_connection', (string) $arguments[0]); - $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[1]); - $this->assertEquals('doctrine.odm.mongodb.default_configuration', (string) $arguments[1]); - } - - public function testLoadMultipleConnections() - { - $container = $this->getContainer(); - $loader = new DoctrineMongoDBExtension(); - $container->registerExtension($loader); - - $this->loadFromFile($container, 'mongodb_service_multiple_connections'); - - $container->getCompilerPassConfig()->setOptimizationPasses(array()); - $container->getCompilerPassConfig()->setRemovingPasses(array()); - $container->compile(); - - $definition = $container->getDefinition('doctrine.odm.mongodb.conn1_connection'); - $this->assertEquals('%doctrine.odm.mongodb.connection_class%', $definition->getClass()); - $this->assertEquals(array('mongodb://localhost:27017', array('connect' => true), new Reference('doctrine.odm.mongodb.conn1_configuration')), $definition->getArguments()); - - $this->assertEquals('doctrine.odm.mongodb.dm2_document_manager', (string) $container->getAlias('doctrine.odm.mongodb.document_manager')); - - $definition = $container->getDefinition('doctrine.odm.mongodb.dm1_document_manager'); - $this->assertEquals('%doctrine.odm.mongodb.document_manager_class%', $definition->getClass()); - $this->assertEquals('%doctrine.odm.mongodb.document_manager_class%', $definition->getFactoryClass()); - $this->assertEquals('create', $definition->getFactoryMethod()); - $this->assertArrayHasKey('doctrine.odm.mongodb.document_manager', $definition->getTags()); - - $arguments = $definition->getArguments(); - $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[0]); - $this->assertEquals('doctrine.odm.mongodb.conn1_connection', (string) $arguments[0]); - $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[1]); - $this->assertEquals('doctrine.odm.mongodb.dm1_configuration', (string) $arguments[1]); - - $definition = $container->getDefinition('doctrine.odm.mongodb.conn2_connection'); - $this->assertEquals('%doctrine.odm.mongodb.connection_class%', $definition->getClass()); - $this->assertEquals(array('mongodb://localhost:27017', array('connect' => true), new Reference('doctrine.odm.mongodb.conn2_configuration')), $definition->getArguments()); - - $definition = $container->getDefinition('doctrine.odm.mongodb.dm2_document_manager'); - $this->assertEquals('%doctrine.odm.mongodb.document_manager_class%', $definition->getClass()); - $this->assertEquals('%doctrine.odm.mongodb.document_manager_class%', $definition->getFactoryClass()); - $this->assertEquals('create', $definition->getFactoryMethod()); - $this->assertArrayHasKey('doctrine.odm.mongodb.document_manager', $definition->getTags()); - - $arguments = $definition->getArguments(); - $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[0]); - $this->assertEquals('doctrine.odm.mongodb.conn2_connection', (string) $arguments[0]); - $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[1]); - $this->assertEquals('doctrine.odm.mongodb.dm2_configuration', (string) $arguments[1]); - } - - public function testBundleDocumentAliases() - { - $container = $this->getContainer(); - $loader = new DoctrineMongoDBExtension(); - - $loader->load(array(array('document_managers' => array('default' => array('mappings' => array('Yaml' => array()))))), $container); - - $definition = $container->getDefinition('doctrine.odm.mongodb.default_configuration'); - $calls = $definition->getMethodCalls(); - $this->assertTrue(isset($calls[0][1][0]['Yaml'])); - $this->assertEquals('DoctrineMongoDBBundle\Tests\DependencyInjection\Fixtures\Bundles\YamlBundle\Document', $calls[0][1][0]['Yaml']); - } - - public function testYamlBundleMappingDetection() - { - $container = $this->getContainer(); - $loader = new DoctrineMongoDBExtension(); - - $loader->load(array(array('document_managers' => array('default' => array('mappings' => array('Yaml' => array()))))), $container); - - $calls = $container->getDefinition('doctrine.odm.mongodb.default_metadata_driver')->getMethodCalls(); - $this->assertEquals('doctrine.odm.mongodb.default_yml_metadata_driver', (string) $calls[0][1][0]); - $this->assertEquals('DoctrineMongoDBBundle\Tests\DependencyInjection\Fixtures\Bundles\YamlBundle\Document', $calls[0][1][1]); - } - - public function testXmlBundleMappingDetection() - { - $container = $this->getContainer('XmlBundle'); - $loader = new DoctrineMongoDBExtension(); - - $loader->load(array(array('document_managers' => array('default' => array('mappings' => array('Xml' => array()))))), $container); - - $calls = $container->getDefinition('doctrine.odm.mongodb.default_metadata_driver')->getMethodCalls(); - $this->assertEquals('doctrine.odm.mongodb.default_xml_metadata_driver', (string) $calls[0][1][0]); - $this->assertEquals('DoctrineMongoDBBundle\Tests\DependencyInjection\Fixtures\Bundles\XmlBundle\Document', $calls[0][1][1]); - } - - public function testAnnotationsBundleMappingDetection() - { - $container = $this->getContainer('AnnotationsBundle'); - $loader = new DoctrineMongoDBExtension(); - - $loader->load(array(array('document_managers' => array('default' => array('mappings' => array('Annotations' => array()))))), $container); - - $calls = $container->getDefinition('doctrine.odm.mongodb.default_metadata_driver')->getMethodCalls(); - $this->assertEquals('doctrine.odm.mongodb.default_annotation_metadata_driver', (string) $calls[0][1][0]); - $this->assertEquals('DoctrineMongoDBBundle\Tests\DependencyInjection\Fixtures\Bundles\AnnotationsBundle\Document', $calls[0][1][1]); - } - - public function testDocumentManagerMetadataCacheDriverConfiguration() - { - $container = $this->getContainer(); - $loader = new DoctrineMongoDBExtension(); - $container->registerExtension($loader); - - $this->loadFromFile($container, 'mongodb_service_multiple_connections'); - - $container->getCompilerPassConfig()->setOptimizationPasses(array()); - $container->getCompilerPassConfig()->setRemovingPasses(array()); - $container->compile(); - - $definition = $container->getDefinition('doctrine.odm.mongodb.dm1_metadata_cache'); - $this->assertEquals('%doctrine.odm.mongodb.cache.xcache_class%', $definition->getClass()); - - $definition = $container->getDefinition('doctrine.odm.mongodb.dm2_metadata_cache'); - $this->assertEquals('%doctrine.odm.mongodb.cache.apc_class%', $definition->getClass()); - } - - public function testDocumentManagerMemcacheMetadataCacheDriverConfiguration() - { - $container = $this->getContainer(); - $loader = new DoctrineMongoDBExtension(); - $container->registerExtension($loader); - - $this->loadFromFile($container, 'mongodb_service_simple_single_connection'); - - $container->getCompilerPassConfig()->setOptimizationPasses(array()); - $container->getCompilerPassConfig()->setRemovingPasses(array()); - $container->compile(); - - $definition = $container->getDefinition('doctrine.odm.mongodb.default_metadata_cache'); - $this->assertEquals('Doctrine\Common\Cache\MemcacheCache', $definition->getClass()); - - $calls = $definition->getMethodCalls(); - $this->assertEquals('setMemcache', $calls[0][0]); - $this->assertEquals('doctrine.odm.mongodb.default_memcache_instance', (string) $calls[0][1][0]); - - $definition = $container->getDefinition('doctrine.odm.mongodb.default_memcache_instance'); - $this->assertEquals('Memcache', $definition->getClass()); - - $calls = $definition->getMethodCalls(); - $this->assertEquals('connect', $calls[0][0]); - $this->assertEquals('localhost', $calls[0][1][0]); - $this->assertEquals(11211, $calls[0][1][1]); - } - - public function testDependencyInjectionImportsOverrideDefaults() - { - $container = $this->getContainer(); - $loader = new DoctrineMongoDBExtension(); - $container->registerExtension($loader); - - $this->loadFromFile($container, 'odm_imports'); - - $container->getCompilerPassConfig()->setOptimizationPasses(array()); - $container->getCompilerPassConfig()->setRemovingPasses(array()); - $container->compile(); - - $this->assertTrue($container->getParameter('doctrine.odm.mongodb.auto_generate_proxy_classes')); - } - - public function testRegistersValidatorNamespace() - { - $container = $this->getContainer(); - - $container->setParameter('validator.annotations.namespaces', array('Namespace1\\', 'Namespace2\\')); - - $loader = new DoctrineMongoDBExtension(); - - $loader->load(array(array()), $container); - - $this->assertEquals(array( - 'Namespace1\\', - 'Namespace2\\', - 'mongodb' => 'Symfony\Bundle\DoctrineMongoDBBundle\Validator\Constraints\\', - ), $container->getParameter('validator.annotations.namespaces')); - } - - protected function getContainer($bundle = 'YamlBundle') - { - require_once __DIR__.'/Fixtures/Bundles/'.$bundle.'/'.$bundle.'.php'; - - return new ContainerBuilder(new ParameterBag(array( - 'kernel.bundles' => array(substr($bundle, 0, -6) => 'DoctrineMongoDBBundle\\Tests\\DependencyInjection\\Fixtures\\Bundles\\'.$bundle.'\\'.$bundle), - 'kernel.cache_dir' => sys_get_temp_dir(), - 'kernel.debug' => false, - ))); - } -} diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/ConfigurationTest.php deleted file mode 100644 index 21262c5e06..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/ConfigurationTest.php +++ /dev/null @@ -1,280 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\Tests\DependencyInjection; - -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Bundle\DoctrineMongoDBBundle\DependencyInjection\Configuration; -use Symfony\Component\Yaml\Yaml; - -use Symfony\Component\Config\Definition\Processor; - -class ConfigurationTest extends \PHPUnit_Framework_TestCase -{ - public function testDefaults() - { - $processor = new Processor(); - $configuration = new Configuration(false); - $options = $processor->process($configuration->getConfigTree(), array()); - - $defaults = array( - 'auto_generate_hydrator_classes' => false, - 'auto_generate_proxy_classes' => false, - 'default_database' => 'default', - 'document_managers' => array(), - 'connections' => array(), - 'proxy_namespace' => 'Proxies', - 'hydrator_namespace' => 'Hydrators', - ); - - foreach ($defaults as $key => $default) { - $this->assertTrue(array_key_exists($key, $options), sprintf('The default "%s" exists', $key)); - $this->assertEquals($default, $options[$key]); - - unset($options[$key]); - } - - if (count($options)) { - $this->fail('Extra defaults were returned: '. print_r($options, true)); - } - } - - /** - * Tests a full configuration. - * - * @dataProvider fullConfigurationProvider - */ - public function testFullConfiguration($config) - { - $processor = new Processor(); - $configuration = new Configuration(false); - $options = $processor->process($configuration->getConfigTree(), array($config)); - - $expected = array( - 'proxy_namespace' => 'Test_Proxies', - 'auto_generate_proxy_classes' => true, - 'hydrator_namespace' => 'Test_Hydrators', - 'auto_generate_hydrator_classes' => true, - 'default_document_manager' => 'default_dm_name', - 'default_database' => 'default_db_name', - 'default_connection' => 'conn1', - 'connections' => array( - 'conn1' => array( - 'server' => 'http://server', - 'options' => array( - 'connect' => true, - 'persist' => 'persist_val', - 'timeout' => 500, - 'replicaSet' => true, - 'username' => 'username_val', - 'password' => 'password_val', - ), - ), - 'conn2' => array( - 'server' => 'http://server2', - 'options' => array(), - ), - ), - 'document_managers' => array( - 'dm1' => array( - 'mappings' => array( - 'Foo' => array( - 'type' => 'annotations', - ), - ), - 'metadata_cache_driver' => array( - 'type' => 'memcache', - 'class' => 'fooClass', - 'host' => 'host_val', - 'port' => 1234, - 'instance_class' => 'instance_val', - ), - 'logging' => false, - ), - 'dm2' => array( - 'connection' => 'dm2_connection', - 'database' => 'db1', - 'mappings' => array( - 'Bar' => array( - 'type' => 'yml', - 'dir' => '%kernel.cache_dir%', - 'prefix' => 'prefix_val', - 'alias' => 'alias_val', - 'is_bundle' => false, - ) - ), - 'metadata_cache_driver' => array( - 'type' => 'apc', - ), - 'logging' => true, - ) - ) - ); - - $this->assertEquals($expected, $options); - } - - public function fullConfigurationProvider() - { - $yaml = Yaml::load(__DIR__.'/Fixtures/config/yml/full.yml'); - $yaml = $yaml['doctrine_mongo_db']; - - return array( - array($yaml), - ); - } - - /** - * @dataProvider optionProvider - * @param array $configs The source array of configuration arrays - * @param array $correctValues A key-value pair of end values to check - */ - public function testMergeOptions(array $configs, array $correctValues) - { - $processor = new Processor(); - $configuration = new Configuration(false); - $options = $processor->process($configuration->getConfigTree(), $configs); - - foreach ($correctValues as $key => $correctVal) - { - $this->assertEquals($correctVal, $options[$key]); - } - } - - public function optionProvider() - { - $cases = array(); - - // single config, testing normal option setting - $cases[] = array( - array( - array('default_document_manager' => 'foo'), - ), - array('default_document_manager' => 'foo') - ); - - // single config, testing normal option setting with dashes - $cases[] = array( - array( - array('default-document-manager' => 'bar'), - ), - array('default_document_manager' => 'bar') - ); - - // testing the normal override merging - the later config array wins - $cases[] = array( - array( - array('default_document_manager' => 'foo'), - array('default_document_manager' => 'baz'), - ), - array('default_document_manager' => 'baz') - ); - - // the "options" array is totally replaced - $cases[] = array( - array( - array('connections' => array('default' => array('options' => array('timeout' => 2000)))), - array('connections' => array('default' => array('options' => array('username' => 'foo')))), - ), - array('connections' => array('default' => array('options' => array('username' => 'foo'), 'server' => null))), - ); - - // mappings are merged non-recursively. - $cases[] = array( - array( - array('document_managers' => array('default' => array('mappings' => array('foomap' => array('type' => 'val1'), 'barmap' => array('dir' => 'val2'))))), - array('document_managers' => array('default' => array('mappings' => array('barmap' => array('prefix' => 'val3'))))), - ), - array('document_managers' => array('default' => array('logging' => false, 'mappings' => array('foomap' => array('type' => 'val1'), 'barmap' => array('prefix' => 'val3'))))), - ); - - // connections are merged non-recursively. - $cases[] = array( - array( - array('connections' => array('foocon' => array('server' => 'val1'), 'barcon' => array('options' => array('username' => 'val2')))), - array('connections' => array('barcon' => array('server' => 'val3'))), - ), - array('connections' => array( - 'foocon' => array('server' => 'val1', 'options' => array()), - 'barcon' => array('server' => 'val3', 'options' => array()) - )), - ); - - // managers are merged non-recursively. - $cases[] = array( - array( - array('document_managers' => array('foodm' => array('database' => 'val1'), 'bardm' => array('database' => 'val2'))), - array('document_managers' => array('bardm' => array('database' => 'val3'))), - ), - array('document_managers' => array( - 'foodm' => array('database' => 'val1', 'logging' => false, 'mappings' => array()), - 'bardm' => array('database' => 'val3', 'logging' => false, 'mappings' => array()), - )), - ); - - return $cases; - } - - /** - * @dataProvider getNormalizationTests - */ - public function testNormalizeOptions(array $config, $targetKey, array $normalized) - { - $processor = new Processor(); - $configuration = new Configuration(false); - $options = $processor->process($configuration->getConfigTree(), array($config)); - $this->assertSame($normalized, $options[$targetKey]); - } - - public function getNormalizationTests() - { - return array( - // connection versus connections (id is the identifier) - array( - array('connection' => array( - array('server' => 'mongodb://abc', 'id' => 'foo'), - array('server' => 'mongodb://def', 'id' => 'bar'), - )), - 'connections', - array( - 'foo' => array('server' => 'mongodb://abc', 'options' => array()), - 'bar' => array('server' => 'mongodb://def', 'options' => array()), - ), - ), - // document_manager versus document_managers (id is the identifier) - array( - array('document_manager' => array( - array('connection' => 'conn1', 'id' => 'foo'), - array('connection' => 'conn2', 'id' => 'bar'), - )), - 'document_managers', - array( - 'foo' => array('connection' => 'conn1', 'logging' => false, 'mappings' => array()), - 'bar' => array('connection' => 'conn2', 'logging' => false, 'mappings' => array()), - ), - ), - // mapping configuration that's beneath a specific document manager - array( - array('document_manager' => array( - array('id' => 'foo', 'connection' => 'conn1', 'mapping' => array( - 'type' => 'xml', 'name' => 'foo-mapping' - )), - )), - 'document_managers', - array( - 'foo' => array('connection' => 'conn1', 'mappings' => array( - 'foo-mapping' => array('type' => 'xml'), - ), 'logging' => false), - ), - ), - ); - } -} diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/DoctrineMongoDBExtensionTest.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/DoctrineMongoDBExtensionTest.php deleted file mode 100644 index 39e9f4f0a6..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/DoctrineMongoDBExtensionTest.php +++ /dev/null @@ -1,41 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\Tests\DependencyInjection; - -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Bundle\DoctrineMongoDBBundle\DependencyInjection\DoctrineMongoDBExtension; - -use Symfony\Component\Config\Definition\Processor; - -class DoctrineMongoDBExtensionTest extends \PHPUnit_Framework_TestCase -{ - /** - * @dataProvider parameterProvider - */ - public function testParameterOverride($option, $parameter, $value) - { - $container = new ContainerBuilder(); - $container->setParameter('kernel.debug', false); - $loader = new DoctrineMongoDBExtension(); - $loader->load(array(array($option => $value)), $container); - - $this->assertEquals($value, $container->getParameter('doctrine.odm.mongodb.'.$parameter)); - } - - public function parameterProvider() - { - return array( - array('proxy_namespace', 'proxy_namespace', 'foo'), - array('proxy-namespace', 'proxy_namespace', 'bar'), - ); - } -} \ No newline at end of file diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/Bundles/AnnotationsBundle/AnnotationsBundle.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/Bundles/AnnotationsBundle/AnnotationsBundle.php deleted file mode 100644 index 23b96a825d..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/Bundles/AnnotationsBundle/AnnotationsBundle.php +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - true - - - - - true - - - - - - - \ No newline at end of file diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/xml/mongodb_service_simple_single_connection.xml b/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/xml/mongodb_service_simple_single_connection.xml deleted file mode 100644 index 0663a9c314..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/xml/mongodb_service_simple_single_connection.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - true - - - - - Doctrine\Common\Cache\MemcacheCache - localhost - 11211 - Memcache - - - - \ No newline at end of file diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/xml/mongodb_service_single_connection.xml b/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/xml/mongodb_service_single_connection.xml deleted file mode 100644 index 0ee2ddb300..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/xml/mongodb_service_single_connection.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - true - - - - - - Doctrine\Common\Cache\MemcacheCache - localhost - 11211 - Memcache - - - - - \ No newline at end of file diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/xml/odm_imports.xml b/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/xml/odm_imports.xml deleted file mode 100644 index 1e215a1635..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/xml/odm_imports.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/xml/odm_imports_import.xml b/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/xml/odm_imports_import.xml deleted file mode 100644 index b06efb4628..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/xml/odm_imports_import.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/yml/full.yml b/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/yml/full.yml deleted file mode 100644 index f6032bc3f2..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/yml/full.yml +++ /dev/null @@ -1,47 +0,0 @@ -doctrine_mongo_db: - proxy_namespace: Test_Proxies - auto_generate_proxy_classes: true - - hydrator_namespace: Test_Hydrators - auto_generate_hydrator_classes: true - - default_document_manager: default_dm_name - default_database: default_db_name - - default_connection: conn1 - - connections: - conn1: - server: http://server - options: - connect: true - persist: persist_val - timeout: 500 - replicaSet: true - username: username_val - password: password_val - conn2: - server: http://server2 - - document_managers: - dm1: - mappings: - Foo: annotations - metadata_cache_driver: - type: memcache - class: fooClass - host: host_val - port: 1234 - instance_class: instance_val - dm2: - connection: dm2_connection - database: db1 - mappings: - Bar: - type: yml - dir: %kernel.cache_dir% - prefix: prefix_val - alias: alias_val - is_bundle: false - metadata_cache_driver: apc - logging: true diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/yml/mongodb_service_multiple_connections.yml b/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/yml/mongodb_service_multiple_connections.yml deleted file mode 100644 index d56d9383ee..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/yml/mongodb_service_multiple_connections.yml +++ /dev/null @@ -1,19 +0,0 @@ -doctrine_mongo_db: - default_document_manager: dm2 - default_connection: conn2 - connections: - conn1: - server: mongodb://localhost:27017 - options: - connect: true - conn2: - server: mongodb://localhost:27017 - options: - connect: true - document_managers: - dm1: - connection: conn1 - metadata_cache_driver: xcache - dm2: - connection: conn2 - metadata_cache_driver: apc diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/yml/mongodb_service_simple_single_connection.yml b/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/yml/mongodb_service_simple_single_connection.yml deleted file mode 100644 index 4e55aa119e..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/yml/mongodb_service_simple_single_connection.yml +++ /dev/null @@ -1,14 +0,0 @@ -doctrine_mongo_db: - connections: - default: - server: mongodb://localhost:27017 - options: { connect: true } - default_database: mydb - document_managers: - default: - metadata_cache_driver: - type: memcache - class: Doctrine\Common\Cache\MemcacheCache - host: localhost - port: 11211 - instance_class: Memcache \ No newline at end of file diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/yml/mongodb_service_single_connection.yml b/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/yml/mongodb_service_single_connection.yml deleted file mode 100644 index 95466f9126..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/yml/mongodb_service_single_connection.yml +++ /dev/null @@ -1,15 +0,0 @@ -doctrine_mongo_db: - connections: - default: - server: mongodb://localhost:27017 - options: - connect: true - document_managers: - default: - connection: default - metadata_cache_driver: - type: memcache - class: Doctrine\Common\Cache\MemcacheCache - host: localhost - port: 11211 - instance_class: Memcache \ No newline at end of file diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/yml/odm_imports.yml b/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/yml/odm_imports.yml deleted file mode 100644 index e4292b8662..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/yml/odm_imports.yml +++ /dev/null @@ -1,5 +0,0 @@ -imports: - - { resource: odm_imports_import.yml } - -doctrine_mongo_db: - auto_generate_proxy_classes: true diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/yml/odm_imports_import.yml b/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/yml/odm_imports_import.yml deleted file mode 100644 index 888177d921..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/config/yml/odm_imports_import.yml +++ /dev/null @@ -1,2 +0,0 @@ -doctrine_mongo_db: - auto_generate_proxy_classes: false diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/XmlMongoDBExtensionTest.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/XmlMongoDBExtensionTest.php deleted file mode 100644 index 00976d6bb9..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/XmlMongoDBExtensionTest.php +++ /dev/null @@ -1,25 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\Tests\DependencyInjection; - -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; -use Symfony\Component\Config\FileLocator; - -class XmlMongoDBExtensionTest extends AbstractMongoDBExtensionTest -{ - protected function loadFromFile(ContainerBuilder $container, $file) - { - $loadXml = new XmlFileLoader($container, new FileLocator(__DIR__.'/Fixtures/config/xml')); - $loadXml->load($file.'.xml'); - } -} \ No newline at end of file diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/YamlMongoDBExtensionTest.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/YamlMongoDBExtensionTest.php deleted file mode 100644 index 2c56e63d6a..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/YamlMongoDBExtensionTest.php +++ /dev/null @@ -1,25 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\Tests\DependencyInjection; - -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; -use Symfony\Component\Config\FileLocator; - -class YamlMongoDBExtensionTest extends AbstractMongoDBExtensionTest -{ - protected function loadFromFile(ContainerBuilder $container, $file) - { - $loadYaml = new YamlFileLoader($container, new FileLocator(__DIR__.'/Fixtures/config/yml')); - $loadYaml->load($file.'.yml'); - } -} \ No newline at end of file diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/Fixtures/Validator/Document.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/Fixtures/Validator/Document.php deleted file mode 100755 index 6c8b77d6ca..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/Fixtures/Validator/Document.php +++ /dev/null @@ -1,9 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\Tests\Logger; - -use Symfony\Bundle\DoctrineMongoDBBundle\Logger\DoctrineMongoDBLogger; - -class DoctrineMongoDBLoggerTest extends \PHPUnit_Framework_TestCase -{ - protected $logger; - - protected function setUp() - { - $this->logger = new DoctrineMongoDBLogger(); - } - - /** - * @dataProvider getQueries - */ - public function testLogger($query, $formatted) - { - $this->logger->logQuery($query); - - $this->assertEquals($formatted, $this->logger->getQueries()); - } - - public function getQueries() - { - return array( - // batchInsert - array( - array('db' => 'foo', 'collection' => 'bar', 'batchInsert' => true, 'num' => 1, 'data' => array('foo'), 'options' => array()), - array('use foo;', 'db.bar.batchInsert(**1 item(s)**);'), - ), - // find - array( - array('db' => 'foo', 'collection' => 'bar', 'find' => true, 'query' => array(), 'fields' => array()), - array('use foo;', 'db.bar.find();'), - ), - ); - } -} diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/TestCase.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/TestCase.php deleted file mode 100644 index 3e14e1bb78..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/TestCase.php +++ /dev/null @@ -1,42 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\Tests; - -use Doctrine\ODM\MongoDB\DocumentManager; -use Doctrine\MongoDB\Connection; - -class TestCase extends \PHPUnit_Framework_TestCase -{ - protected function setUp() - { - if (!class_exists('Doctrine\\ODM\\MongoDB\\Version')) { - $this->markTestSkipped('Doctrine MongoDB ODM is not available.'); - } - } - - /** - * @return DocumentManager - */ - protected function createTestDocumentManager($paths = array()) - { - $config = new \Doctrine\ODM\MongoDB\Configuration(); - $config->setAutoGenerateProxyClasses(true); - $config->setProxyDir(\sys_get_temp_dir()); - $config->setHydratorDir(\sys_get_temp_dir()); - $config->setProxyNamespace('SymfonyTests\Doctrine'); - $config->setHydratorNamespace('SymfonyTests\Doctrine'); - $config->setMetadataDriverImpl($config->newDefaultAnnotationDriver($paths)); - $config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache()); - - return DocumentManager::create(new Connection(), $config); - } -} diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/Validator/Constraints/UniqueValidatorTest.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/Validator/Constraints/UniqueValidatorTest.php deleted file mode 100755 index f3e0d6fae7..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/Validator/Constraints/UniqueValidatorTest.php +++ /dev/null @@ -1,156 +0,0 @@ -classMetadata = $this->getClassMetadata(); - $this->repository = $this->getDocumentRepository(); - $this->dm = $this->getDocumentManager($this->classMetadata, $this->repository); - $container = $this->getContainer(); - $this->validator = new UniqueValidator($container); - } - - public function tearDown() - { - unset($this->validator, $this->dm, $this->repository, $this->classMetadata); - } - - /** - * @dataProvider getFieldsPathsValuesDocumentsAndReturns - */ - public function testShouldValidateValidStringMappingValues($field, $path, $value, $document, $return) - { - $this->setFieldMapping($field, 'string'); - - $this->repository->expects($this->once()) - ->method('findOneBy') - ->with(array($path => $value)) - ->will($this->returnValue($return)); - - $this->assertTrue($this->validator->isValid($document, new Unique($path))); - } - - public function getFieldsPathsValuesDocumentsAndReturns() - { - $field = 'unique'; - $path = $field; - $value = 'someUniqueValueToBeValidated'; - $document = $this->getFixtureDocument($field, $value); - - return array( - array('unique', 'unique', 'someUniqueValueToBeValidated', $document, null), - array('unique', 'unique', 'someUniqueValueToBeValidated', $document, $document), - array('unique', 'unique', 'someUniqueValueToBeValidated', $document, $this->getFixtureDocument($field, $value)), - ); - } - - /** - * @dataProvider getFieldTypesFieldsPathsValuesAndQueries - */ - public function testGetsCorrectQueryArrayForCollection($type, $field, $path, $value, $query) - { - $this->setFieldMapping($field, $type); - $document = $this->getFixtureDocument($field, $value); - - $this->repository->expects($this->once()) - ->method('findOneBy') - ->with($query); - - $this->validator->isValid($document, new Unique($path)); - } - - public function getFieldTypesFieldsPathsValuesAndQueries() - { - $field = 'unique'; - $key = 'uniqueValue'; - $path = $field.'.'.$key; - $value = 'someUniqueValueToBeValidated'; - - return array( - array('collection', $field, $path, array($value), array($field => array('$in' => array($value)))), - array('hash', $field, $path, array($key => $value), array($path => $value)), - ); - } - - private function getContainer() - { - $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); - - $container->expects($this->once()) - ->method('get') - ->will($this->returnValue($this->dm)); - - return $container; - } - - private function getDocumentManager(ClassMetadata $classMetadata, DocumentRepository $repository) - { - $dm = $this->getMockBuilder('Doctrine\ODM\MongoDB\DocumentManager') - ->disableOriginalConstructor() - ->setMethods(array('getClassMetadata', 'getRepository')) - ->getMock(); - $dm->expects($this->any()) - ->method('getClassMetadata') - ->will($this->returnValue($classMetadata)); - $dm->expects($this->any()) - ->method('getRepository') - ->will($this->returnValue($repository)); - - return $dm; - } - - protected function getDocumentRepository() - { - $dm = $this->getMock('Doctrine\ODM\MongoDB\DocumentRepository', array('findOneBy'), array(), '', false, false); - - return $dm; - } - - protected function getClassMetadata() - { - $classMetadata = $this->getMock('Doctrine\ODM\MongoDB\Mapping\ClassMetadata', array(), array(), '', false, false); - $classMetadata->expects($this->any()) - ->method('getFieldValue') - ->will($this->returnCallback(function($document, $fieldName) { - return $document->{$fieldName}; - })); - - $classMetadata->fieldmappings = array(); - - return $classMetadata; - } - - protected function setFieldMapping($fieldName, $type, array $attributes = array()) - { - $this->classMetadata->fieldMappings[$fieldName] = array_merge(array( - 'fieldName' => $fieldName, - 'type' => $type, - ), $attributes); - } - - protected function getFixtureDocument($field, $value, $id = 1) - { - $document = new Document(); - $document->{$field} = $value; - $document->id = 1; - - return $document; - } -} diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Validator/Constraints/Unique.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Validator/Constraints/Unique.php deleted file mode 100755 index 3a29894d0d..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Validator/Constraints/Unique.php +++ /dev/null @@ -1,56 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\Validator\Constraints; - -use Symfony\Component\Validator\Constraint; - -/** - * Doctrine MongoDB ODM unique value constraint. - * - * @author Bulat Shakirzyanov - */ -class Unique extends Constraint -{ - public $message = 'The value for {{ property }} already exists.'; - public $path; - public $documentManager; - - public function getDefaultOption() - { - return 'path'; - } - - public function getRequiredOptions() - { - return array('path'); - } - - public function validatedBy() - { - return 'doctrine_odm.mongodb.unique'; - } - - public function getTargets() - { - return Constraint::CLASS_CONSTRAINT; - } - - public function getDocumentManagerId() - { - $id = 'doctrine.odm.mongodb.document_manager'; - if (null !== $this->documentManager) { - $id = sprintf('doctrine.odm.mongodb.%s_document_manager', $this->documentManager); - } - - return $id; - } -} diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Validator/Constraints/UniqueValidator.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Validator/Constraints/UniqueValidator.php deleted file mode 100755 index 3708760971..0000000000 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Validator/Constraints/UniqueValidator.php +++ /dev/null @@ -1,138 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\DoctrineMongoDBBundle\Validator\Constraints; - -use Doctrine\ODM\MongoDB\DocumentManager; -use Doctrine\ODM\MongoDB\Proxy\Proxy; -use Doctrine\ODM\MongoDB\Mapping\ClassMetadata; -use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\ConstraintValidator; - -/** - * Doctrine MongoDB ODM unique value validator. - * - * @author Bulat Shakirzyanov - */ -class UniqueValidator extends ConstraintValidator -{ - - private $container; - - public function __construct(ContainerInterface $container) - { - $this->container = $container; - } - - /** - * @param Doctrine\ODM\MongoDB\Document $value - * @param Constraint $constraint - * @return Boolean - */ - public function isValid($document, Constraint $constraint) - { - $class = get_class($document); - $dm = $this->getDocumentManager($constraint); - $metadata = $dm->getClassMetadata($class); - - if ($metadata->isEmbeddedDocument) { - throw new \InvalidArgumentException(sprintf("Document '%s' is an embedded document, and cannot be validated", $class)); - } - - $query = $this->getQueryArray($metadata, $document, $constraint->path); - - // check if document exists in mongodb - if (null === ($doc = $dm->getRepository($class)->findOneBy($query))) { - return true; - } - - // check if document in mongodb is the same document as the checked one - if ($doc === $document) { - return true; - } - - // check if returned document is proxy and initialize the minimum identifier if needed - if ($doc instanceof Proxy) { - $metadata->setIdentifierValue($doc, $doc->__identifier); - } - - // check if document has the same identifier as the current one - if ($metadata->getIdentifierValue($doc) === $metadata->getIdentifierValue($document)) { - return true; - } - - $this->context->setPropertyPath($this->context->getPropertyPath() . '.' . $constraint->path); - $this->setMessage($constraint->message, array( - '{{ property }}' => $constraint->path, - )); - return false; - } - - protected function getQueryArray(ClassMetadata $metadata, $document, $path) - { - $class = $metadata->name; - $field = $this->getFieldNameFromPropertyPath($path); - if (!isset($metadata->fieldMappings[$field])) { - throw new \LogicException('Mapping for \'' . $path . '\' doesn\'t exist for ' . $class); - } - $mapping = $metadata->fieldMappings[$field]; - if (isset($mapping['reference']) && $mapping['reference']) { - throw new \LogicException('Cannot determine uniqueness of referenced document values'); - } - switch ($mapping['type']) { - case 'one': - // TODO: implement support for embed one documents - case 'many': - // TODO: implement support for embed many documents - throw new \RuntimeException('Not Implemented.'); - case 'hash': - $value = $metadata->getFieldValue($document, $mapping['fieldName']); - return array($path => $this->getFieldValueRecursively($path, $value)); - case 'collection': - return array($mapping['fieldName'] => array('$in' => $metadata->getFieldValue($document, $mapping['fieldName']))); - default: - return array($mapping['fieldName'] => $metadata->getFieldValue($document, $mapping['fieldName'])); - } - } - - /** - * Returns the actual document field value - * - * E.g. document.someVal -> document - * user.emails -> user - * username -> username - * - * @param string $field - * @return string - */ - private function getFieldNameFromPropertyPath($field) - { - $pieces = explode('.', $field); - return $pieces[0]; - } - - private function getFieldValueRecursively($fieldName, $value) - { - $pieces = explode('.', $fieldName); - unset($pieces[0]); - foreach ($pieces as $piece) { - $value = $value[$piece]; - } - return $value; - } - - private function getDocumentManager(Unique $constraint) - { - return $this->container->get($constraint->getDocumentManagerId()); - } - -} diff --git a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/TemplatePathsCacheWarmer.php b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/TemplatePathsCacheWarmer.php index fe0e971b5c..b8a142f03c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/TemplatePathsCacheWarmer.php +++ b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/TemplatePathsCacheWarmer.php @@ -15,6 +15,7 @@ use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmer; use Symfony\Component\HttpKernel\KernelInterface; use Symfony\Component\Finder\Finder; use Symfony\Bundle\FrameworkBundle\Templating\TemplateNameParser; +use Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateLocator; /** * Computes the association between template names and their paths on the disk. @@ -24,20 +25,23 @@ use Symfony\Bundle\FrameworkBundle\Templating\TemplateNameParser; class TemplatePathsCacheWarmer extends CacheWarmer { protected $kernel; - protected $rootDir; protected $parser; + protected $rootDir; + protected $locator; /** * Constructor. * * @param KernelInterface $kernel A KernelInterface instance * @param TemplateNameParser $parser A TemplateNameParser instance + * @param TemplateLocator $locator The template locator * @param string $rootDir The directory where global templates can be stored */ - public function __construct(KernelInterface $kernel, TemplateNameParser $parser, $rootDir) + public function __construct(KernelInterface $kernel, TemplateNameParser $parser, TemplateLocator $locator, $rootDir) { $this->kernel = $kernel; $this->parser = $parser; + $this->locator = $locator; $this->rootDir = $rootDir; } @@ -51,7 +55,6 @@ class TemplatePathsCacheWarmer extends CacheWarmer $templates = array(); foreach ($this->kernel->getBundles() as $name => $bundle) { - $templates += $this->findTemplatesIn($this->rootDir.'/'.$name.'/views', $name); $templates += $this->findTemplatesIn($bundle->getPath().'/Resources/views', $name); } @@ -88,9 +91,9 @@ class TemplatePathsCacheWarmer extends CacheWarmer $template = $this->parser->parseFromFilename($file->getRelativePathname()); if (false !== $template) { if (null !== $bundle) { - $template->set('bundle', $bundle); + $template->set('bundle', $bundle); } - $templates[$template->getSignature()] = $file->getRealPath(); + $templates[$template->getSignature()] = $this->locator->locate($template); } } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Client.php b/src/Symfony/Bundle/FrameworkBundle/Client.php index 91b4b63cf6..9329c21b63 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Client.php +++ b/src/Symfony/Bundle/FrameworkBundle/Client.php @@ -14,8 +14,6 @@ namespace Symfony\Bundle\FrameworkBundle; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\Client as BaseClient; -use Symfony\Component\BrowserKit\History; -use Symfony\Component\BrowserKit\CookieJar; use Symfony\Component\HttpKernel\Profiler\Profiler as HttpProfiler; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -27,23 +25,6 @@ use Symfony\Component\HttpFoundation\Response; */ class Client extends BaseClient { - protected $container; - - /** - * Constructor. - * - * @param HttpKernelInterface $kernel An HttpKernelInterface instance - * @param array $server The server parameters (equivalent of $_SERVER) - * @param History $history A History instance to store the browser history - * @param CookieJar $cookieJar A CookieJar instance to store the cookies - */ - public function __construct(HttpKernelInterface $kernel, array $server = array(), History $history = null, CookieJar $cookieJar = null) - { - parent::__construct($kernel, $server, $history, $cookieJar); - - $this->container = $kernel->getContainer(); - } - /** * Returns the container. * @@ -51,7 +32,7 @@ class Client extends BaseClient */ public function getContainer() { - return $this->container; + return $this->kernel->getContainer(); } /** @@ -71,11 +52,11 @@ class Client extends BaseClient */ public function getProfiler() { - if (!$this->container->has('profiler')) { + if (!$this->kernel->getContainer()->has('profiler')) { return false; } - return $this->container->get('profiler')->loadFromResponse($this->response); + return $this->kernel->getContainer()->get('profiler')->loadFromResponse($this->response); } /** @@ -87,10 +68,9 @@ class Client extends BaseClient */ protected function doRequest($request) { - $returnValue = $this->kernel->handle($request); $this->kernel->shutdown(); - return $returnValue; + return $this->kernel->handle($request); } /** diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php index 1f80df8366..8cf0c09332 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php @@ -18,7 +18,7 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\Output; /** - * AssetsInstallCommand. + * Command that places bundle web assets into a given directory. * * @author Fabien Potencier */ @@ -31,9 +31,23 @@ class AssetsInstallCommand extends Command { $this ->setDefinition(array( - new InputArgument('target', InputArgument::REQUIRED, 'The target directory'), + new InputArgument('target', InputArgument::REQUIRED, 'The target directory (usually "web")'), )) ->addOption('symlink', null, InputOption::VALUE_NONE, 'Symlinks the assets instead of copying it') + ->setHelp(<<assets:install command installs bundle assets into a given +directory (e.g. the web directory). + +./app/console assets:install web [--symlink] + +A "bundles" directory will be created inside the target directory, and the +"Resources/public" directory of each bundle will be copied into it. + +To create a symlink to each bundle instead of copying its assets, use the +--symlink option. + +EOT + ) ->setName('assets:install') ; } @@ -56,10 +70,10 @@ class AssetsInstallCommand extends Command foreach ($this->container->get('kernel')->getBundles() as $bundle) { if (is_dir($originDir = $bundle->getPath().'/Resources/public')) { - $output->writeln(sprintf('Installing assets for %s', $bundle->getNamespace())); - $targetDir = $input->getArgument('target').'/bundles/'.preg_replace('/bundle$/', '', strtolower($bundle->getName())); + $output->writeln(sprintf('Installing assets for %s into %s', $bundle->getNamespace(), $targetDir)); + $filesystem->remove($targetDir); if ($input->getOption('symlink')) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php index bf1f323685..14ef5f12ca 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php @@ -57,7 +57,7 @@ EOF $oldCacheDir = $realCacheDir.'_old'; if (!is_writable($realCacheDir)) { - throw new \RuntimeException(sprintf('Unable to write in the "%s" directory', $this->realCacheDir)); + throw new \RuntimeException(sprintf('Unable to write in the "%s" directory', $realCacheDir)); } if ($input->getOption('no-warmup')) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php index 0195ff4648..8aeb8193ce 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php @@ -49,13 +49,7 @@ The container:debug displays all configured publiccontainer:debug -You can also search for specific services using wildcards (*): - - container:debug doctrine.* - - container:debug *event_manager - -To get specific information about a service, use specify its name exactly: +To get specific information about a service, specify its name: container:debug validator @@ -73,20 +67,23 @@ EOF */ protected function execute(InputInterface $input, OutputInterface $output) { - $filter = $input->getArgument('name'); + $name = $input->getArgument('name'); $this->containerBuilder = $this->getContainerBuilder(); - $serviceIds = $this->filterServices($this->containerBuilder->getServiceIds(), $filter); + $serviceIds = $this->containerBuilder->getServiceIds(); - if (1 == count($serviceIds) && false === strpos($filter, '*')) { - $this->outputService($output, $serviceIds[0]); + // sort so that it reads like an index of services + asort($serviceIds); + + if ($name) { + $this->outputService($output, $name); } else { $showPrivate = $input->getOption('show-private'); - $this->outputServices($output, $serviceIds, $filter, $showPrivate); + $this->outputServices($output, $serviceIds, $showPrivate); } } - protected function outputServices(OutputInterface $output, $serviceIds, $filter, $showPrivate = false) + protected function outputServices(OutputInterface $output, $serviceIds, $showPrivate = false) { // set the label to specify public or public+private if ($showPrivate) { @@ -95,9 +92,6 @@ EOF $label = 'Public services'; } - if ($filter) { - $label .= sprintf(' matching %s', $filter); - } $output->writeln($this->getHelper('formatter')->formatSection('container', $label)); // loop through to find get space needed and filter private services @@ -215,74 +209,4 @@ EOF // the service has been injected in some special way, just return the service return $this->containerBuilder->get($serviceId); } - - /** - * Filters the given array of service ids by the given string filter: - * - * * An exact filter, "foo", will return *only* the "foo" service - * * A wildcard filter, "foo*", will return all services matching the wildcard - * - * @param array $serviceIds The array of service ids - * @param string $filter The given filter. If ending in *, a wildcard - * @return array - */ - private function filterServices($serviceIds, $filter, $onlyPublic = true) - { - // alphabetical so that this reads like an index of services - asort($serviceIds); - - if (!$filter) { - return $serviceIds; - } - - $regex = $this->buildFilterRegularExpression($filter); - $filteredIds = array(); - foreach ($serviceIds as $serviceId) { - if (preg_match($regex, $serviceId)) { - $filteredIds[] = $serviceId; - } - } - - if (!$filteredIds) { - // give a different message if the use was searching for an exact service - if (false === strpos($filter, '*')) { - $message = sprintf('The service "%s" does not exist.', $filter); - } else { - $message = sprintf('No services matched the pattern "%s"', $filter); - } - - throw new \InvalidArgumentException($message); - } - - return $filteredIds; - } - - /** - * Given a string with wildcards denoted as asterisks (*), this returns - * the regular expression that can be used to match on the string. - * - * For example, *foo* would equate to: - * - * /^(.+?)*foo(.+?)*$/ - * - * @param string $filter The raw filter - * @return string The regular expression - */ - private function buildFilterRegularExpression($filter) - { - $regex = preg_quote(str_replace('*', '', $filter)); - - // process the "front" wildcard - if ('*' === substr($filter, 0, 1)) { - $regex = '(.+?)*'.$regex; - } - - // process the "end" wildcard - if ('*' === substr($filter, -1, 1)) { - $regex .= '(.+?)*'; - } - $regex = sprintf('/^%s$/', $regex); - - return $regex; - } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/InitBundleCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/InitBundleCommand.php index 9c602a009c..72b84c24b6 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/InitBundleCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/InitBundleCommand.php @@ -66,6 +66,7 @@ EOT } // validate namespace + $namespace = strtr($namespace, '/', '\\'); if (preg_match('/[^A-Za-z0-9_\\\-]/', $namespace)) { throw new \InvalidArgumentException('The namespace contains invalid characters.'); } @@ -96,8 +97,6 @@ EOT $targetDir = $dir.strtr($namespace, '\\', '/'); - - if (file_exists($targetDir)) { throw new \RuntimeException(sprintf('Bundle "%s" already exists.', $bundle)); } @@ -107,9 +106,8 @@ EOT $filesystem->mirror(__DIR__.'/../Resources/skeleton/bundle/'.$input->getOption('format'), $targetDir); Mustache::renderDir($targetDir, array( - 'namespace' => $namespace, - 'bundle' => $bundle, - 'bundleShort' => preg_replace('/Bundle$/', '', $bundle), + 'namespace' => $namespace, + 'bundle' => $bundle, )); rename($targetDir.'/Bundle.php', $targetDir.'/'.$bundle.'.php'); diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/RouterDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/RouterDebugCommand.php index e5d18d5bce..bf5503bf4a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/RouterDebugCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/RouterDebugCommand.php @@ -161,6 +161,10 @@ EOF return sprintf('object(%s)', get_class($value)); } + if (is_string($value)) { + return $value; + } + return preg_replace("/\n\s*/s", '', var_export($value, true)); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/ContainerAwareEventDispatcher.php b/src/Symfony/Bundle/FrameworkBundle/ContainerAwareEventDispatcher.php index 539f908f49..87479a0aa6 100644 --- a/src/Symfony/Bundle/FrameworkBundle/ContainerAwareEventDispatcher.php +++ b/src/Symfony/Bundle/FrameworkBundle/ContainerAwareEventDispatcher.php @@ -34,7 +34,7 @@ class ContainerAwareEventDispatcher extends EventDispatcher * The service IDs of the event listeners and subscribers * @var array */ - private $listenerIds; + private $listenerIds = array(); /** * Constructor. @@ -49,22 +49,21 @@ class ContainerAwareEventDispatcher extends EventDispatcher /** * Adds a service as event listener * - * @param string|array $events One or more events for which the listener - * is added - * @param string $serviceId The ID of the listener service - * @param integer $priority The higher this value, the earlier an event - * listener will be triggered in the chain. - * Defaults to 0. + * @param string|array $eventNames One or more events for which the listener is added + * @param string $serviceId The ID of the listener service + * @param integer $priority The higher this value, the earlier an event listener + * will be triggered in the chain. + * Defaults to 0. */ - public function addListenerService($events, $serviceId, $priority = 0) + public function addListenerService($eventNames, $serviceId, $priority = 0) { if (!is_string($serviceId)) { throw new \InvalidArgumentException('Expected a string argument'); } - foreach ((array) $events as $event) { + foreach ((array) $eventNames as $eventName) { // Prevent duplicate entries - $this->listenerIds[$event][$serviceId] = $priority; + $this->listenerIds[$eventName][$serviceId] = $priority; } } @@ -73,6 +72,8 @@ class ContainerAwareEventDispatcher extends EventDispatcher * * Lazily loads listeners for this event from the dependency injection * container. + * + * @throws \InvalidArgumentException if the service is not defined */ public function dispatch($eventName, Event $event = null) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php b/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php index 8c9efb09a0..4e15c163ad 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php +++ b/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php @@ -14,6 +14,7 @@ namespace Symfony\Bundle\FrameworkBundle\Controller; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\DependencyInjection\ContainerAware; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * Controller is a simple implementation of a Controller. @@ -41,7 +42,7 @@ class Controller extends ContainerAware /** * Forwards the request to another controller. * - * @param string $controller The controller name (a string like Blog:Post:index) + * @param string $controller The controller name (a string like BlogBundle:Post:index) * @param array $path An array of path parameters * @param array $query An array of query parameters * @@ -92,6 +93,20 @@ class Controller extends ContainerAware return $this->container->get('templating')->renderResponse($view, $parameters, $response); } + /** + * Returns a NotFoundHttpException. + * + * This will result in a 404 response code. Usage example: + * + * throw $this->createNotFoundException('Page not found!'); + * + * @return NotFoundHttpException + */ + public function createNotFoundException($message = 'Not Found', \Exception $previous = null) + { + return new NotFoundHttpException($message, $previous); + } + /** * Returns true if the service id is defined. * diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php b/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php index b1a948fc57..86dd9cea24 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php +++ b/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php @@ -16,7 +16,7 @@ use Symfony\Component\HttpKernel\Log\LoggerInterface; /** * ControllerNameParser converts controller from the short notation a:b:c - * (Blog:Post:index) to a fully-qualified class::method string + * (BlogBundle:Post:index) to a fully-qualified class::method string * (Bundle\BlogBundle\Controller\PostController::indexAction). * * @author Fabien Potencier diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/ExceptionController.php b/src/Symfony/Bundle/FrameworkBundle/Controller/ExceptionController.php index 1563879571..7c345111e3 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Controller/ExceptionController.php +++ b/src/Symfony/Bundle/FrameworkBundle/Controller/ExceptionController.php @@ -49,12 +49,12 @@ class ExceptionController extends ContainerAware if ($this->container->get('kernel')->isDebug() && 'html' == $format) { $name = 'exception_full'; } - $template = 'Framework:Exception:'.$name.'.'.$format.'.twig'; + $template = 'FrameworkBundle:Exception:'.$name.'.'.$format.'.twig'; $templating = $this->container->get('templating'); if (!$templating->exists($template)) { $this->container->get('request')->setRequestFormat('html'); - $template = 'Framework:Exception:'.$name.'.html.twig'; + $template = 'FrameworkBundle:Exception:'.$name.'.html.twig'; } $code = $exception->getStatusCode(); diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php b/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php index 81d40ce8da..40f9a729b2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php +++ b/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php @@ -51,23 +51,43 @@ class RedirectController extends ContainerAware /** * Redirects to a URL. * - * It expects a url path parameter. * By default, the response status code is 301. * - * If the url is empty, the status code will be 410. - * If the permanent path parameter is set, the status code will be 302. + * If the path is empty, the status code will be 410. + * If the permanent flag is set, the status code will be 302. * - * @param string $url The url to redirect to + * @param string $path The path to redirect to * @param Boolean $permanent Whether the redirect is permanent or not + * @param Boolean $scheme The URL scheme (null to keep the current one) + * @param integer $httpPort The HTTP port + * @param integer $httpsPort The HTTPS port * * @return Response A Response instance */ - public function urlRedirectAction($url, $permanent = false) + public function urlRedirectAction($path, $permanent = false, $scheme = null, $httpPort = 80, $httpsPort = 443) { - if (!$url) { + if (!$path) { return new Response(null, 410); } + $request = $this->container->get('request'); + if (null === $scheme) { + $scheme = $request->getScheme(); + } + $qs = $request->getQueryString(); + if ($qs) { + $qs = '?'.$qs; + } + + $port = ''; + if ('http' === $scheme && 80 != $httpPort) { + $port = ':'.$httpPort; + } elseif ('https' === $scheme && 443 != $httpPort) { + $port = ':'.$httpsPort; + } + + $url = $scheme.'://'.$request->getHttpHost().$port.$request->getBaseUrl().$path.$qs; + return new RedirectResponse($url, $permanent ? 301 : 302); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Debug/TraceableEventDispatcher.php b/src/Symfony/Bundle/FrameworkBundle/Debug/TraceableEventDispatcher.php index 24747f6683..bdea0f0456 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Debug/TraceableEventDispatcher.php +++ b/src/Symfony/Bundle/FrameworkBundle/Debug/TraceableEventDispatcher.php @@ -24,8 +24,9 @@ use Symfony\Component\EventDispatcher\Event; */ class TraceableEventDispatcher extends ContainerAwareEventDispatcher implements TraceableEventDispatcherInterface { - protected $logger; - protected $called; + private $logger; + private $called; + private $container; /** * Constructor. @@ -37,10 +38,33 @@ class TraceableEventDispatcher extends ContainerAwareEventDispatcher implements { parent::__construct($container); + $this->container = $container; $this->logger = $logger; $this->called = array(); } + /** + * {@inheritDoc} + * + * @throws \RuntimeException if the listener method is not callable + */ + public function addListener($eventNames, $listener, $priority = 0) + { + if (!$listener instanceof \Closure) { + foreach ((array) $eventNames as $method) { + if (!is_callable(array($listener, $method))) { + $msg = sprintf('The event method "%s()" is not callable on the class "%s".', $method, get_class($listener)); + if (null !== $this->logger) { + $this->logger->err($msg); + } + throw new \RuntimeException($msg); + } + } + } + + parent::addListener($eventNames, $listener, $priority); + } + /** * {@inheritDoc} */ @@ -48,30 +72,25 @@ class TraceableEventDispatcher extends ContainerAwareEventDispatcher implements { parent::triggerListener($listener, $eventName, $event); - $listenerString = $this->listenerToString($listener); - if (null !== $this->logger) { - $this->logger->debug(sprintf('Notified event "%s" to listener "%s"', $eventName, $listenerString)); + $this->logger->debug(sprintf('Notified event "%s" to listener "%s".', $eventName, get_class($listener))); } - $this->called[$eventName.'.'.$listenerString] = array( - 'class' => $listenerString, - 'event' => $eventName, - ); + $this->called[$eventName.'.'.get_class($listener)] = $this->getListenerInfo($listener, $eventName); if ($event->isPropagationStopped() && null !== $this->logger) { - $this->logger->debug(sprintf('Listener "%s" stopped propagation of the event "%s"', $this->listenerToString($listener), $eventName)); + $this->logger->debug(sprintf('Listener "%s" stopped propagation of the event "%s".', get_class($listener), $eventName)); $skippedListeners = $this->getListeners($eventName); $skipped = false; foreach ($skippedListeners as $skippedListener) { if ($skipped) { - $this->logger->debug(sprintf('Listener "%s" was not called for event "%s"', $this->listenerToString($skippedListener), $eventName)); + $this->logger->debug(sprintf('Listener "%s" was not called for event "%s".', get_class($skippedListener), $eventName)); } if ($skippedListener === $listener) { - $skipped = false; + $skipped = true; } } } @@ -93,12 +112,8 @@ class TraceableEventDispatcher extends ContainerAwareEventDispatcher implements $notCalled = array(); foreach (array_keys($this->getListeners()) as $name) { foreach ($this->getListeners($name) as $listener) { - $listener = $this->listenerToString($listener); - if (!isset($this->called[$name.'.'.$listener])) { - $notCalled[] = array( - 'class' => $listener, - 'event' => $name, - ); + if (!isset($this->called[$name.'.'.get_class($listener)])) { + $notCalled[$name.'.'.get_class($listener)] = $this->getListenerInfo($listener, $name); } } } @@ -106,18 +121,37 @@ class TraceableEventDispatcher extends ContainerAwareEventDispatcher implements return $notCalled; } - protected function listenerToString($listener) + /** + * Returns information about the listener + * + * @param object $listener The listener + * @param string $eventName The event name + * + * @return array Informations about the listener + */ + private function getListenerInfo($listener, $eventName) { - if (is_object($listener)) { - if ($listener instanceof \Closure) { - return 'Closure'; + $info = array('event' => $eventName); + if ($listener instanceof \Closure) { + $info += array('type' => 'Closure'); + } else { + $class = get_class($listener); + try { + $r = new \ReflectionMethod($class, $eventName); + $file = $r->getFileName(); + $line = $r->getStartLine(); + } catch (\ReflectionException $e) { + $file = null; + $line = null; } - - return get_class($listener); + $info += array( + 'type' => 'Method', + 'class' => $class, + 'file' => $file, + 'line' => $line + ); } - if (is_array($listener)) { - return is_object($listener[0]) ? get_class($listener[0]) : implode('::', $listener); - } + return $info; } } diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddCacheWarmerPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddCacheWarmerPass.php index b69e79a159..170c33e360 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddCacheWarmerPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddCacheWarmerPass.php @@ -41,7 +41,7 @@ class AddCacheWarmerPass implements CompilerPassInterface krsort($warmers); $warmers = call_user_func_array('array_merge', $warmers); - $container->getDefinition('cache_warmer')->setArgument(0, $warmers); + $container->getDefinition('cache_warmer')->replaceArgument(0, $warmers); if ('full' === $container->getParameter('kernel.cache_warmup')) { $container->getDefinition('cache_warmer')->addMethodCall('enableOptionalWarmers', array()); diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddConstraintValidatorsPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddConstraintValidatorsPass.php index 574282ea34..99ee9d6280 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddConstraintValidatorsPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddConstraintValidatorsPass.php @@ -29,6 +29,6 @@ class AddConstraintValidatorsPass implements CompilerPassInterface } } - $container->getDefinition('validator.validator_factory')->setArgument(1, $validators); + $container->getDefinition('validator.validator_factory')->replaceArgument(1, $validators); } } \ No newline at end of file diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddFieldFactoryGuessersPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddFieldFactoryGuessersPass.php index 0a0a977147..ef88acf730 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddFieldFactoryGuessersPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddFieldFactoryGuessersPass.php @@ -33,6 +33,6 @@ class AddFieldFactoryGuessersPass implements CompilerPassInterface return new Reference($id); }, array_keys($container->findTaggedServiceIds('form.field_factory.guesser'))); - $container->getDefinition('form.field_factory')->setArgument(0, $guessers); + $container->getDefinition('form.field_factory')->replaceArgument(0, $guessers); } } \ No newline at end of file diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CompilerDebugDumpPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CompilerDebugDumpPass.php new file mode 100644 index 0000000000..9d5507082b --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CompilerDebugDumpPass.php @@ -0,0 +1,24 @@ +getCompilerLogFilename($container), false); + $cache->write(implode("\n", $container->getCompiler()->getLog())); + } + + public static function getCompilerLogFilename(ContainerInterface $container) + { + $class = $container->getParameter('kernel.container_class'); + + return $container->getParameter('kernel.cache_dir').'/'.$class.'Compiler.log'; + } +} \ No newline at end of file diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php index 931be56deb..b45e2d4582 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php @@ -4,34 +4,45 @@ namespace Symfony\Bundle\FrameworkBundle\DependencyInjection; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; /** * FrameworkExtension configuration structure. * * @author Jeremy Mikola */ -class Configuration +class Configuration implements ConfigurationInterface { + private $debug; + /** - * Generates the configuration tree. + * Constructor * - * @param boolean $kernelDebug The kernel.debug DIC parameter - * - * @return \Symfony\Component\Config\Definition\ArrayNode The config tree + * @param Boolean $debug Wether to use the debug mode */ - public function getConfigTree($kernelDebug) + public function __construct($debug) + { + $this->debug = (Boolean) $debug; + } + + /** + * Generates the configuration tree builder. + * + * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder + */ + public function getConfigTreeBuilder() { $treeBuilder = new TreeBuilder(); $rootNode = $treeBuilder->root('framework'); $rootNode ->children() - ->scalarNode('cache_warmer')->defaultValue(!$kernelDebug)->end() + ->scalarNode('cache_warmer')->defaultValue(!$this->debug)->end() ->scalarNode('charset')->end() ->scalarNode('document_root')->end() ->scalarNode('error_handler')->end() ->scalarNode('exception_controller')->defaultValue('Symfony\\Bundle\\FrameworkBundle\\Controller\\ExceptionController::showAction')->end() - ->scalarNode('ide')->end() + ->scalarNode('ide')->defaultNull()->end() ->booleanNode('test')->end() ->end() ; @@ -45,7 +56,7 @@ class Configuration $this->addTranslatorSection($rootNode); $this->addValidationSection($rootNode); - return $treeBuilder->buildTree(); + return $treeBuilder; } private function addCsrfProtectionSection(ArrayNodeDefinition $rootNode) @@ -90,6 +101,7 @@ class Configuration ->canBeUnset() ->children() ->booleanNode('only_exceptions')->defaultValue(false)->end() + ->booleanNode('only_master_requests')->defaultValue(false)->end() ->scalarNode('dsn')->defaultValue('sqlite:%kernel.cache_dir%/profiler.db')->end() ->scalarNode('username')->defaultValue('')->end() ->scalarNode('password')->defaultValue('')->end() @@ -119,6 +131,8 @@ class Configuration ->scalarNode('cache_warmer')->defaultFalse()->end() ->scalarNode('resource')->isRequired()->end() ->scalarNode('type')->end() + ->scalarNode('http_port')->defaultValue(80)->end() + ->scalarNode('https_port')->defaultValue(443)->end() ->end() ->end() ->end() @@ -183,12 +197,7 @@ class Configuration ->ifTrue(function($v){ return !is_array($v); }) ->then(function($v){ return array($v); }) ->end() - ->prototype('scalar') - ->beforeNormalization() - ->ifTrue(function($v) { return is_array($v) && isset($v['value']); }) - ->then(function($v){ return $v['value']; }) - ->end() - ->end() + ->prototype('scalar')->end() ->end() ->scalarNode('cache')->end() ->scalarNode('cache_warmer')->defaultFalse()->end() @@ -201,13 +210,8 @@ class Configuration ->beforeNormalization() ->ifTrue(function($v){ return !is_array($v); }) ->then(function($v){ return array($v); }) - ->end() - ->prototype('scalar') - ->beforeNormalization() - ->ifTrue(function($v) { return is_array($v) && isset($v['id']); }) - ->then(function($v){ return $v['id']; }) - ->end() ->end() + ->prototype('scalar')->end() ->end() ->end() ->fixXmlConfig('loader') @@ -225,18 +229,11 @@ class Configuration ->arrayNode('packages') ->useAttributeAsKey('name') ->prototype('array') - ->children() - ->scalarNode('version')->defaultNull()->end() - ->end() ->fixXmlConfig('base_url') ->children() + ->scalarNode('version')->defaultNull()->end() ->arrayNode('base_urls') - ->prototype('scalar') - ->beforeNormalization() - ->ifTrue(function($v) { return is_array($v) && isset($v['value']); }) - ->then(function($v){ return $v['value']; }) - ->end() - ->end() + ->prototype('scalar')->end() ->end() ->end() ->end() @@ -279,6 +276,7 @@ class Configuration ->end() ->children() ->booleanNode('enabled')->end() + ->scalarNode('cache')->end() ->arrayNode('annotations') ->canBeUnset() ->treatNullLike(array()) @@ -287,12 +285,7 @@ class Configuration ->children() ->arrayNode('namespaces') ->useAttributeAsKey('prefix') - ->prototype('scalar') - ->beforeNormalization() - ->ifTrue(function($v) { return is_array($v) && isset($v['namespace']); }) - ->then(function($v){ return $v['namespace']; }) - ->end() - ->end() + ->prototype('scalar')->end() ->end() ->end() ->end() diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index eb91be85fc..f2297d3f4e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -15,12 +15,12 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Parameter; use Symfony\Component\DependencyInjection\Reference; -use Symfony\Component\Config\Definition\Processor; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; use Symfony\Component\Config\Resource\FileResource; use Symfony\Component\Finder\Finder; use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\Config\FileLocator; +use Symfony\Component\Config\Definition\Processor; /** * FrameworkExtension. @@ -56,9 +56,8 @@ class FrameworkExtension extends Extension } $processor = new Processor(); - $configuration = new Configuration(); - - $config = $processor->process($configuration->getConfigTree($container->getParameter('kernel.debug')), $configs); + $configuration = new Configuration($container->getParameter('kernel.debug')); + $config = $processor->processConfiguration($configuration, $configs); $container->setParameter('kernel.cache_warmup', $config['cache_warmer']); @@ -76,26 +75,18 @@ class FrameworkExtension extends Extension } else { $container ->getDefinition('error_handler')->addMethodCall('register', array()) - ->setArgument(0, $config['error_handler']) + ->replaceArgument(0, $config['error_handler']) ; } } - $container->getDefinition('exception_listener')->setArgument(0, $config['exception_controller']); - - $pattern = ''; - if (isset($config['ide'])) { - $patterns = array( - 'textmate' => 'txmt://open?url=file://%%f&line=%%l', - 'macvim' => 'mvim://open?url=file://%%f&line=%%l', - ); - $pattern = isset($patterns[$config['ide']]) ? $patterns[$config['ide']] : $config['ide']; - } - $container->setParameter('debug.file_link_format', $pattern); + $container->getDefinition('exception_listener')->replaceArgument(0, $config['exception_controller']); if (!empty($config['test'])) { $loader->load('test.xml'); - $config['session']['storage_id'] = 'array'; + if (isset($config['session'])) { + $config['session']['storage_id'] = 'filesystem'; + } } if (isset($config['csrf_protection'])) { @@ -119,7 +110,7 @@ class FrameworkExtension extends Extension } if (isset($config['templating'])) { - $this->registerTemplatingConfiguration($config['templating'], $container, $loader); + $this->registerTemplatingConfiguration($config['templating'], $config['ide'], $container, $loader); } if (isset($config['translator'])) { @@ -203,7 +194,8 @@ class FrameworkExtension extends Extension $loader->load('collectors.xml'); $container->getDefinition('profiler_listener') - ->setArgument(2, $config['only_exceptions']) + ->replaceArgument(2, $config['only_exceptions']) + ->replaceArgument(3, $config['only_master_requests']) ; // Choose storage class based on the DSN @@ -217,10 +209,10 @@ class FrameworkExtension extends Extension } $container->getDefinition('profiler.storage') - ->setArgument(0, $config['dsn']) - ->setArgument(1, $config['username']) - ->setArgument(2, $config['password']) - ->setArgument(3, $config['lifetime']) + ->replaceArgument(0, $config['dsn']) + ->replaceArgument(1, $config['username']) + ->replaceArgument(2, $config['password']) + ->replaceArgument(3, $config['lifetime']) ->setClass($supported[$class]) ; @@ -264,6 +256,10 @@ class FrameworkExtension extends Extension $container->setAlias('router', 'router.cached'); } + $def = $container->getDefinition('request_listener'); + $def->replaceArgument(2, $config['http_port']); + $def->replaceArgument(3, $config['https_port']); + $this->addClassesToCompile(array( 'Symfony\\Component\\Routing\\RouterInterface', 'Symfony\\Component\\Routing\\Matcher\\UrlMatcherInterface', @@ -293,7 +289,7 @@ class FrameworkExtension extends Extension $container->setParameter('session.class', $config['class']); } - $container->getDefinition('session')->setArgument(1, $config['default_locale']); + $container->getDefinition('session')->replaceArgument(1, $config['default_locale']); $container->setAlias('session.storage', 'session.storage.'.$config['storage_id']); @@ -319,11 +315,21 @@ class FrameworkExtension extends Extension * @param ContainerBuilder $container A ContainerBuilder instance * @param XmlFileLoader $loader An XmlFileLoader instance */ - private function registerTemplatingConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader) + private function registerTemplatingConfiguration(array $config, $ide, ContainerBuilder $container, XmlFileLoader $loader) { $loader->load('templating.xml'); $loader->load('templating_php.xml'); + $links = array( + 'textmate' => 'txmt://open?url=file://%f&line=%l', + 'macvim' => 'mvim://open?url=file://%f&line=%l', + ); + + $container + ->getDefinition('templating.helper.code') + ->replaceArgument(0, str_replace('%', '%%', isset($links[$ide]) ? $links[$ide] : $ide)) + ; + if ($container->getParameter('kernel.debug')) { $loader->load('templating_debug.xml'); } @@ -337,9 +343,9 @@ class FrameworkExtension extends Extension } $container ->getDefinition('templating.helper.assets') - ->setArgument(1, isset($config['assets_base_urls']) ? $config['assets_base_urls'] : array()) - ->setArgument(2, $config['assets_version']) - ->setArgument(3, $packages) + ->replaceArgument(1, isset($config['assets_base_urls']) ? $config['assets_base_urls'] : array()) + ->replaceArgument(2, $config['assets_version']) + ->replaceArgument(3, $packages) ; if (!empty($config['loaders'])) { @@ -357,15 +363,20 @@ class FrameworkExtension extends Extension if (isset($config['cache'])) { // Wrap the existing loader with cache (must happen after loaders are registered) $container->setDefinition('templating.loader.wrapped', $container->findDefinition('templating.loader')); - $container->setDefinition('templating.loader', $container->getDefinition('templating.loader.cache')); - $container->setParameter('templating.loader.cache.path', $config['cache']); - } else { - $container->setParameter('templating.loader.cache.path', null); + $loaderCache = $container->getDefinition('templating.loader.cache'); + $loaderCache->replaceArgument(1, $config['cache']); + + $container->setDefinition('templating.loader', $loaderCache); } if ($config['cache_warmer']) { - $container->getDefinition('templating.cache_warmer.template_paths')->addTag('kernel.cache_warmer'); + $container + ->getDefinition('templating.cache_warmer.template_paths') + ->addTag('kernel.cache_warmer', array('priority' => 20)) + ; $container->setAlias('templating.locator', 'templating.locator.cached'); + } else { + $container->setAlias('templating.locator', 'templating.locator.uncached'); } $this->addClassesToCompile(array( @@ -399,7 +410,7 @@ class FrameworkExtension extends Extension if (1 === count($engines)) { $container->setAlias('templating', (string) reset($engines)); } else { - $container->getDefinition('templating.engine.delegating')->setArgument(1, $engines); + $container->getDefinition('templating.engine.delegating')->replaceArgument(1, $engines); $container->setAlias('templating', 'templating.engine.delegating'); } } @@ -462,12 +473,12 @@ class FrameworkExtension extends Extension $container ->getDefinition('validator.mapping.loader.xml_files_loader') - ->setArgument(0, $this->getValidatorXmlMappingFiles($container)) + ->replaceArgument(0, $this->getValidatorXmlMappingFiles($container)) ; $container ->getDefinition('validator.mapping.loader.yaml_files_loader') - ->setArgument(0, $this->getValidatorYamlMappingFiles($container)) + ->replaceArgument(0, $this->getValidatorYamlMappingFiles($container)) ; if (isset($config['annotations'])) { @@ -480,7 +491,7 @@ class FrameworkExtension extends Extension // Register annotation loader $container ->getDefinition('validator.mapping.loader.annotation_loader') - ->setArgument(0, $namespaces) + ->replaceArgument(0, $namespaces) ; $loaderChain = $container->getDefinition('validator.mapping.loader.loader_chain'); @@ -488,6 +499,15 @@ class FrameworkExtension extends Extension array_unshift($arguments[0], new Reference('validator.mapping.loader.annotation_loader')); $loaderChain->setArguments($arguments); } + + if (isset($config['cache'])) { + $container->getDefinition('validator.mapping.class_metadata_factory') + ->replaceArgument(1, new Reference('validator.mapping.cache.'.$config['cache'])); + $container->setParameter( + 'validator.mapping.cache.prefix', + 'validator_'.md5($container->getParameter('kernel.root_dir')) + ); + } } private function getValidatorXmlMappingFiles(ContainerBuilder $container) @@ -513,7 +533,7 @@ class FrameworkExtension extends Extension foreach ($container->getParameter('kernel.bundles') as $bundle) { $reflection = new \ReflectionClass($bundle); if (file_exists($file = dirname($reflection->getFilename()).'/Resources/config/validation.yml')) { - $yamlMappingFiles[] = realpath($file); + $files[] = realpath($file); $container->addResource(new FileResource($file)); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php index 9dae9332ec..dedd53aed9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php +++ b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php @@ -22,6 +22,7 @@ use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddClassesToAuto use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslatorPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddCacheWarmerPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ContainerBuilderDebugDumpPass; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CompilerDebugDumpPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\PassConfig; use Symfony\Component\DependencyInjection\Scope; @@ -81,6 +82,10 @@ class FrameworkBundle extends Bundle $container->addCompilerPass(new AddClassesToAutoloadMapPass()); $container->addCompilerPass(new TranslatorPass()); $container->addCompilerPass(new AddCacheWarmerPass()); - $container->addCompilerPass(new ContainerBuilderDebugDumpPass(), PassConfig::TYPE_BEFORE_REMOVING); + + if ($container->getParameter('kernel.debug')) { + $container->addCompilerPass(new ContainerBuilderDebugDumpPass(), PassConfig::TYPE_BEFORE_REMOVING); + $container->addCompilerPass(new CompilerDebugDumpPass(), PassConfig::TYPE_AFTER_REMOVING); + } } } diff --git a/src/Symfony/Bundle/FrameworkBundle/HttpFoundation/SessionListener.php b/src/Symfony/Bundle/FrameworkBundle/HttpFoundation/SessionListener.php deleted file mode 100644 index 58a5356c6f..0000000000 --- a/src/Symfony/Bundle/FrameworkBundle/HttpFoundation/SessionListener.php +++ /dev/null @@ -1,44 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\FrameworkBundle\HttpFoundation; - -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\HttpKernelInterface; -use Symfony\Component\HttpKernel\Event\FilterResponseEvent; - -/** - * SessionListener. - * - * Saves session in test environment. - * - * @author Bulat Shakirzyanov - */ -class SessionListener -{ - /** - * Checks if session was initialized and saves if current request is master - * Runs on 'onCoreResponse' in test environment - * - * @param FilterResponseEvent $event - */ - public function onCoreResponse(FilterResponseEvent $event) - { - if ($request = $event->getRequest()) { - if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) { - if ($session = $request->getSession()) { - $session->save(); - } - } - } - } -} diff --git a/src/Symfony/Bundle/FrameworkBundle/HttpKernel.php b/src/Symfony/Bundle/FrameworkBundle/HttpKernel.php index 9e9dc4b7a9..dcde0d34df 100644 --- a/src/Symfony/Bundle/FrameworkBundle/HttpKernel.php +++ b/src/Symfony/Bundle/FrameworkBundle/HttpKernel.php @@ -47,7 +47,7 @@ class HttpKernel extends BaseHttpKernel /** * Forwards the request to another controller. * - * @param string $controller The controller name (a string like Blog:Post:index) + * @param string $controller The controller name (a string like BlogBundle:Post:index) * @param array $attributes An array of request attributes * @param array $query An array of request query parameters * @@ -76,7 +76,7 @@ class HttpKernel extends BaseHttpKernel * * standalone: whether to generate an esi:include tag or not when ESI is supported * * comment: a comment to add when returning an esi:include tag * - * @param string $controller A controller name to execute (a string like Blog:Post:index), or a relative URI + * @param string $controller A controller name to execute (a string like BlogBundle:Post:index), or a relative URI * @param array $options An array of options * * @return string The Response content @@ -153,7 +153,7 @@ class HttpKernel extends BaseHttpKernel * * This method uses the "_internal" route, which should be available. * - * @param string $controller A controller name to execute (a string like Blog:Post:index), or a relative URI + * @param string $controller A controller name to execute (a string like BlogBundle:Post:index), or a relative URI * @param array $attributes An array of request attributes * @param array $query An array of request query parameters * @@ -169,7 +169,7 @@ class HttpKernel extends BaseHttpKernel 'controller' => $controller, 'path' => $attributes ? http_build_query($attributes) : 'none', '_format' => $this->container->get('request')->getRequestFormat(), - ), true); + )); if ($query) { $uri = $uri.'?'.http_build_query($query); diff --git a/src/Symfony/Bundle/FrameworkBundle/Profiler/ProfilerListener.php b/src/Symfony/Bundle/FrameworkBundle/Profiler/ProfilerListener.php index fcb97a25bd..f3f0524002 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Profiler/ProfilerListener.php +++ b/src/Symfony/Bundle/FrameworkBundle/Profiler/ProfilerListener.php @@ -27,9 +27,10 @@ use Symfony\Component\DependencyInjection\ContainerInterface; class ProfilerListener { protected $container; - protected $exception; - protected $onlyException; protected $matcher; + protected $onlyException; + protected $onlyMasterRequests; + protected $exception; /** * Constructor. @@ -37,12 +38,14 @@ class ProfilerListener * @param ContainerInterface $container A ContainerInterface instance * @param RequestMatcherInterface $matcher A RequestMatcher instance * @param Boolean $onlyException true if the profiler only collects data when an exception occurs, false otherwise + * @param Boolean $onlyMaster true if the profiler only collects data when the request is a master request, false otherwise */ - public function __construct(ContainerInterface $container, RequestMatcherInterface $matcher = null, $onlyException = false) + public function __construct(ContainerInterface $container, RequestMatcherInterface $matcher = null, $onlyException = false, $onlyMasterRequests = false) { $this->container = $container; $this->matcher = $matcher; - $this->onlyException = $onlyException; + $this->onlyException = (Boolean) $onlyException; + $this->onlyMasterRequests = (Boolean) $onlyMasterRequests; } /** @@ -81,6 +84,10 @@ class ProfilerListener { $response = $event->getResponse(); + if ($this->onlyMasterRequests && HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) { + return $response; + } + if (null !== $this->matcher && !$this->matcher->matches($event->getRequest())) { return $response; } diff --git a/src/Symfony/Bundle/FrameworkBundle/RequestListener.php b/src/Symfony/Bundle/FrameworkBundle/RequestListener.php index 5a5c81721d..ac68a2e57c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/RequestListener.php +++ b/src/Symfony/Bundle/FrameworkBundle/RequestListener.php @@ -21,6 +21,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Routing\Matcher\Exception\MethodNotAllowedException; use Symfony\Component\Routing\Matcher\Exception\NotFoundException; use Symfony\Component\Routing\RouterInterface; +use Symfony\Component\Routing\RequestContext; /** * RequestListener. @@ -29,14 +30,18 @@ use Symfony\Component\Routing\RouterInterface; */ class RequestListener { - protected $router; - protected $logger; - protected $container; + private $router; + private $logger; + private $container; + private $httpPort; + private $httpsPort; - public function __construct(ContainerInterface $container, RouterInterface $router, LoggerInterface $logger = null) + public function __construct(ContainerInterface $container, RouterInterface $router, $httpPort = 80, $httpsPort = 443, LoggerInterface $logger = null) { $this->container = $container; $this->router = $router; + $this->httpPort = $httpPort; + $this->httpsPort = $httpsPort; $this->logger = $logger; } @@ -72,13 +77,20 @@ class RequestListener if ($master) { // set the context even if the parsing does not need to be done // to have correct link generation - $this->router->setContext(array( - 'base_url' => $request->getBaseUrl(), - 'method' => $request->getMethod(), - 'host' => $request->getHost(), - 'port' => $request->getPort(), - 'is_secure' => $request->isSecure(), - )); + $context = new RequestContext( + $request->getBaseUrl(), + $request->getMethod(), + $request->getHost(), + $request->getScheme(), + $this->httpPort, + $this->httpsPort + ); + + if ($session = $request->getSession()) { + $context->setParameter('_locale', $session->getLocale()); + } + + $this->router->setContext($context); } if ($request->attributes->has('_controller')) { @@ -91,14 +103,10 @@ class RequestListener $parameters = $this->router->match($request->getPathInfo()); if (null !== $this->logger) { - $this->logger->info(sprintf('Matched route "%s" (parameters: %s)', $parameters['_route'], json_encode($parameters))); + $this->logger->info(sprintf('Matched route "%s" (parameters: %s)', $parameters['_route'], $this->parametersToString($parameters))); } $request->attributes->add($parameters); - - if ($locale = $request->attributes->get('_locale')) { - $request->getSession()->setLocale($locale); - } } catch (NotFoundException $e) { $message = sprintf('No route found for "%s %s"', $request->getMethod(), $request->getPathInfo()); if (null !== $this->logger) { @@ -112,5 +120,20 @@ class RequestListener } throw new MethodNotAllowedHttpException($e->getAllowedMethods(), $message, $e); } + + if ($master && $locale = $request->attributes->get('_locale')) { + $request->getSession()->setLocale($locale); + $context->setParameter('_locale', $locale); + } + } + + private function parametersToString(array $parameters) + { + $pieces = array(); + foreach ($parameters as $key => $val) { + $pieces[] = sprintf('"%s": "%s"', $key, (is_string($val) ? $val : json_encode($val))); + } + + return implode(', ', $pieces); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/collectors.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/collectors.xml index e2bbd15e63..d68b99cdc5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/collectors.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/collectors.xml @@ -16,38 +16,39 @@ - + - + - + - + - + + - + - + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug.xml index c1fefe3eaa..ec149eea85 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug.xml @@ -10,6 +10,7 @@ + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/profiling.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/profiling.xml index 0659d3b023..9dcaaa401d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/profiling.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/profiling.xml @@ -11,6 +11,7 @@ + @@ -29,6 +30,7 @@ +
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml index 6467e7b575..81eec8edc0 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml @@ -8,7 +8,6 @@ Symfony\Component\Routing\Router Symfony\Bundle\FrameworkBundle\Routing\CachedRouter Symfony\Bundle\FrameworkBundle\Routing\DelegatingLoader - Symfony\Component\HttpKernel\Config\FileLocator Symfony\Component\Config\Loader\LoaderResolver Symfony\Component\Routing\Loader\XmlFileLoader Symfony\Component\Routing\Loader\YamlFileLoader @@ -16,8 +15,8 @@ Symfony\Component\Routing\Generator\UrlGenerator Symfony\Component\Routing\Generator\UrlGenerator Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper - Symfony\Component\Routing\Matcher\UrlMatcher - Symfony\Component\Routing\Matcher\UrlMatcher + Symfony\Bundle\FrameworkBundle\Routing\RedirectableUrlMatcher + Symfony\Bundle\FrameworkBundle\Routing\RedirectableUrlMatcher Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper Symfony\Bundle\FrameworkBundle\CacheWarmer\RouterCacheWarmer %kernel.name%%kernel.environment%UrlMatcher @@ -28,26 +27,23 @@ - - - - - + - + - + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing/internal.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing/internal.xml index faa3e77c23..3a13fed14a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing/internal.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing/internal.xml @@ -5,6 +5,6 @@ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd"> - Framework:Internal:index + FrameworkBundle:Internal:index diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd index 09e5607469..326a4f4a87 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd @@ -54,6 +54,7 @@ + @@ -93,7 +94,7 @@ - + @@ -103,10 +104,6 @@ - - - - @@ -127,11 +124,15 @@ + - - + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml index a4b521193f..32c456d00a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml @@ -47,10 +47,22 @@ --> + + + + + %kernel.root_dir%/Resources + + + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/session.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/session.xml index c8e81c57c3..2f855a6e0f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/session.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/session.xml @@ -10,8 +10,8 @@ Symfony\Component\HttpFoundation\SessionStorage\PdoSessionStorage - Symfony\Component\HttpFoundation\SessionStorage\ArraySessionStorage - + Symfony\Component\HttpFoundation\SessionStorage\FilesystemSessionStorage + @@ -29,8 +29,9 @@ %session.storage.pdo.options%
- - %session.storage.array.options% + + %kernel.cache_dir%/sessions + %session.storage.filesystem.options% diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating.xml index 469db64679..35de718ee1 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating.xml @@ -25,20 +25,19 @@ - + - %kernel.root_dir%/Resources %kernel.cache_dir% - %kernel.root_dir%/Resources + %kernel.root_dir%/Resources @@ -48,7 +47,7 @@ - %templating.loader.cache.path% + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_debug.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_debug.xml index f4ff8d6859..0d3cebebea 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_debug.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_debug.xml @@ -10,6 +10,7 @@ + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_php.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_php.xml index 409dfcaeb5..0107bd9d22 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_php.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_php.xml @@ -62,7 +62,7 @@ - %debug.file_link_format% + %kernel.root_dir% diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/test.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/test.xml index 757ad7faee..f0d0ddd3b7 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/test.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/test.xml @@ -9,7 +9,7 @@ Symfony\Component\BrowserKit\History Symfony\Component\BrowserKit\CookieJar - Symfony\Bundle\FrameworkBundle\HttpFoundation\SessionListener + Symfony\Bundle\FrameworkBundle\Test\SessionListener @@ -25,6 +25,8 @@ + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/validator.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/validator.xml index f857904cd2..8a671bc458 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/validator.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/validator.xml @@ -7,6 +7,8 @@ Symfony\Component\Validator\Validator Symfony\Component\Validator\Mapping\ClassMetadataFactory + Symfony\Component\Validator\Mapping\Cache\ApcCache + Symfony\Component\Validator\Mapping\Loader\LoaderChain Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader Symfony\Component\Validator\Mapping\Loader\AnnotationLoader @@ -23,6 +25,11 @@ + + + %validator.mapping.cache.prefix% diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml index 77888c5f50..9fae044bd5 100755 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml @@ -14,11 +14,13 @@ + + @@ -26,8 +28,11 @@ + + + @@ -38,6 +43,7 @@ + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/public/css/exception_layout.css b/src/Symfony/Bundle/FrameworkBundle/Resources/public/css/exception_layout.css index 3ad777fd5e..571815baaf 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/public/css/exception_layout.css +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/public/css/exception_layout.css @@ -71,11 +71,6 @@ img padding-top:20px; } -.search button -{ - float:none; -} - .search label { line-height:28px; @@ -98,10 +93,10 @@ img -webkit-appearance: textfield; } -button +.search button { -webkit-appearance: button-bevel; - float: left; + float: none; text-align: left; padding: 0; margin: 0; @@ -117,24 +112,24 @@ button background: none; } -button:-moz-focus-inner +.search button:-moz-focus-inner { padding: 0; border: none; } -button:hover +.search button:hover { text-decoration: none; } -button span span, -button span span span +.search button span span, +.search button span span span { position: static; } -button span +.search button span { position: relative; text-decoration: none; @@ -145,13 +140,13 @@ button span background: transparent url(../images/border_l.png) no-repeat top left; } -button span span +.search button span span { padding: 0 8px 0 0; background: transparent url(../images/border_r.png) right top no-repeat; } -button span span span +.search button span span span { padding: 0px 7px; font: bold 11px Arial, Helvetica, sans-serif; diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/skeleton/bundle/generic/Controller/DefaultController.php b/src/Symfony/Bundle/FrameworkBundle/Resources/skeleton/bundle/generic/Controller/DefaultController.php index 7c8e145aa9..609aebeef9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/skeleton/bundle/generic/Controller/DefaultController.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/skeleton/bundle/generic/Controller/DefaultController.php @@ -8,6 +8,6 @@ class DefaultController extends Controller { public function indexAction() { - return $this->render('{{ bundleShort }}:Default:index.html.twig'); + return $this->render('{{ bundle }}:Default:index.html.twig'); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/skeleton/bundle/php/Resources/config/routing.php b/src/Symfony/Bundle/FrameworkBundle/Resources/skeleton/bundle/php/Resources/config/routing.php index 51d7d3fdea..c57b0546c3 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/skeleton/bundle/php/Resources/config/routing.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/skeleton/bundle/php/Resources/config/routing.php @@ -6,7 +6,7 @@ use Symfony\Component\Routing\Route; $collection = new RouteCollection(); /* $collection->add('homepage', new Route('/', array( - '_controller' => '{{ bundleShort }}:Default:index', + '_controller' => '{{ bundle }}:Default:index', ))); */ return $collection; diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/skeleton/bundle/xml/Resources/config/routing.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/skeleton/bundle/xml/Resources/config/routing.xml index c54205b34e..0e1d57fd51 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/skeleton/bundle/xml/Resources/config/routing.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/skeleton/bundle/xml/Resources/config/routing.xml @@ -6,7 +6,7 @@ diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/skeleton/bundle/yml/Resources/config/routing.yml b/src/Symfony/Bundle/FrameworkBundle/Resources/skeleton/bundle/yml/Resources/config/routing.yml index 6b0e450814..64d3d6db9f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/skeleton/bundle/yml/Resources/config/routing.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/skeleton/bundle/yml/Resources/config/routing.yml @@ -1,3 +1,3 @@ #homepage: # pattern: / -# defaults: { _controller: {{ bundleShort }}:Default:index } +# defaults: { _controller: {{ bundle }}:Default:index } diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/translations/validators.fr.xliff b/src/Symfony/Bundle/FrameworkBundle/Resources/translations/validators.fr.xliff index 6a32e7a6d1..de854edfe5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/translations/validators.fr.xliff +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/translations/validators.fr.xliff @@ -119,8 +119,8 @@ Le fichier envoyé est trop gros. Merci d'essayer d'envoyer un fichier plus petit - The CSRF token is invalid - Le jeton CSRF est invalide + The CSRF token is invalid. Please try to resubmit the form + Le jeton CSRF est invalide. Veuillez renvoyer le formulaire The two values should be equal diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/error.atom.twig b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/error.atom.twig index ba26ba6588..3310e87cdc 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/error.atom.twig +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/error.atom.twig @@ -1 +1 @@ -{% include 'Framework:Exception:error.xml.twig' with { 'exception': exception } %} +{% include 'FrameworkBundle:Exception:error.xml.twig' with { 'exception': exception } %} diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/error.rdf.twig b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/error.rdf.twig index ba26ba6588..3310e87cdc 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/error.rdf.twig +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/error.rdf.twig @@ -1 +1 @@ -{% include 'Framework:Exception:error.xml.twig' with { 'exception': exception } %} +{% include 'FrameworkBundle:Exception:error.xml.twig' with { 'exception': exception } %} diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.atom.twig b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.atom.twig index 312c433cb8..e321807747 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.atom.twig +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.atom.twig @@ -1 +1 @@ -{% include 'Framework:Exception:exception.xml.twig' with { 'exception': exception } %} +{% include 'FrameworkBundle:Exception:exception.xml.twig' with { 'exception': exception } %} diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.css.twig b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.css.twig index 9a527cb521..e96cdc36a2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.css.twig +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.css.twig @@ -1,3 +1,3 @@ /* -{% include 'Framework:Exception:exception.txt.twig' with { 'exception': exception } %} +{% include 'FrameworkBundle:Exception:exception.txt.twig' with { 'exception': exception } %} */ diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.html.twig b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.html.twig index 4a8ff54eb8..79e4c0c4a2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.html.twig +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.html.twig @@ -41,7 +41,7 @@ {% for position, e in exception.toarray %} - {% include 'Framework:Exception:traces.html.twig' with { 'exception': e, 'position': position, 'count': previous_count } only %} + {% include 'FrameworkBundle:Exception:traces.html.twig' with { 'exception': e, 'position': position, 'count': previous_count } only %} {% endfor %} {% if logger %} @@ -68,7 +68,7 @@
- {% include 'Framework:Exception:logs.html.twig' with { 'logs': logger.logs } only %} + {% include 'FrameworkBundle:Exception:logs.html.twig' with { 'logs': logger.logs } only %}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.js.twig b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.js.twig index 9a527cb521..e96cdc36a2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.js.twig +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.js.twig @@ -1,3 +1,3 @@ /* -{% include 'Framework:Exception:exception.txt.twig' with { 'exception': exception } %} +{% include 'FrameworkBundle:Exception:exception.txt.twig' with { 'exception': exception } %} */ diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.rdf.twig b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.rdf.twig index 312c433cb8..e321807747 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.rdf.twig +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.rdf.twig @@ -1 +1 @@ -{% include 'Framework:Exception:exception.xml.twig' with { 'exception': exception } %} +{% include 'FrameworkBundle:Exception:exception.xml.twig' with { 'exception': exception } %} diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.txt.twig b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.txt.twig index 4ff675ec6e..dacecebd3a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.txt.twig +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.txt.twig @@ -2,6 +2,6 @@ [message] {{ exception.message }} {% for i, e in exception.toarray %} [{{ i + 1 }}] {{ e.class }}: {{ e.message }} -{% include 'Framework:Exception:traces.txt.twig' with { 'exception': e } only %} +{% include 'FrameworkBundle:Exception:traces.txt.twig' with { 'exception': e } only %} {% endfor %} diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.xml.twig b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.xml.twig index 777388d722..1051664e0d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.xml.twig +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception.xml.twig @@ -3,7 +3,7 @@ {% for e in exception.toarray %} -{% include 'Framework:Exception:traces.xml.twig' with { 'exception': e } only %} +{% include 'FrameworkBundle:Exception:traces.xml.twig' with { 'exception': e } only %} {% endfor %} diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception_full.html.twig b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception_full.html.twig index 7a77d6d7af..0098e6268a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception_full.html.twig +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/exception_full.html.twig @@ -1,5 +1,9 @@ -{% extends 'Framework:Exception:layout.html.twig' %} +{% extends 'FrameworkBundle::layout.html.twig' %} + +{% block title %} + {{ exception.message }} ({{ status_code }} {{ status_text }}) +{% endblock %} {% block body %} - {% include 'Framework:Exception:exception.html.twig' %} + {% include 'FrameworkBundle:Exception:exception.html.twig' %} {% endblock %} diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/traces.html.twig b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/traces.html.twig index cc8ebcac7a..24aa0543bf 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/traces.html.twig +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/traces.html.twig @@ -18,7 +18,7 @@
    {% for i, trace in exception.trace %}
  1. - {% include 'Framework:Exception:trace.html.twig' with { 'prefix': position, 'i': i, 'trace': trace } only %} + {% include 'FrameworkBundle:Exception:trace.html.twig' with { 'prefix': position, 'i': i, 'trace': trace } only %}
  2. {% endfor %}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/traces.txt.twig b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/traces.txt.twig index 84e6b0cd8b..39180cb012 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/traces.txt.twig +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/traces.txt.twig @@ -1,6 +1,6 @@ {% if exception.trace|length %} {% for trace in exception.trace %} -{% include 'Framework:Exception:trace.txt.twig' with { 'trace': trace } only %} +{% include 'FrameworkBundle:Exception:trace.txt.twig' with { 'trace': trace } only %} {% endfor %} {% endif %} diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/traces.xml.twig b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/traces.xml.twig index 257ce5b763..de08cc61e5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/traces.xml.twig +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/traces.xml.twig @@ -1,7 +1,7 @@ {% for trace in exception.trace %} -{% include 'Framework:Exception:trace.txt.twig' with { 'trace': trace } only %} +{% include 'FrameworkBundle:Exception:trace.txt.twig' with { 'trace': trace } only %} {% endfor %} diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/money_field.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/money_field.html.php index 412b9215fc..df05f6fe2f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/money_field.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/money_field.html.php @@ -1,4 +1,4 @@ render($field, array(), array(), 'Framework:Form:number_field.html.php'), + $view['form']->render($field, array(), array(), 'FrameworkBundle:Form:number_field.html.php'), $field->getPattern() ) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_field.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_field.html.php index df75eef730..4fb2b09dea 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_field.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_field.html.php @@ -1 +1 @@ -render($field, array(), array(), 'Framework:Form:number_field.html.php') ?> % +render($field, array(), array(), 'FrameworkBundle:Form:number_field.html.php') ?> % diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/layout.html.twig b/src/Symfony/Bundle/FrameworkBundle/Resources/views/layout.html.twig similarity index 94% rename from src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/layout.html.twig rename to src/Symfony/Bundle/FrameworkBundle/Resources/views/layout.html.twig index 6f70a34a74..dc1d4e1ada 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Exception/layout.html.twig +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/layout.html.twig @@ -2,8 +2,7 @@ - {{ exception.message }} ({{ status_code }} {{ status_text }}) - + {% block title '' %} @@ -37,7 +36,6 @@ {% block body '' %} - diff --git a/src/Symfony/Bundle/FrameworkBundle/Routing/RedirectableUrlMatcher.php b/src/Symfony/Bundle/FrameworkBundle/Routing/RedirectableUrlMatcher.php new file mode 100644 index 0000000000..c08badac42 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Routing/RedirectableUrlMatcher.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Routing; + +use Symfony\Component\Routing\Matcher\UrlMatcher; +use Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface; + +/** + * @author Fabien Potencier + */ +class RedirectableUrlMatcher extends UrlMatcher implements RedirectableUrlMatcherInterface +{ + /** + * Redirects the user to another URL. + * + * @param string $path The path info to redirect to. + * @param string $route The route that matched + * @param string $scheme The URL scheme (null to keep the current one) + * + * @return array An array of parameters + */ + public function redirect($path, $route, $scheme = null) + { + return array( + '_controller' => 'Symfony\\Bundle\\FrameworkBundle\\Controller\\RedirectController::urlRedirectAction', + 'path' => $path, + 'permanent' => true, + 'scheme' => $scheme, + 'httpPort' => $this->context->getHttpPort(), + 'httpsPort' => $this->context->getHttpsPort(), + '_route' => $route, + ); + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/DelegatingEngine.php b/src/Symfony/Bundle/FrameworkBundle/Templating/DelegatingEngine.php index feb0d4c236..2df2e4878f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Templating/DelegatingEngine.php +++ b/src/Symfony/Bundle/FrameworkBundle/Templating/DelegatingEngine.php @@ -69,7 +69,7 @@ class DelegatingEngine extends BaseDelegatingEngine implements EngineInterface } } - throw new \RuntimeException(sprintf('No engine is able to work with the %s template.', json_encode($name))); + throw new \RuntimeException(sprintf('No engine is able to work with the template "%s".', $name)); } /** diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/ActionsHelper.php b/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/ActionsHelper.php index 84e9a17251..d10ef85e1e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/ActionsHelper.php +++ b/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/ActionsHelper.php @@ -36,7 +36,7 @@ class ActionsHelper extends Helper /** * Returns the Response content for a given controller or URI. * - * @param string $controller A controller name to execute (a string like Blog:Post:index), or a relative URI + * @param string $controller A controller name to execute (a string like BlogBundle:Post:index), or a relative URI * @param array $attributes An array of request attributes * @param array $options An array of options * @@ -46,10 +46,6 @@ class ActionsHelper extends Helper { $options['attributes'] = $attributes; - if (isset($options['query'])) { - $options['query'] = $options['query']; - } - return $this->kernel->render($controller, $options); } diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/CodeHelper.php b/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/CodeHelper.php index a5c68730a0..e8537bcf0a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/CodeHelper.php +++ b/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/CodeHelper.php @@ -31,7 +31,7 @@ class CodeHelper extends Helper */ public function __construct($fileLinkFormat, $rootDir) { - $this->fileLinkFormat = null !== $fileLinkFormat ? $fileLinkFormat : ini_get('xdebug.file_link_format'); + $this->fileLinkFormat = empty($fileLinkFormat) ? ini_get('xdebug.file_link_format') : $fileLinkFormat; $this->rootDir = str_replace('\\', '/', $rootDir).'/'; } @@ -169,7 +169,7 @@ class CodeHelper extends Helper $fileStr = sprintf('kernel.root_dir/%s', $this->rootDir, $fileStr); } - $text = "$fileStr line $line"; + $text = "$fileStr at line $line"; } if (false !== $link = $this->getFileLink($file, $line)) { @@ -189,15 +189,19 @@ class CodeHelper extends Helper */ public function getFileLink($file, $line) { - return $this->fileLinkFormat ? strtr($this->fileLinkFormat, array('%f' => $file, '%l' => $line)) : false; + if ($this->fileLinkFormat && file_exists($file)) { + return strtr($this->fileLinkFormat, array('%f' => $file, '%l' => $line)); + } + + return false; } public function formatFileFromText($text) { $that = $this; - return preg_replace_callback('/in (.*?)(?: on|at)? line (\d+)/', function ($match) use ($that) { - return 'in '.$that->formatFile($match[1], $match[2]); + return preg_replace_callback('/in (")?(.*?)\1(?: +(?:on|at))? +line (\d+)/', function ($match) use ($that) { + return 'in '.$that->formatFile($match[2], $match[3]); }, $text); } diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/FormHelper.php b/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/FormHelper.php index b996fd09e3..854f0efa8a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/FormHelper.php +++ b/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/FormHelper.php @@ -115,7 +115,7 @@ class FormHelper extends Helper public function row(/*FieldInterface*/ $field, $template = null) { if (null === $template) { - $template = 'Framework:Form:field_row.html.php'; + $template = 'FrameworkBundle:Form:field_row.html.php'; } return $this->engine->render($template, array( @@ -126,7 +126,7 @@ class FormHelper extends Helper public function label(/*FieldInterface */$field, $label = false, array $parameters = array(), $template = null) { if (null === $template) { - $template = 'Framework:Form:label.html.php'; + $template = 'FrameworkBundle:Form:label.html.php'; } return $this->engine->render($template, array( @@ -139,7 +139,7 @@ class FormHelper extends Helper public function errors(/*FieldInterface */$field, array $parameters = array(), $template = null) { if (null === $template) { - $template = 'Framework:Form:errors.html.php'; + $template = 'FrameworkBundle:Form:errors.html.php'; } return $this->engine->render($template, array( @@ -151,7 +151,7 @@ class FormHelper extends Helper public function hidden(/*FormInterface */$form, array $parameters = array(), $template = null) { if (null === $template) { - $template = 'Framework:Form:hidden.html.php'; + $template = 'FrameworkBundle:Form:hidden.html.php'; } return $this->engine->render($template, array( @@ -178,7 +178,7 @@ class FormHelper extends Helper $underscoredName = strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), array('\\1_\\2', '\\1_\\2'), strtr($className, '_', '.'))); - if ($this->engine->exists($guess = 'Framework:Form:'.$underscoredName.'.html.php')) { + if ($this->engine->exists($guess = 'FrameworkBundle:Form:'.$underscoredName.'.html.php')) { $template = $guess; } @@ -186,7 +186,7 @@ class FormHelper extends Helper } while (null === $template && false !== $currentFqClassName); if (null === $template && $field instanceof FormInterface) { - $template = 'Framework:Form:form.html.php'; + $template = 'FrameworkBundle:Form:form.html.php'; } self::$cache[$fqClassName] = $template; diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/Loader/CachedTemplateLocator.php b/src/Symfony/Bundle/FrameworkBundle/Templating/Loader/CachedTemplateLocator.php index d210dd66f8..49d8f6f51b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Templating/Loader/CachedTemplateLocator.php +++ b/src/Symfony/Bundle/FrameworkBundle/Templating/Loader/CachedTemplateLocator.php @@ -30,14 +30,15 @@ class CachedTemplateLocator extends TemplateLocator * @param FileLocatorInterface $locator A FileLocatorInterface instance * @param string $path A global fallback path */ - public function __construct($cacheDir, FileLocatorInterface $locator, $path) + public function __construct($cacheDir, FileLocatorInterface $locator) { if (!file_exists($cache = $cacheDir.'/templates.php')) { throw new \RuntimeException(sprintf('The template locator cache is not warmed up (%s).', $cache)); } $this->templates = require $cache; - parent::__construct($locator, $path); + + parent::__construct($locator); } /** @@ -49,16 +50,30 @@ class CachedTemplateLocator extends TemplateLocator * * @return string The full path for the file * + * @throws \InvalidArgumentException When the template is not an instance of TemplateReferenceInterface * @throws \InvalidArgumentException When file is not found */ public function locate($template, $currentPath = null, $first = true) { - $key = $template->getSignature(); - - if (!isset($this->templates[$key])) { - return parent::locate($template, $currentPath, $first); + if (!$template instanceof TemplateReferenceInterface) { + throw new \InvalidArgumentException("The template must be an instance of TemplateReferenceInterface."); } - return $this->templates[$key]; + $path = $this->getCachedTemplatePath($template); + + return $path === null ? parent::locate($template) : $path; + } + + /** + * Returns the template path from the cache + * + * @param TemplateReferenceInterface $template The template + * + * @return string|null The path when it is present in the cache, false otherwise + */ + protected function getCachedTemplatePath(TemplateReferenceInterface $template) + { + $key = $template->getSignature(); + return isset($this->templates[$key]) ? $this->templates[$key] : null; } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/Loader/TemplateLocator.php b/src/Symfony/Bundle/FrameworkBundle/Templating/Loader/TemplateLocator.php index 461f9db97f..eee7d246e2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Templating/Loader/TemplateLocator.php +++ b/src/Symfony/Bundle/FrameworkBundle/Templating/Loader/TemplateLocator.php @@ -29,12 +29,10 @@ class TemplateLocator implements FileLocatorInterface * Constructor. * * @param FileLocatorInterface $locator A FileLocatorInterface instance - * @param string $path A global fallback path */ - public function __construct(FileLocatorInterface $locator, $path) + public function __construct(FileLocatorInterface $locator) { $this->locator = $locator; - $this->path = $path; $this->cache = array(); } @@ -47,10 +45,15 @@ class TemplateLocator implements FileLocatorInterface * * @return string The full path for the file * - * @throws \InvalidArgumentException When file is not found + * @throws \InvalidArgumentException When the template is not an instance of TemplateReferenceInterface + * @throws \InvalidArgumentException When the template file can not be found */ public function locate($template, $currentPath = null, $first = true) { + if (!$template instanceof TemplateReferenceInterface) { + throw new \InvalidArgumentException("The template must be an instance of TemplateReferenceInterface."); + } + $key = $template->getSignature(); if (isset($this->cache[$key])) { @@ -58,9 +61,9 @@ class TemplateLocator implements FileLocatorInterface } try { - return $this->cache[$key] = $this->locator->locate($template->getPath(), $this->path); + return $this->cache[$key] = $this->locator->locate($template->getPath(), $currentPath); } catch (\InvalidArgumentException $e) { - throw new \InvalidArgumentException(sprintf('Unable to find template "%s" in "%s".', json_encode($template), $this->path), 0, $e); + throw new \InvalidArgumentException(sprintf('Unable to find template "%s" in "%s".', $template, $this->path), 0, $e); } } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateNameParser.php b/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateNameParser.php index f7a6466b3c..9c6f48db24 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateNameParser.php +++ b/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateNameParser.php @@ -83,7 +83,7 @@ class TemplateNameParser extends BaseTemplateNameParser * Convert a filename to a template. * * @param string $file The filename - * + * * @return TemplateReferenceInterface A template */ public function parseFromFilename($file) diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateReference.php b/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateReference.php index fee48dea53..14e8537f10 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateReference.php +++ b/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateReference.php @@ -35,7 +35,7 @@ class TemplateReference extends BaseTemplateReference * Returns the path to the template * - as a path when the template is not part of a bundle * - as a resource when the template is part of a bundle - * + * * @return string A path to the template or a resource */ public function getPath() @@ -46,4 +46,15 @@ class TemplateReference extends BaseTemplateReference return empty($this->parameters['bundle']) ? 'views/'.$path : '@'.$this->get('bundle').'/Resources/views/'.$path; } + /** + * {@inheritdoc} + */ + public function getLogicalName() + { + $parts = sprintf('%s:%s:', $this->get('bundle'), $this->get('controller')); + $elements = sprintf('%s.%s.%s', $this->get('name'), $this->get('format'), $this->get('engine')); + + return $parts . $elements; + } + } diff --git a/src/Symfony/Bundle/FrameworkBundle/Test/SessionListener.php b/src/Symfony/Bundle/FrameworkBundle/Test/SessionListener.php new file mode 100644 index 0000000000..78287cfd41 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Test/SessionListener.php @@ -0,0 +1,76 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Test; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\Cookie; +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\Event\FilterResponseEvent; +use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * SessionListener. + * + * Saves session in test environment. + * + * @author Bulat Shakirzyanov + * @author Fabien Potencier + */ +class SessionListener +{ + protected $container; + + public function __construct(ContainerInterface $container) + { + $this->container = $container; + } + + public function onCoreRequest(GetResponseEvent $event) + { + if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) { + return; + } + + // bootstrap the session + if ($this->container->has('session')) { + $this->container->get('session'); + } + + $cookies = $event->getRequest()->cookies; + if ($cookies->has(session_name())) { + session_id($cookies->get(session_name())); + } + } + + /** + * Checks if session was initialized and saves if current request is master + * Runs on 'onCoreResponse' in test environment + * + * @param FilterResponseEvent $event + */ + public function onCoreResponse(FilterResponseEvent $event) + { + if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) { + return; + } + + if ($session = $event->getRequest()->getSession()) { + $session->save(); + + $params = session_get_cookie_params(); + + $event->getResponse()->headers->setCookie(new Cookie(session_name(), session_id(), time() + $params['lifetime'], $params['path'], $params['domain'], $params['secure'], $params['httponly'])); + } + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php b/src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php index 1f63b6e2f1..eba30b4d21 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php +++ b/src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php @@ -55,20 +55,20 @@ abstract class WebTestCase extends BaseWebTestCase */ protected function getPhpUnitXmlDir() { - $dir = getcwd(); + $dir = null; if (!isset($_SERVER['argv']) || false === strpos($_SERVER['argv'][0], 'phpunit')) { throw new \RuntimeException('You must override the WebTestCase::createKernel() method.'); } - // find the --configuration flag from PHPUnit - $cli = implode(' ', $_SERVER['argv']); - if (preg_match('/\-\-configuration[= ]+([^ ]+)/', $cli, $matches)) { - $dir = realpath($matches[1]); - } elseif (preg_match('/\-c +([^ ]+)/', $cli, $matches)) { - $dir = realpath($matches[1]); - } elseif (file_exists(getcwd().'/phpunit.xml') || file_exists(getcwd().'/phpunit.xml.dist')) { + $dir = $this->getPhpUnitCliConfigArgument(); + if ($dir === null && + (file_exists(getcwd().DIRECTORY_SEPARATOR.'phpunit.xml') || + file_exists(getcwd().DIRECTORY_SEPARATOR.'phpunit.xml.dist'))) { $dir = getcwd(); - } else { + } + + // Can't continue + if ($dir === null) { throw new \RuntimeException('Unable to guess the Kernel directory.'); } @@ -79,6 +79,32 @@ abstract class WebTestCase extends BaseWebTestCase return $dir; } + /** + * Finds the value of configuration flag from cli + * + * PHPUnit will use the last configuration argument on the command line, so this only returns + * the last configuration argument + * + * @return string The value of the phpunit cli configuration option + */ + private function getPhpUnitCliConfigArgument() + { + $dir = null; + $reversedArgs = array_reverse($_SERVER['argv']); + foreach ($reversedArgs as $argIndex=>$testArg) { + if ($testArg === '-c' || $testArg === '--configuration') { + $dir = realpath($reversedArgs[$argIndex - 1]); + break; + } elseif (strpos($testArg, '--configuration=') === 0) { + $argPath = substr($testArg, strlen('--configuration=')); + $dir = realpath($argPath); + break; + } + } + + return $dir; + } + /** * Attempts to guess the kernel location. * diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/ContainerAwareEventDispatcherTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/ContainerAwareEventDispatcherTest.php new file mode 100644 index 0000000000..ea06810311 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/ContainerAwareEventDispatcherTest.php @@ -0,0 +1,82 @@ +getMock('Symfony\Bundle\FrameworkBundle\Tests\Service'); + + $service + ->expects($this->once()) + ->method('onEvent') + ->with($event) + ; + + $container = new Container(); + $container->set('service.listener', $service); + + $dispatcher = new ContainerAwareEventDispatcher($container); + $dispatcher->addListenerService('onEvent', 'service.listener'); + + $dispatcher->dispatch('onEvent', $event); + } + + public function testPreventDuplicateListenerService() + { + $event = new Event(); + + $service = $this->getMock('Symfony\Bundle\FrameworkBundle\Tests\Service'); + + $service + ->expects($this->once()) + ->method('onEvent') + ->with($event) + ; + + $container = new Container(); + $container->set('service.listener', $service); + + $dispatcher = new ContainerAwareEventDispatcher($container); + $dispatcher->addListenerService('onEvent', 'service.listener', 5); + $dispatcher->addListenerService('onEvent', 'service.listener', 10); + + $dispatcher->dispatch('onEvent', $event); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testTriggerAListenerServiceOutOfScope() + { + $service = $this->getMock('Symfony\Bundle\FrameworkBundle\Tests\Service'); + + $scope = new Scope('scope'); + + $container = new Container(); + $container->addScope($scope); + $container->enterScope('scope'); + $container->set('service.listener', $service, 'scope'); + + $dispatcher = new ContainerAwareEventDispatcher($container); + $dispatcher->addListenerService('onEvent', 'service.listener'); + + $container->leaveScope('scope'); + $dispatcher->dispatch('onEvent'); + } +} + +class Service +{ + function onEvent(Event $e) + { + } +} \ No newline at end of file diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerNameParserTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerNameParserTest.php index c0c8524102..158848d2df 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerNameParserTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerNameParserTest.php @@ -13,22 +13,35 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\Controller; use Symfony\Bundle\FrameworkBundle\Tests\TestCase; use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser; -use Symfony\Bundle\FrameworkBundle\Tests\Logger; -use Symfony\Bundle\FrameworkBundle\Tests\Kernel; - -require_once __DIR__.'/../Kernel.php'; -require_once __DIR__.'/../Logger.php'; +use Symfony\Component\ClassLoader\UniversalClassLoader; class ControllerNameParserTest extends TestCase { + protected $loader; + + public function setUp() + { + $this->loader = new UniversalClassLoader(); + $this->loader->registerNamespaces(array( + 'TestBundle' => __DIR__.'/../Fixtures', + 'TestApplication' => __DIR__.'/../Fixtures', + )); + $this->loader->register(); + } + + public function tearDown() + { + spl_autoload_unregister(array($this->loader, 'loadClass')); + } + public function testParse() { $parser = $this->createParser(); - $this->assertEquals('TestBundle\FooBundle\Controller\DefaultController::indexAction', $parser->parse('Foo:Default:index'), '->parse() converts a short a:b:c notation string to a class::method string'); - $this->assertEquals('TestBundle\FooBundle\Controller\Sub\DefaultController::indexAction', $parser->parse('Foo:Sub\Default:index'), '->parse() converts a short a:b:c notation string to a class::method string'); - $this->assertEquals('TestBundle\Fabpot\FooBundle\Controller\DefaultController::indexAction', $parser->parse('SensioFoo:Default:index'), '->parse() converts a short a:b:c notation string to a class::method string'); - $this->assertEquals('TestBundle\Sensio\Cms\FooBundle\Controller\DefaultController::indexAction', $parser->parse('SensioCmsFoo:Default:index'), '->parse() converts a short a:b:c notation string to a class::method string'); + $this->assertEquals('TestBundle\FooBundle\Controller\DefaultController::indexAction', $parser->parse('FooBundle:Default:index'), '->parse() converts a short a:b:c notation string to a class::method string'); + $this->assertEquals('TestBundle\FooBundle\Controller\Sub\DefaultController::indexAction', $parser->parse('FooBundle:Sub\Default:index'), '->parse() converts a short a:b:c notation string to a class::method string'); + $this->assertEquals('TestBundle\Fabpot\FooBundle\Controller\DefaultController::indexAction', $parser->parse('SensioFooBundle:Default:index'), '->parse() converts a short a:b:c notation string to a class::method string'); + $this->assertEquals('TestBundle\Sensio\Cms\FooBundle\Controller\DefaultController::indexAction', $parser->parse('SensioCmsFooBundle:Default:index'), '->parse() converts a short a:b:c notation string to a class::method string'); try { $parser->parse('foo:'); @@ -56,17 +69,38 @@ class ControllerNameParserTest extends TestCase public function getMissingControllersTest() { return array( - array('Foo:Fake:index'), // a normal bundle - array('SensioFoo:Fake:index'), // a bundle with children + array('FooBundle:Fake:index'), // a normal bundle + array('SensioFooBundle:Fake:index'), // a bundle with children ); } private function createParser() { - $kernel = new Kernel(); - $kernel->boot(); - $logger = new Logger(); + $bundles = array( + 'SensioFooBundle' => array($this->getBundle('TestBundle\Fabpot\FooBundle', 'FabpotFooBundle'), $this->getBundle('TestBundle\Sensio\FooBundle', 'SensioFooBundle')), + 'SensioCmsFooBundle' => array($this->getBundle('TestBundle\Sensio\Cms\FooBundle', 'SensioCmsFooBundle')), + 'FooBundle' => array($this->getBundle('TestBundle\FooBundle', 'FooBundle')), + 'FabpotFooBundle' => array($this->getBundle('TestBundle\Fabpot\FooBundle', 'FabpotFooBundle'), $this->getBundle('TestBundle\Sensio\FooBundle', 'SensioFooBundle')), + ); - return new ControllerNameParser($kernel, $logger); + $kernel = $this->getMock('Symfony\Component\HttpKernel\KernelInterface'); + $kernel + ->expects($this->any()) + ->method('getBundle') + ->will($this->returnCallback(function ($bundle) use ($bundles) { + return $bundles[$bundle]; + })) + ; + + return new ControllerNameParser($kernel); + } + + private function getBundle($namespace, $name) + { + $bundle = $this->getMock('Symfony\Component\HttpKernel\Bundle\BundleInterface'); + $bundle->expects($this->any())->method('getName')->will($this->returnValue($name)); + $bundle->expects($this->any())->method('getNamespace')->will($this->returnValue($namespace)); + + return $bundle; } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/RedirectControllerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/RedirectControllerTest.php index 85e2c1ff37..04c39b0f62 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/RedirectControllerTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/RedirectControllerTest.php @@ -17,8 +17,6 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Bundle\FrameworkBundle\Controller\RedirectController; use Symfony\Bundle\FrameworkBundle\Tests\TestCase; use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser; -use Symfony\Bundle\FrameworkBundle\Tests\Logger; -use Symfony\Bundle\FrameworkBundle\Tests\Kernel; /** * @author Marcin Sikon diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Debug/TraceableEventDispactherTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Debug/TraceableEventDispactherTest.php new file mode 100644 index 0000000000..54f1872b8f --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Debug/TraceableEventDispactherTest.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Debug; + +use Symfony\Bundle\FrameworkBundle\Tests\TestCase; +use Symfony\Bundle\FrameworkBundle\Debug\TraceableEventDispatcher; + +class TraceableEventDispactherTest extends TestCase +{ + + /** + * @expectedException \RuntimeException + */ + public function testThrowsAnExceptionWhenAListenerMethodIsNotCallable() + { + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $dispatcher = new TraceableEventDispatcher($container); + $dispatcher->addListener('onFooEvent', new \stdClass()); + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/ProfilerPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/ProfilerPassTest.php index 566604c9ff..02cb33bcf5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/ProfilerPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/ProfilerPassTest.php @@ -22,7 +22,7 @@ class ProfilerPassTest extends \PHPUnit_Framework_TestCase * an exception (both are needed if the template is specified). Thus, * a fully-valid tag looks something like this: * - * + * */ public function testTemplateNoIdThrowsException() { diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/Bundles/XmlBundle/Resources/config/doctrine/metadata/mongodb/Fixtures.Bundles.XmlBundle.Document.Test.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/TestBundle/Resources/config/validation.xml similarity index 100% rename from src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/Bundles/XmlBundle/Resources/config/doctrine/metadata/mongodb/Fixtures.Bundles.XmlBundle.Document.Test.xml rename to src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/TestBundle/Resources/config/validation.xml diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/Bundles/YamlBundle/Resources/config/doctrine/metadata/mongodb/Fixtures.Bundles.YamlBundle.Document.Test.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/TestBundle/Resources/config/validation.yml similarity index 100% rename from src/Symfony/Bundle/DoctrineMongoDBBundle/Tests/DependencyInjection/Fixtures/Bundles/YamlBundle/Resources/config/doctrine/metadata/mongodb/Fixtures.Bundles.YamlBundle.Document.Test.yml rename to src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/TestBundle/Resources/config/validation.yml diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/TestBundle/TestBundle.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/TestBundle/TestBundle.php new file mode 100644 index 0000000000..ab6b62a8c1 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/TestBundle/TestBundle.php @@ -0,0 +1,8 @@ +loadFromExtension('framework', array( 'templating' => array( 'assets_version' => 'SomeVersionScheme', 'assets_base_urls' => 'http://cdn.example.com', + 'cache' => '/path/to/cache', 'cache_warmer' => true, 'engines' => array('php', 'twig'), 'loader' => array('loader.foo', 'loader.bar'), @@ -54,5 +55,6 @@ $container->loadFromExtension('framework', array( ), 'validation' => array( 'enabled' => true, + 'cache' => 'apc', ), )); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml index b03ce66b24..481dbfb58a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml @@ -2,33 +2,33 @@ - - - - - - - - loader.foo - loader.bar - - - http://cdn.example.com - - http://images1.example.com - http://images2.example.com - - - - http://bar1.example.com - http://bar2.example.com - - - - - + + + + + + + + loader.foo + loader.bar + php + twig + http://cdn.example.com + + http://images1.example.com + http://images2.example.com + + + + http://bar1.example.com + http://bar2.example.com + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/session_pdo.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/session_pdo.xml index f54fb261d3..cb088ee787 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/session_pdo.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/session_pdo.xml @@ -2,11 +2,11 @@ - - - + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_annotations.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_annotations.xml index 18e058aed6..8980e16a3b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_annotations.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_annotations.xml @@ -2,13 +2,13 @@ - - - - - + + + Application\Validator\Constraints\ + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml index b1d92ff195..187695e777 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml @@ -28,6 +28,7 @@ framework: cache_warmer: true engines: [php, twig] loader: [loader.foo, loader.bar] + cache: /path/to/cache packages: images: version: 1.0.0 @@ -41,3 +42,4 @@ framework: fallback: fr validation: enabled: true + cache: apc diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index d613720f9d..3bd27dfbec 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -113,7 +113,12 @@ abstract class FrameworkExtensionTest extends TestCase $this->assertEquals('templating.engine.delegating', (string) $container->getAlias('templating'), '->registerTemplatingConfiguration() configures delegating loader if multiple engines are provided'); - $this->assertEquals('templating.loader.chain', (string) $container->getAlias('templating.loader'), '->registerTemplatingConfiguration() configures loader chain if multiple loaders are provided'); + $this->assertEquals($container->getDefinition('templating.loader.chain'), $container->getDefinition('templating.loader.wrapped'), '->registerTemplatingConfiguration() configures loader chain if multiple loaders are provided'); + + $this->assertEquals($container->getDefinition('templating.loader'), $container->getDefinition('templating.loader.cache'), '->registerTemplatingConfiguration() configures the loader to use cache'); + + $arguments = $container->getDefinition('templating.loader.cache')->getArguments(); + $this->assertEquals('/path/to/cache', $arguments[1]); $this->assertEquals(array('php', 'twig'), $container->getParameter('templating.engines'), '->registerTemplatingConfiguration() sets a templating.engines parameter'); } @@ -174,22 +179,40 @@ abstract class FrameworkExtensionTest extends TestCase $this->assertEquals('Application\\Validator\\Constraints\\', $arguments[0]['app'], '->registerValidationConfiguration() loads custom validation namespaces'); } - protected function createContainer() + public function testValidationPaths() { - return new ContainerBuilder(new ParameterBag(array( - 'kernel.bundles' => array('Framework' => 'Symfony\\Bundle\\FrameworkBundle\\FrameworkBundle'), + require_once __DIR__ . "/Fixtures/TestBundle/TestBundle.php"; + + $container = $this->createContainerFromFile('validation_annotations', array( + 'kernel.bundles' => array('TestBundle' => 'Symfony\Bundle\FrameworkBundle\Tests\TestBundle'), + )); + + $yamlArgs = $container->getDefinition('validator.mapping.loader.yaml_files_loader')->getArguments(); + $this->assertEquals(1, count($yamlArgs[0])); + $this->assertStringEndsWith('TestBundle/Resources/config/validation.yml', $yamlArgs[0][0]); + + $xmlArgs = $container->getDefinition('validator.mapping.loader.xml_files_loader')->getArguments(); + $this->assertEquals(2, count($xmlArgs[0])); + $this->assertStringEndsWith('Component/Form/Resources/config/validation.xml', $xmlArgs[0][0]); + $this->assertStringEndsWith('TestBundle/Resources/config/validation.xml', $xmlArgs[0][1]); + } + + protected function createContainer(array $data = array()) + { + return new ContainerBuilder(new ParameterBag(array_merge(array( + 'kernel.bundles' => array('FrameworkBundle' => 'Symfony\\Bundle\\FrameworkBundle\\FrameworkBundle'), 'kernel.cache_dir' => __DIR__, 'kernel.compiled_classes' => array(), 'kernel.debug' => false, 'kernel.environment' => 'test', 'kernel.name' => 'kernel', 'kernel.root_dir' => __DIR__, - ))); + ), $data))); } - protected function createContainerFromFile($file) + protected function createContainerFromFile($file, $data = array()) { - $container = $this->createContainer(); + $container = $this->createContainer($data); $container->registerExtension(new FrameworkExtension()); $this->loadFromFile($container, $file); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Fabpot/FooBundle/FabpotFooBundle.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Fabpot/FooBundle/FabpotFooBundle.php index 39bb6e1013..141130c519 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Fabpot/FooBundle/FabpotFooBundle.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TestBundle/Fabpot/FooBundle/FabpotFooBundle.php @@ -25,6 +25,6 @@ class FabpotFooBundle extends Bundle */ public function getParent() { - return 'SensioFoo'; + return 'SensioFooBundle'; } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel.php deleted file mode 100644 index cbbf78226d..0000000000 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel.php +++ /dev/null @@ -1,65 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\FrameworkBundle\Tests; - -use Symfony\Component\HttpKernel\Kernel as BaseKernel; -use Symfony\Component\HttpKernel\Util\Filesystem; -use Symfony\Component\ClassLoader\UniversalClassLoader; -use Symfony\Component\Config\Loader\LoaderInterface; - -class Kernel extends BaseKernel -{ - public function __construct() - { - $this->rootDir = sys_get_temp_dir().'/sf2_'.rand(1, 9999); - if (!is_dir($this->rootDir)) { - if (false === @mkdir($this->rootDir)) { - exit(sprintf('Unable to create a temporary directory (%s)', $this->rootDir)); - } - } elseif (!is_writable($this->rootDir)) { - exit(sprintf('Unable to write in a temporary directory (%s)', $this->rootDir)); - } - - parent::__construct('env', true); - - $loader = new UniversalClassLoader(); - $loader->registerNamespaces(array( - 'TestBundle' => __DIR__.'/Fixtures/', - 'TestApplication' => __DIR__.'/Fixtures/', - )); - $loader->register(); - } - - public function __destruct() - { - $fs = new Filesystem(); - $fs->remove($this->rootDir); - } - - public function registerBundles() - { - return array( - new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(), - new \TestBundle\Sensio\FooBundle\SensioFooBundle(), - new \TestBundle\Sensio\Cms\FooBundle\SensioCmsFooBundle(), - new \TestBundle\FooBundle\FooBundle(), - new \TestBundle\Fabpot\FooBundle\FabpotFooBundle(), - ); - } - - public function registerContainerConfiguration(LoaderInterface $loader) - { - $loader->load(function ($container) { - $container->setParameter('kernel.compiled_classes', array()); - }); - } -} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Logger.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Logger.php deleted file mode 100644 index e975d61978..0000000000 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Logger.php +++ /dev/null @@ -1,88 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\FrameworkBundle\Tests; - -use Symfony\Component\HttpKernel\Log\LoggerInterface; - -class Logger implements LoggerInterface -{ - protected $logs; - - public function __construct() - { - $this->clear(); - } - - public function getLogs($priority = false) - { - return false === $priority ? $this->logs : $this->logs[$priority]; - } - - public function clear() - { - $this->logs = array( - 'emerg' => array(), - 'alert' => array(), - 'crit' => array(), - 'err' => array(), - 'warn' => array(), - 'notice' => array(), - 'info' => array(), - 'debug' => array(), - ); - } - - public function log($message, $priority) - { - $this->logs[$priority][] = $message; - } - - public function emerg($message) - { - $this->log($message, 'emerg'); - } - - public function alert($message) - { - $this->log($message, 'alert'); - } - - public function crit($message) - { - $this->log($message, 'crit'); - } - - public function err($message) - { - $this->log($message, 'err'); - } - - public function warn($message) - { - $this->log($message, 'warn'); - } - - public function notice($message) - { - $this->log($message, 'notice'); - } - - public function info($message) - { - $this->log($message, 'info'); - } - - public function debug($message) - { - $this->log($message, 'debug'); - } -} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Loader/CachedTemplateLocatorTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Loader/CachedTemplateLocatorTest.php new file mode 100644 index 0000000000..71d6d892c0 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Loader/CachedTemplateLocatorTest.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Templating\Loader; + +use Symfony\Bundle\FrameworkBundle\Templating\Loader\CachedTemplateLocator; +use Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateLocator; +use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference; +use Symfony\Bundle\FrameworkBundle\Tests\TestCase; + +class CachedTemplateLocatorTest extends TestCase +{ + public function testLocateACachedTemplate() + { + $template = new TemplateReference('bundle', 'controller', 'name', 'format', 'engine'); + + $locator = $this + ->getMockBuilder('Symfony\Bundle\FrameworkBundle\Templating\Loader\CachedTemplateLocator') + ->setMethods(array('getCachedTemplatePath')) + ->disableOriginalConstructor() + ->getMock() + ; + + $locator + ->expects($this->once()) + ->method('getCachedTemplatePath') + ->with($template) + ->will($this->returnValue('/cached/path/to/template')) + ; + + $this->assertEquals('/cached/path/to/template', $locator->locate($template)); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testThrowsAnExceptionWhenTemplateIsNotATemplateReferenceInterface() + { + $locator = $this + ->getMockBuilder('Symfony\Bundle\FrameworkBundle\Templating\Loader\CachedTemplateLocator') + ->setMethods(array('getCacheTemplatePath')) + ->disableOriginalConstructor() + ->getMock() + ; + + $locator->locate('template'); + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Loader/TemplateLocatorTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Loader/TemplateLocatorTest.php new file mode 100644 index 0000000000..daa164777a --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Loader/TemplateLocatorTest.php @@ -0,0 +1,76 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Templating\Loader; + +use Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateLocator; +use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference; +use Symfony\Bundle\FrameworkBundle\Tests\TestCase; + +class TemplateLocatorTest extends TestCase +{ + public function testLocateATemplate() + { + $template = new TemplateReference('bundle', 'controller', 'name', 'format', 'engine'); + + $fileLocator = $this->getFileLocator(); + + $fileLocator + ->expects($this->once()) + ->method('locate') + ->with($template->getPath()) + ->will($this->returnValue('/path/to/template')) + ; + + $locator = new TemplateLocator($fileLocator); + + $this->assertEquals('/path/to/template', $locator->locate($template)); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testThrowsExceptionWhenTemplateNotFound() + { + $template = new TemplateReference('bundle', 'controller', 'name', 'format', 'engine'); + + $fileLocator = $this->getFileLocator(); + + $fileLocator + ->expects($this->once()) + ->method('locate') + ->will($this->throwException(new \InvalidArgumentException())) + ; + + $locator = new TemplateLocator($fileLocator); + + $locator->locate($template); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testThrowsAnExceptionWhenTemplateIsNotATemplateReferenceInterface() + { + $locator = new TemplateLocator($this->getFileLocator()); + $locator->locate('template'); + } + + protected function getFileLocator() + { + return $this + ->getMockBuilder('Symfony\Component\Config\FileLocator') + ->setMethods(array('locate')) + ->setConstructorArgs(array('/path/to/fallback')) + ->getMock() + ; + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateNameParserTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateNameParserTest.php index 84185ffbc8..b5240021b5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateNameParserTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateNameParserTest.php @@ -12,7 +12,6 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\Templating; use Symfony\Bundle\FrameworkBundle\Tests\TestCase; -use Symfony\Bundle\FrameworkBundle\Tests\Kernel; use Symfony\Bundle\FrameworkBundle\Templating\TemplateNameParser; use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference; @@ -22,9 +21,18 @@ class TemplateNameParserTest extends TestCase protected function setUp() { - $kernel = new Kernel(); - $kernel->boot(); + $kernel = $this->getMock('Symfony\Component\HttpKernel\KernelInterface'); + $kernel + ->expects($this->any()) + ->method('getBundle') + ->will($this->returnCallback(function ($bundle) { + if (in_array($bundle, array('SensioFooBundle', 'SensioCmsFooBundle', 'FooBundle'))) { + return true; + } + throw new \InvalidArgumentException(); + })) + ; $this->parser = new TemplateNameParser($kernel); } @@ -41,16 +49,18 @@ class TemplateNameParserTest extends TestCase $template = $this->parser->parse($name); $this->assertEquals($template->getSignature(), $ref->getSignature()); + $this->assertEquals($template->getLogicalName(), $ref->getLogicalName()); + $this->assertEquals($template->getLogicalName(), $name); } public function getLogicalNameToTemplateProvider() { return array( - array('Foo:Post:index.html.php', new TemplateReference('Foo', 'Post', 'index', 'html', 'php')), - array('Foo:Post:index.html.twig', new TemplateReference('Foo', 'Post', 'index', 'html', 'twig')), - array('Foo:Post:index.xml.php', new TemplateReference('Foo', 'Post', 'index', 'xml', 'php')), - array('SensioFoo:Post:index.html.php', new TemplateReference('SensioFoo', 'Post', 'index', 'html', 'php')), - array('SensioCmsFoo:Post:index.html.php', new TemplateReference('SensioCmsFoo', 'Post', 'index', 'html', 'php')), + array('FooBundle:Post:index.html.php', new TemplateReference('FooBundle', 'Post', 'index', 'html', 'php')), + array('FooBundle:Post:index.html.twig', new TemplateReference('FooBundle', 'Post', 'index', 'html', 'twig')), + array('FooBundle:Post:index.xml.php', new TemplateReference('FooBundle', 'Post', 'index', 'xml', 'php')), + array('SensioFooBundle:Post:index.html.php', new TemplateReference('SensioFooBundle', 'Post', 'index', 'html', 'php')), + array('SensioCmsFooBundle:Post:index.html.php', new TemplateReference('SensioCmsFooBundle', 'Post', 'index', 'html', 'php')), array(':Post:index.html.php', new TemplateReference('', 'Post', 'index', 'html', 'php')), array('::index.html.php', new TemplateReference('', '', 'index', 'html', 'php')), ); @@ -68,11 +78,11 @@ class TemplateNameParserTest extends TestCase public function getInvalidLogicalNameProvider() { return array( - array('Bar:Post:index.html.php'), - array('Foo:Post:index'), + array('BarBundle:Post:index.html.php'), + array('FooBundle:Post:index'), array('FooBundle:Post'), - array('Foo:Post:foo:bar'), - array('Foo:Post:index.foo.bar.foobar'), + array('FooBundle:Post:foo:bar'), + array('FooBundle:Post:index.foo.bar.foobar'), ); } @@ -82,7 +92,7 @@ class TemplateNameParserTest extends TestCase public function testParseFromFilename($file, $ref) { $template = $this->parser->parseFromFilename($file); - + if ($ref === false) { $this->assertFalse($template); } else { diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateTest.php index abead162ed..c49010bfdc 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/TemplateTest.php @@ -12,7 +12,6 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\Templating; use Symfony\Bundle\FrameworkBundle\Tests\TestCase; -use Symfony\Bundle\FrameworkBundle\Tests\Kernel; use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference; class TemplateTest extends TestCase @@ -34,14 +33,14 @@ class TemplateTest extends TestCase { if (!$template->get('bundle')) { $this->assertEquals($template->getPath(), $path); - } + } } public function getTemplateToPathProvider() { return array( - array(new TemplateReference('Foo', 'Post', 'index', 'html', 'php'), '@Foo/Resources/views/Post/index.html.php'), - array(new TemplateReference('Foo', '', 'index', 'html', 'twig'), '@Foo/Resources/views/index.html.twig'), + array(new TemplateReference('FooBundle', 'Post', 'index', 'html', 'php'), '@FooBundle/Resources/views/Post/index.html.php'), + array(new TemplateReference('FooBundle', '', 'index', 'html', 'twig'), '@FooBundle/Resources/views/index.html.twig'), array(new TemplateReference('', 'Post', 'index', 'html', 'php'), 'views/Post/index.html.php'), array(new TemplateReference('', '', 'index', 'html', 'php'), 'views/index.html.php'), ); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/HttpFoundation/SessionListenerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Test/SessionListenerTest.php similarity index 89% rename from src/Symfony/Bundle/FrameworkBundle/Tests/HttpFoundation/SessionListenerTest.php rename to src/Symfony/Bundle/FrameworkBundle/Tests/Test/SessionListenerTest.php index b9d86cc827..6605926547 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/HttpFoundation/SessionListenerTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Test/SessionListenerTest.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Symfony\Bundle\FrameworkBundle\Tests\HttpFoundation; +namespace Symfony\Bundle\FrameworkBundle\Tests\Test; -use Symfony\Bundle\FrameworkBundle\HttpFoundation\SessionListener; +use Symfony\Bundle\FrameworkBundle\Test\SessionListener; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\HttpKernelInterface; @@ -31,7 +31,7 @@ class SessionListenerTest extends \PHPUnit_Framework_TestCase public function setUp() { - $this->listener = new SessionListener(); + $this->listener = new SessionListener($this->getMock('Symfony\Component\DependencyInjection\ContainerInterface')); $this->session = $this->getSession(); } diff --git a/src/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/DebugHandlerPass.php b/src/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/DebugHandlerPass.php new file mode 100644 index 0000000000..4c9dfd7e79 --- /dev/null +++ b/src/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/DebugHandlerPass.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\MonologBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Definition; +use Monolog\Logger; + +/** + * Adds the DebugHandler when the profiler is enabled. + * + * @author Christophe Coevoet + */ +class DebugHandlerPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('monolog.logger_prototype') || !$container->hasDefinition('profiler')) { + return; + } + + $debugHandler = new Definition('%monolog.handler.debug.class%', array(Logger::DEBUG, true)); + $container->setDefinition('monolog.handler.debug', $debugHandler); + $container->getDefinition('monolog.logger_prototype')->addMethodCall('pushHandler', array (new Reference('monolog.handler.debug'))); + } +} diff --git a/src/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/LoggerChannelPass.php b/src/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/LoggerChannelPass.php new file mode 100644 index 0000000000..f957467966 --- /dev/null +++ b/src/Symfony/Bundle/MonologBundle/DependencyInjection/Compiler/LoggerChannelPass.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\MonologBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\DefinitionDecorator; + +/** + * Replaces the default logger by another one with its own channel for tagged services. + * + * @author Christophe Coevoet + */ +class LoggerChannelPass implements CompilerPassInterface +{ + protected $channels = array(); + + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('monolog.logger')) { + return; + } + + foreach ($container->findTaggedServiceIds('monolog.logger') as $id => $tags) { + foreach ($tags as $tag) { + if (!empty($tag['channel']) && 'app' !== $tag['channel']) { + $definition = $container->getDefinition($id); + $loggerId = sprintf('monolog.logger.%s', $tag['channel']); + $this->createLogger($tag['channel'], $loggerId, $container); + foreach ($definition->getArguments() as $index => $argument) { + if ($argument instanceof Reference && 'logger' === (string) $argument) { + $definition->replaceArgument($index, new Reference($loggerId, $argument->getInvalidBehavior(), $argument->isStrict())); + } + } + } + } + } + } + + protected function createLogger($channel, $loggerId, ContainerBuilder $container) + { + if (!in_array($channel, $this->channels)) { + $logger = new DefinitionDecorator('monolog.logger_prototype'); + $logger->replaceArgument(0, $channel); + $container->setDefinition($loggerId, $logger); + array_push($this->channels, $channel); + } + } +} diff --git a/src/Symfony/Bundle/MonologBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/MonologBundle/DependencyInjection/Configuration.php new file mode 100644 index 0000000000..a6c76a77a2 --- /dev/null +++ b/src/Symfony/Bundle/MonologBundle/DependencyInjection/Configuration.php @@ -0,0 +1,104 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\MonologBundle\DependencyInjection; + +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; + +/** + * This class contains the configuration information for the bundle + * + * This information is solely responsible for how the different configuration + * sections are normalized, and merged. + * + * @author Jordi Boggiano + * @author Christophe Coevoet + */ +class Configuration implements ConfigurationInterface +{ + /** + * Generates the configuration tree builder. + * + * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder + */ + public function getConfigTreeBuilder() + { + $treeBuilder = new TreeBuilder(); + $rootNode = $treeBuilder->root('monolog'); + + $rootNode + ->fixXmlConfig('handler') + ->fixXmlConfig('processor') + ->children() + ->arrayNode('handlers') + ->canBeUnset() + ->useAttributeAsKey('name') + ->prototype('array') + ->canBeUnset() + ->children() + ->scalarNode('type') + ->isRequired() + ->treatNullLike('null') + ->beforeNormalization() + ->always() + ->then(function($v) { return strtolower($v); }) + ->end() + ->end() + ->scalarNode('id')->end() + ->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('handler')->end() // fingers_crossed and buffer + ->scalarNode('formatter')->end() + ->end() + ->append($this->getProcessorsNode()) + ->validate() + ->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 'service' === $v['type'] && !isset($v['id']); }) + ->thenInvalid('The id has to be specified to use a service as handler') + ->end() + ->end() + ->validate() + ->ifTrue(function($v) { return isset($v['debug']); }) + ->thenInvalid('The "debug" name cannot be used as it is reserved for the handler of the profiler') + ->end() + ->end() + ->end() + ->append($this->getProcessorsNode()) + ; + + return $treeBuilder; + } + + private function getProcessorsNode() + { + $treeBuilder = new TreeBuilder(); + $node = $treeBuilder->root('processors'); + + $node + ->canBeUnset() + ->performNoDeepMerging() + ->prototype('scalar')->end() + ; + + return $node; + } +} diff --git a/src/Symfony/Bundle/MonologBundle/DependencyInjection/MonologExtension.php b/src/Symfony/Bundle/MonologBundle/DependencyInjection/MonologExtension.php new file mode 100644 index 0000000000..4d4c6966a4 --- /dev/null +++ b/src/Symfony/Bundle/MonologBundle/DependencyInjection/MonologExtension.php @@ -0,0 +1,218 @@ + + * @author Christophe Coevoet + */ +class MonologExtension extends Extension +{ + private $nestedHandlers = array(); + + /** + * Loads the Monolog configuration. + * + * @param array $config An array of configuration settings + * @param ContainerBuilder $container A ContainerBuilder instance + */ + public function load(array $configs, ContainerBuilder $container) + { + $configuration = new Configuration(); + $processor = new Processor(); + $config = $processor->processConfiguration($configuration, $configs); + + if (isset($config['handlers'])) { + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('monolog.xml'); + $container->setAlias('logger', 'monolog.logger'); + + $logger = $container->getDefinition('monolog.logger_prototype'); + + if (!empty ($config['processors'])) { + $this->addProcessors($logger, $config['processors']); + } + + $handlers = array(); + foreach ($config['handlers'] as $name => $handler) { + $handlers[] = array('id' => $this->buildHandler($container, $name, $handler), 'priority' => $handler['priority'] ); + } + + $handlers = array_reverse($handlers); + uasort($handlers, function($a, $b) { + if ($a['priority'] == $b['priority']) { + return 0; + } + return $a['priority'] < $b['priority'] ? -1 : 1; + }); + foreach ($handlers as $handler) { + if (!in_array($handler['id'], $this->nestedHandlers)) { + $logger->addMethodCall('pushHandler', array(new Reference($handler['id']))); + } + } + } + + $this->addClassesToCompile(array( + 'Monolog\\Formatter\\FormatterInterface', + 'Monolog\\Formatter\\LineFormatter', + 'Monolog\\Handler\\HandlerInterface', + 'Monolog\\Handler\\AbstractHandler', + 'Monolog\\Handler\\StreamHandler', + 'Monolog\\Handler\\FingersCrossedHandler', + 'Monolog\\Handler\\TestHandler', + 'Monolog\\Logger', + 'Symfony\\Bundle\\MonologBundle\\Logger\\Logger', + 'Symfony\\Bundle\\MonologBundle\\Logger\\DebugHandler', + )); + } + + /** + * Returns the base path for the XSD files. + * + * @return string The XSD base path + */ + public function getXsdValidationBasePath() + { + return __DIR__.'/../Resources/config/schema'; + } + + public function getNamespace() + { + return 'http://symfony.com/schema/dic/monolog'; + } + + private function buildHandler(ContainerBuilder $container, $name, array $handler) + { + $handlerId = $this->getHandlerId($name); + $definition = new Definition(sprintf('%%monolog.handler.%s.class%%', $handler['type'])); + $handler['level'] = is_int($handler['level']) ? $handler['level'] : constant('Monolog\Logger::'.strtoupper($handler['level'])); + + switch ($handler['type']) { + case 'service': + $container->setAlias($handlerId, $handler['id']); + return $handlerId; + + case 'stream': + if (!isset($handler['path'])) { + $handler['path'] = '%kernel.logs_dir%/%kernel.environment%.log'; + } + + $definition->setArguments(array( + $handler['path'], + $handler['level'], + $handler['bubble'], + )); + 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['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); + + $definition->setArguments(array( + new Reference($nestedHandlerId), + $handler['action_level'], + isset($handler['buffer_size']) ? $handler['buffer_size'] : 0, + $handler['bubble'], + )); + break; + + case 'buffer': + $nestedHandlerId = $this->getHandlerId($handler['handler']); + array_push($this->nestedHandlers, $nestedHandlerId); + + $definition->setArguments(array( + new Reference($nestedHandlerId), + isset($handler['buffer_size']) ? $handler['buffer_size'] : 0, + $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'], + $handler['level'], + $handler['bubble'], + )); + break; + + default: + // Handler using the constructor of AbstractHandler without adding their own arguments + $definition->setArguments(array( + $handler['level'], + $handler['bubble'], + )); + break; + } + + if (!empty ($handler['formatter'])) { + $definition->addMethodCall('setFormatter', array(new Reference($handler['formatter']))); + } + if (!empty ($handler['processors'])) { + $this->addProcessors($definition, $handler['processors']); + } + $container->setDefinition($handlerId, $definition); + + return $handlerId; + } + + private function getHandlerId($name) + { + return sprintf('monolog.handler.%s', $name); + } + + 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)); + } + } +} diff --git a/src/Symfony/Bundle/MonologBundle/Logger/DebugHandler.php b/src/Symfony/Bundle/MonologBundle/Logger/DebugHandler.php new file mode 100644 index 0000000000..912823789a --- /dev/null +++ b/src/Symfony/Bundle/MonologBundle/Logger/DebugHandler.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\MonologBundle\Logger; + +use Monolog\Handler\TestHandler; +use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; + +/** + * DebugLogger. + * + * @author Jordi Boggiano + */ +class DebugHandler extends TestHandler implements DebugLoggerInterface +{ + /** + * {@inheritdoc} + */ + public function getLogs() + { + $records = array(); + foreach ($this->records as $record) { + $records[] = array( + 'timestamp' => $record['datetime']->getTimestamp(), + 'message' => $record['message'], + 'priority' => $record['level'], + 'priorityName' => $record['level_name'], + ); + } + return $records; + } + + /** + * {@inheritdoc} + */ + public function countErrors() + { + return isset($this->recordsByLevel[\Monolog\Logger::ERROR]) + ? count($this->recordsByLevel[\Monolog\Logger::ERROR]) + : 0; + } +} diff --git a/src/Symfony/Bundle/MonologBundle/Logger/Logger.php b/src/Symfony/Bundle/MonologBundle/Logger/Logger.php new file mode 100644 index 0000000000..6d74db904e --- /dev/null +++ b/src/Symfony/Bundle/MonologBundle/Logger/Logger.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\MonologBundle\Logger; + +use Monolog\Logger as BaseLogger; +use Symfony\Component\HttpKernel\Log\LoggerInterface; +use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; + +/** + * Logger. + * + * @author Fabien Potencier + */ +class Logger extends BaseLogger implements LoggerInterface +{ + /** + * Returns a DebugLoggerInterface instance if one is registered with this logger. + * + * @return DebugLoggerInterface A DebugLoggerInterface instance or null if none is registered + */ + public function getDebugLogger() + { + foreach ($this->handlers as $handler) { + if ($handler instanceof DebugLoggerInterface) { + return $handler; + } + } + } + + public function log($message, $level) + { + return $this->addRecord($level, $message); + } +} diff --git a/src/Symfony/Bundle/ZendBundle/ZendBundle.php b/src/Symfony/Bundle/MonologBundle/MonologBundle.php similarity index 54% rename from src/Symfony/Bundle/ZendBundle/ZendBundle.php rename to src/Symfony/Bundle/MonologBundle/MonologBundle.php index 5445d99136..e51ddf1e32 100644 --- a/src/Symfony/Bundle/ZendBundle/ZendBundle.php +++ b/src/Symfony/Bundle/MonologBundle/MonologBundle.php @@ -9,23 +9,25 @@ * file that was distributed with this source code. */ -namespace Symfony\Bundle\ZendBundle; +namespace Symfony\Bundle\MonologBundle; use Symfony\Component\HttpKernel\Bundle\Bundle; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Bundle\ZendBundle\DependencyInjection\Compiler\ZendLoggerWriterPass; +use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\LoggerChannelPass; +use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\DebugHandlerPass; /** * Bundle. * - * @author Fabien Potencier + * @author Jordi Boggiano */ -class ZendBundle extends Bundle +class MonologBundle extends Bundle { public function build(ContainerBuilder $container) { parent::build($container); - $container->addCompilerPass(new ZendLoggerWriterPass()); + $container->addCompilerPass(new LoggerChannelPass()); + $container->addCompilerPass(new DebugHandlerPass()); } } diff --git a/src/Symfony/Bundle/MonologBundle/Resources/config/monolog.xml b/src/Symfony/Bundle/MonologBundle/Resources/config/monolog.xml new file mode 100644 index 0000000000..f9d84105a8 --- /dev/null +++ b/src/Symfony/Bundle/MonologBundle/Resources/config/monolog.xml @@ -0,0 +1,28 @@ + + + + + + Symfony\Bundle\MonologBundle\Logger\Logger + Monolog\Handler\StreamHandler + Monolog\Handler\FingersCrossedHandler + Monolog\Handler\BufferHandler + Monolog\Handler\RotatingFileHandler + Monolog\Handler\SyslogHandler + Monolog\Handler\NullHandler + Monolog\Handler\TestHandler + Symfony\Bundle\MonologBundle\Logger\DebugHandler + + + + + app + + + + + + + diff --git a/src/Symfony/Bundle/MonologBundle/Resources/config/schema/monolog-1.0.xsd b/src/Symfony/Bundle/MonologBundle/Resources/config/schema/monolog-1.0.xsd new file mode 100644 index 0000000000..8f61e3d39c --- /dev/null +++ b/src/Symfony/Bundle/MonologBundle/Resources/config/schema/monolog-1.0.xsd @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Compiler/LoggerChannelPassTest.php b/src/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Compiler/LoggerChannelPassTest.php new file mode 100644 index 0000000000..20c3ca82e7 --- /dev/null +++ b/src/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/Compiler/LoggerChannelPassTest.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\MonologBundle\Tests\DependencyInjection\Compiler; + +use Symfony\Bundle\MonologBundle\Tests\TestCase; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\LoggerChannelPass; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; + +class LoggerChannelPassTest extends TestCase +{ + public function testProcess() + { + $container = $this->getContainer(); + $this->assertTrue($container->hasDefinition('monolog.logger.test'), '->process adds a logger service for tagged service'); + + $service = $container->getDefinition('test'); + $arguments = $service->getArguments(); + $this->assertEquals('monolog.logger.test', (string) $arguments[1], '->process replaces the logger by the new one'); + } + + protected function getContainer() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../../../Resources/config')); + $loader->load('monolog.xml'); + $definition = $container->getDefinition('monolog.logger_prototype'); + $container->set('monolog.handler.test', new Definition('%monolog.handler.null.class%', array (100, false))); + $definition->addMethodCall('pushHandler', array(new Reference('monolog.handler.test'))); + + $service = new Definition('TestClass', array('false', new Reference('logger'))); + $service->addTag('monolog.logger', array ('channel' => 'test')); + $container->setDefinition('test', $service); + + $container->getCompilerPassConfig()->setOptimizationPasses(array()); + $container->getCompilerPassConfig()->setRemovingPasses(array()); + $container->addCompilerPass(new LoggerChannelPass()); + $container->compile(); + + return $container; + } +} diff --git a/src/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/MonologExtensionTest.php b/src/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/MonologExtensionTest.php new file mode 100644 index 0000000000..1cecce1378 --- /dev/null +++ b/src/Symfony/Bundle/MonologBundle/Tests/DependencyInjection/MonologExtensionTest.php @@ -0,0 +1,263 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\MonologBundle\Tests\DependencyInjection; + +use Symfony\Bundle\MonologBundle\Tests\TestCase; +use Symfony\Bundle\MonologBundle\DependencyInjection\MonologExtension; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +class MonologExtensionTest extends TestCase +{ + public function testLoadWithDefault() + { + $container = new ContainerBuilder(); + $loader = new MonologExtension(); + + $loader->load(array(array('handlers' => array('main' => array('type' => 'stream')))), $container); + $this->assertTrue($container->hasDefinition('monolog.logger')); + $this->assertTrue($container->hasDefinition('monolog.handler.main')); + + $logger = $container->getDefinition('monolog.logger'); + $this->assertDICDefinitionMethodCallAt(0, $logger, 'pushHandler', array(new Reference('monolog.handler.main'))); + + $handler = $container->getDefinition('monolog.handler.main'); + $this->assertDICDefinitionClass($handler, '%monolog.handler.stream.class%'); + $this->assertDICConstructorArguments($handler, array('%kernel.logs_dir%/%kernel.environment%.log', \Monolog\Logger::DEBUG, false)); + } + + public function testLoadWithCustomValues() + { + $container = new ContainerBuilder(); + $loader = new MonologExtension(); + + $loader->load(array(array('handlers' => array('custom' => array('type' => 'stream', 'path' => '/tmp/symfony.log', 'bubble' => true, 'level' => 'ERROR')))), $container); + $this->assertTrue($container->hasDefinition('monolog.logger')); + $this->assertTrue($container->hasDefinition('monolog.handler.custom')); + + $logger = $container->getDefinition('monolog.logger'); + $this->assertDICDefinitionMethodCallAt(0, $logger, 'pushHandler', array(new Reference('monolog.handler.custom'))); + + $handler = $container->getDefinition('monolog.handler.custom'); + $this->assertDICDefinitionClass($handler, '%monolog.handler.stream.class%'); + $this->assertDICConstructorArguments($handler, array('/tmp/symfony.log', \Monolog\Logger::ERROR, true)); + } + + public function testLoadWithSeveralHandlers() + { + $container = new ContainerBuilder(); + $loader = new MonologExtension(); + + $loader->load(array(array('handlers' => array( + 'custom' => array('type' => 'stream', 'path' => '/tmp/symfony.log', 'bubble' => true, 'level' => 'ERROR'), + 'main' => array('type' => 'fingers_crossed', 'action_level' => 'ERROR', 'handler' => 'nested'), + 'nested' => array('type' => 'stream') + ))), $container); + $this->assertTrue($container->hasDefinition('monolog.logger')); + $this->assertTrue($container->hasDefinition('monolog.handler.custom')); + $this->assertTrue($container->hasDefinition('monolog.handler.main')); + $this->assertTrue($container->hasDefinition('monolog.handler.nested')); + + $logger = $container->getDefinition('monolog.logger'); + $this->assertDICDefinitionMethodCallAt(1, $logger, 'pushHandler', array(new Reference('monolog.handler.custom'))); + $this->assertDICDefinitionMethodCallAt(0, $logger, 'pushHandler', array(new Reference('monolog.handler.main'))); + + $handler = $container->getDefinition('monolog.handler.custom'); + $this->assertDICDefinitionClass($handler, '%monolog.handler.stream.class%'); + $this->assertDICConstructorArguments($handler, array('/tmp/symfony.log', \Monolog\Logger::ERROR, true)); + + $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)); + } + + public function testLoadWithOverwriting() + { + $container = new ContainerBuilder(); + $loader = new MonologExtension(); + + $loader->load(array( + array('handlers' => array( + 'custom' => array('type' => 'stream', 'path' => '/tmp/symfony.log', 'bubble' => true, 'level' => 'ERROR'), + 'main' => array('type' => 'fingers_crossed', 'action_level' => 'ERROR', 'handler' => 'nested'), + 'nested' => array('type' => 'stream') + )), + array('handlers' => array( + 'custom' => array('type' => 'stream', 'path' => '/tmp/symfony.log', 'bubble' => true, 'level' => 'WARNING'), + )) + ), $container); + $this->assertTrue($container->hasDefinition('monolog.logger')); + $this->assertTrue($container->hasDefinition('monolog.handler.custom')); + $this->assertTrue($container->hasDefinition('monolog.handler.main')); + $this->assertTrue($container->hasDefinition('monolog.handler.nested')); + + $logger = $container->getDefinition('monolog.logger'); + $this->assertDICDefinitionMethodCallAt(1, $logger, 'pushHandler', array(new Reference('monolog.handler.custom'))); + $this->assertDICDefinitionMethodCallAt(0, $logger, 'pushHandler', array(new Reference('monolog.handler.main'))); + + $handler = $container->getDefinition('monolog.handler.custom'); + $this->assertDICDefinitionClass($handler, '%monolog.handler.stream.class%'); + $this->assertDICConstructorArguments($handler, array('/tmp/symfony.log', \Monolog\Logger::WARNING, true)); + + $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)); + } + + public function testLoadWithNewAtEnd() + { + $container = new ContainerBuilder(); + $loader = new MonologExtension(); + + $loader->load(array( + array('handlers' => array( + 'custom' => array('type' => 'stream', 'path' => '/tmp/symfony.log', 'bubble' => true, 'level' => 'ERROR'), + 'main' => array('type' => 'fingers_crossed', 'action_level' => 'ERROR', 'handler' => 'nested'), + 'nested' => array('type' => 'stream') + )), + array('handlers' => array( + 'custom' => array('type' => 'stream', 'path' => '/tmp/symfony.log', 'bubble' => true, 'level' => 'WARNING'), + 'new' => array('type' => 'stream', 'path' => '/tmp/monolog.log', 'bubble' => true, 'level' => 'ERROR'), + )) + ), $container); + $this->assertTrue($container->hasDefinition('monolog.logger')); + $this->assertTrue($container->hasDefinition('monolog.handler.custom')); + $this->assertTrue($container->hasDefinition('monolog.handler.main')); + $this->assertTrue($container->hasDefinition('monolog.handler.nested')); + $this->assertTrue($container->hasDefinition('monolog.handler.new')); + + $logger = $container->getDefinition('monolog.logger'); + $this->assertDICDefinitionMethodCallAt(2, $logger, 'pushHandler', array(new Reference('monolog.handler.new'))); + $this->assertDICDefinitionMethodCallAt(1, $logger, 'pushHandler', array(new Reference('monolog.handler.custom'))); + $this->assertDICDefinitionMethodCallAt(0, $logger, 'pushHandler', array(new Reference('monolog.handler.main'))); + + $handler = $container->getDefinition('monolog.handler.new'); + $this->assertDICDefinitionClass($handler, '%monolog.handler.stream.class%'); + $this->assertDICConstructorArguments($handler, array('/tmp/monolog.log', \Monolog\Logger::ERROR, true)); + } + + public function testLoadWithNewAndPriority() + { + $container = new ContainerBuilder(); + $loader = new MonologExtension(); + + $loader->load(array( + array('handlers' => array( + 'custom' => array('type' => 'stream', 'path' => '/tmp/symfony.log', 'bubble' => true, 'level' => 'ERROR'), + 'main' => array('type' => 'buffer', 'level' => 'INFO', 'handler' => 'nested'), + 'nested' => array('type' => 'stream') + )), + array('handlers' => array( + 'custom' => array('type' => 'stream', 'path' => '/tmp/symfony.log', 'bubble' => true, 'level' => 'WARNING'), + 'first' => array('type' => 'rotating_file', 'path' => '/tmp/monolog.log', 'bubble' => true, 'level' => 'ERROR', 'priority' => 3), + 'last' => array('type' => 'stream', 'path' => '/tmp/last.log', 'bubble' => true, 'level' => 'ERROR', 'priority' => -3), + )) + ), $container); + $this->assertTrue($container->hasDefinition('monolog.logger')); + $this->assertTrue($container->hasDefinition('monolog.handler.custom')); + $this->assertTrue($container->hasDefinition('monolog.handler.main')); + $this->assertTrue($container->hasDefinition('monolog.handler.nested')); + $this->assertTrue($container->hasDefinition('monolog.handler.first')); + $this->assertTrue($container->hasDefinition('monolog.handler.last')); + + $logger = $container->getDefinition('monolog.logger'); + $this->assertDICDefinitionMethodCallAt(2, $logger, 'pushHandler', array(new Reference('monolog.handler.last'))); + $this->assertDICDefinitionMethodCallAt(1, $logger, 'pushHandler', array(new Reference('monolog.handler.custom'))); + $this->assertDICDefinitionMethodCallAt(0, $logger, 'pushHandler', array(new Reference('monolog.handler.main'))); + $this->assertDICDefinitionMethodCallAt(2, $logger, 'pushHandler', array(new Reference('monolog.handler.first'))); + + $handler = $container->getDefinition('monolog.handler.main'); + $this->assertDICDefinitionClass($handler, '%monolog.handler.buffer.class%'); + $this->assertDICConstructorArguments($handler, array(new Reference('monolog.handler.nested'), 0, \Monolog\Logger::INFO, false)); + + $handler = $container->getDefinition('monolog.handler.first'); + $this->assertDICDefinitionClass($handler, '%monolog.handler.rotating_file.class%'); + $this->assertDICConstructorArguments($handler, array('/tmp/monolog.log', 0, \Monolog\Logger::ERROR, true)); + + $handler = $container->getDefinition('monolog.handler.last'); + $this->assertDICDefinitionClass($handler, '%monolog.handler.stream.class%'); + $this->assertDICConstructorArguments($handler, array('/tmp/last.log', \Monolog\Logger::ERROR, true)); + } + + /** + * @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + */ + public function testExceptionWhenUsingFingerscrossedWithoutHandler() + { + $container = new ContainerBuilder(); + $loader = new MonologExtension(); + + $loader->load(array(array('handlers' => array('main' => array('type' => 'fingers_crossed')))), $container); + } + + /** + * @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + */ + public function testExceptionWhenUsingBufferWithoutHandler() + { + $container = new ContainerBuilder(); + $loader = new MonologExtension(); + + $loader->load(array(array('handlers' => array('main' => array('type' => 'buffer')))), $container); + } + + /** + * @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + */ + public function testExceptionWhenUsingServiceWithoutId() + { + $container = new ContainerBuilder(); + $loader = new MonologExtension(); + + $loader->load(array(array('handlers' => array('main' => array('type' => 'service')))), $container); + } + + /** + * @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + */ + public function testExceptionWhenUsingDebugName() + { + // logger + $container = new ContainerBuilder(); + $loader = new MonologExtension(); + + $loader->load(array(array('handlers' => array('debug' => array('type' => 'stream')))), $container); + } + + /** + * Assertion on the Class of a DIC Service Definition. + * + * @param \Symfony\Component\DependencyInjection\Definition $definition + * @param string $expectedClass + */ + protected function assertDICDefinitionClass($definition, $expectedClass) + { + $this->assertEquals($expectedClass, $definition->getClass(), "Expected Class of the DIC Container Service Definition is wrong."); + } + + protected function assertDICConstructorArguments($definition, $args) + { + $this->assertEquals($args, $definition->getArguments(), "Expected and actual DIC Service constructor arguments of definition '" . $definition->getClass()."' don't match."); + } + + protected function assertDICDefinitionMethodCallAt($pos, $definition, $methodName, array $params = null) + { + $calls = $definition->getMethodCalls(); + if (isset($calls[$pos][0])) { + $this->assertEquals($methodName, $calls[$pos][0], "Method '".$methodName."' is expected to be called at position $pos."); + + if ($params !== null) { + $this->assertEquals($params, $calls[$pos][1], "Expected parameters to methods '" . $methodName . "' do not match the actual parameters."); + } + } + } +} diff --git a/src/Symfony/Bundle/MonologBundle/Tests/TestCase.php b/src/Symfony/Bundle/MonologBundle/Tests/TestCase.php new file mode 100644 index 0000000000..9df6f38b05 --- /dev/null +++ b/src/Symfony/Bundle/MonologBundle/Tests/TestCase.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\MonologBundle\Tests; + +class TestCase extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Monolog\Logger')) { + $this->markTestSkipped('Monolog is not available.'); + } + } +} diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/AddSecurityVotersPass.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/AddSecurityVotersPass.php index 19d1319cec..a856584da4 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/AddSecurityVotersPass.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/AddSecurityVotersPass.php @@ -40,6 +40,6 @@ class AddSecurityVotersPass implements CompilerPassInterface $voters = iterator_to_array($voters); ksort($voters); - $container->getDefinition('security.access.decision_manager')->setArgument(0, array_values($voters)); + $container->getDefinition('security.access.decision_manager')->replaceArgument(0, array_values($voters)); } } \ No newline at end of file diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/FactoryConfiguration.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/FactoryConfiguration.php new file mode 100644 index 0000000000..d45797485b --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/FactoryConfiguration.php @@ -0,0 +1,45 @@ + + */ +class FactoryConfiguration implements ConfigurationInterface +{ + /** + * Generates the configuration tree builder. + * + * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder + */ + public function getConfigTreeBuilder() + { + $tb = new TreeBuilder(); + + $tb + ->root('security') + ->ignoreExtraKeys() + ->fixXmlConfig('factory', 'factories') + ->children() + ->arrayNode('factories') + ->prototype('scalar')->end() + ->end() + ->end() + ->end() + ; + + return $tb; + } +} \ No newline at end of file diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php similarity index 81% rename from src/Symfony/Bundle/SecurityBundle/DependencyInjection/Configuration.php rename to src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php index b649473299..6884cfafff 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php @@ -4,6 +4,7 @@ namespace Symfony\Bundle\SecurityBundle\DependencyInjection; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\ConfigurationInterface; /** * This class contains the configuration information for the following tags: @@ -16,31 +17,26 @@ use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; * * @author Johannes M. Schmitt */ -class Configuration +class MainConfiguration implements ConfigurationInterface { - /** - * Generates the configuration tree. - * - * @return \Symfony\Component\Config\Definition\ArrayNode The config tree - */ - public function getFactoryConfigTree() - { - $tb = new TreeBuilder(); + private $factories; - return $tb - ->root('security') - ->ignoreExtraKeys() - ->fixXmlConfig('factory', 'factories') - ->children() - ->arrayNode('factories') - ->prototype('scalar')->end() - ->end() - ->end() - ->end() - ->buildTree(); + /** + * Constructor. + * + * @param array $factories + */ + public function __construct(array $factories) + { + $this->factories = $factories; } - public function getMainConfigTree(array $factories) + /** + * Generates the configuration tree builder. + * + * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder + */ + public function getConfigTreeBuilder() { $tb = new TreeBuilder(); $rootNode = $tb->root('security'); @@ -49,6 +45,15 @@ class Configuration ->children() ->scalarNode('access_denied_url')->defaultNull()->end() ->scalarNode('session_fixation_strategy')->cannotBeEmpty()->defaultValue('migrate')->end() + ->booleanNode('always_authenticate_before_granting')->defaultFalse()->end() + ->arrayNode('access_decision_manager') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('strategy')->defaultValue('affirmative')->end() + ->booleanNode('allow_if_all_abstain')->defaultFalse()->end() + ->booleanNode('allow_if_equal_granted_denied')->defaultTrue()->end() + ->end() + ->end() ->end() // add a faux-entry for factories, so that no validation error is thrown ->fixXmlConfig('factory', 'factories') @@ -60,11 +65,11 @@ class Configuration $this->addAclSection($rootNode); $this->addEncodersSection($rootNode); $this->addProvidersSection($rootNode); - $this->addFirewallsSection($rootNode, $factories); + $this->addFirewallsSection($rootNode, $this->factories); $this->addAccessControlSection($rootNode); $this->addRoleHierarchySection($rootNode); - return $tb->buildTree(); + return $tb; } private function addAclSection(ArrayNodeDefinition $rootNode) @@ -74,7 +79,29 @@ class Configuration ->arrayNode('acl') ->children() ->scalarNode('connection')->end() - ->scalarNode('cache')->end() + ->arrayNode('cache') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('id')->end() + ->scalarNode('prefix')->defaultValue('sf2_acl_')->end() + ->end() + ->end() + ->arrayNode('tables') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('class')->defaultValue('acl_classes')->end() + ->scalarNode('entry')->defaultValue('acl_entries')->end() + ->scalarNode('object_identity')->defaultValue('acl_object_identities')->end() + ->scalarNode('object_identity_ancestors')->defaultValue('acl_object_identity_ancestors')->end() + ->scalarNode('security_identity')->defaultValue('acl_security_identities')->end() + ->end() + ->end() + ->arrayNode('voter') + ->addDefaultsIfNotSet() + ->children() + ->booleanNode('allow_if_object_identity_unavailable')->defaultTrue()->end() + ->end() + ->end() ->end() ->end() ->end() diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AbstractFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AbstractFactory.php index 4e91baff24..703821fdaf 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AbstractFactory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AbstractFactory.php @@ -148,17 +148,17 @@ abstract class AbstractFactory implements SecurityFactoryInterface { $listenerId = $this->getListenerId(); $listener = new DefinitionDecorator($listenerId); - $listener->setArgument(3, $id); - $listener->setArgument(4, array_intersect_key($config, $this->options)); + $listener->replaceArgument(3, $id); + $listener->replaceArgument(4, array_intersect_key($config, $this->options)); // success handler if (isset($config['success_handler'])) { - $listener->setArgument(5, new Reference($config['success_handler'])); + $listener->replaceArgument(5, new Reference($config['success_handler'])); } // failure handler if (isset($config['failure_handler'])) { - $listener->setArgument(6, new Reference($config['failure_handler'])); + $listener->replaceArgument(6, new Reference($config['failure_handler'])); } $listenerId .= '.'.$id; diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FormLoginFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FormLoginFactory.php index 53296e5862..e23b4d52b9 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FormLoginFactory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FormLoginFactory.php @@ -65,8 +65,8 @@ class FormLoginFactory extends AbstractFactory $provider = 'security.authentication.provider.dao.'.$id; $container ->setDefinition($provider, new DefinitionDecorator('security.authentication.provider.dao')) - ->setArgument(0, new Reference($userProviderId)) - ->setArgument(2, $id) + ->replaceArgument(0, new Reference($userProviderId)) + ->replaceArgument(2, $id) ; return $provider; diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/HttpBasicFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/HttpBasicFactory.php index 8a5a17b0cf..c87f68c38f 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/HttpBasicFactory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/HttpBasicFactory.php @@ -29,8 +29,8 @@ class HttpBasicFactory implements SecurityFactoryInterface $provider = 'security.authentication.provider.dao.'.$id; $container ->setDefinition($provider, new DefinitionDecorator('security.authentication.provider.dao')) - ->setArgument(0, new Reference($userProvider)) - ->setArgument(2, $id) + ->replaceArgument(0, new Reference($userProvider)) + ->replaceArgument(2, $id) ; // entry point @@ -39,8 +39,8 @@ class HttpBasicFactory implements SecurityFactoryInterface // listener $listenerId = 'security.authentication.listener.basic.'.$id; $listener = $container->setDefinition($listenerId, new DefinitionDecorator('security.authentication.listener.basic')); - $listener->setArgument(2, $id); - $listener->setArgument(3, new Reference($entryPointId)); + $listener->replaceArgument(2, $id); + $listener->replaceArgument(3, new Reference($entryPointId)); return array($provider, $listenerId, $entryPointId); } diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/HttpDigestFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/HttpDigestFactory.php index cdeaeb43a4..2f09be07af 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/HttpDigestFactory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/HttpDigestFactory.php @@ -29,8 +29,8 @@ class HttpDigestFactory implements SecurityFactoryInterface $provider = 'security.authentication.provider.dao.'.$id; $container ->setDefinition($provider, new DefinitionDecorator('security.authentication.provider.dao')) - ->setArgument(0, new Reference($userProvider)) - ->setArgument(2, $id) + ->replaceArgument(0, new Reference($userProvider)) + ->replaceArgument(2, $id) ; // entry point @@ -39,9 +39,9 @@ class HttpDigestFactory implements SecurityFactoryInterface // listener $listenerId = 'security.authentication.listener.digest.'.$id; $listener = $container->setDefinition($listenerId, new DefinitionDecorator('security.authentication.listener.digest')); - $listener->setArgument(1, new Reference($userProvider)); - $listener->setArgument(2, $id); - $listener->setArgument(3, new Reference($entryPointId)); + $listener->replaceArgument(1, new Reference($userProvider)); + $listener->replaceArgument(2, $id); + $listener->replaceArgument(3, new Reference($entryPointId)); return array($provider, $listenerId, $entryPointId); } diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php index 68c7c5227e..13cf66fa39 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php @@ -35,9 +35,6 @@ class RememberMeFactory implements SecurityFactoryInterface // remember me services if (isset($config['token_provider'])) { - $config['token-provider'] = $config['token_provider']; - } - if (isset($config['token-provider'])) { $templateId = 'security.authentication.rememberme.services.persistent'; $rememberMeServicesId = $templateId.'.'.$id; } else { @@ -53,18 +50,17 @@ class RememberMeFactory implements SecurityFactoryInterface } $rememberMeServices = $container->setDefinition($rememberMeServicesId, new DefinitionDecorator($templateId)); - $rememberMeServices->setArgument(1, $config['key']); - $rememberMeServices->setArgument(2, $id); + $rememberMeServices->replaceArgument(1, $config['key']); + $rememberMeServices->replaceArgument(2, $id); - if (isset($config['token-provider'])) { - // FIXME: make the naming assumption more flexible + if (isset($config['token_provider'])) { $rememberMeServices->addMethodCall('setTokenProvider', array( - new Reference('security.rememberme.token.provider.'.$config['token-provider']) + new Reference($config['token_provider']) )); } // remember-me options - $rememberMeServices->setArgument(3, array_intersect_key($config, $this->options)); + $rememberMeServices->replaceArgument(3, array_intersect_key($config, $this->options)); // attach to remember-me aware listeners $userProviders = array(); @@ -88,12 +84,12 @@ class RememberMeFactory implements SecurityFactoryInterface if (count($userProviders) === 0) { throw new \RuntimeException('You must configure at least one remember-me aware listener (such as form-login) for each firewall that has remember-me enabled.'); } - $rememberMeServices->setArgument(0, $userProviders); + $rememberMeServices->replaceArgument(0, $userProviders); // remember-me listener $listenerId = 'security.authentication.listener.rememberme.'.$id; $listener = $container->setDefinition($listenerId, new DefinitionDecorator('security.authentication.listener.rememberme')); - $listener->setArgument(1, new Reference($rememberMeServicesId)); + $listener->replaceArgument(1, new Reference($rememberMeServicesId)); return array($authProviderId, $listenerId, $defaultEntryPoint); } @@ -111,7 +107,7 @@ class RememberMeFactory implements SecurityFactoryInterface public function addConfiguration(NodeDefinition $node) { $builder = $node->children(); - + $builder ->scalarNode('key')->isRequired()->cannotBeEmpty()->end() ->scalarNode('token_provider')->end() diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/X509Factory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/X509Factory.php index 87625cc2cd..d24942b672 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/X509Factory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/X509Factory.php @@ -30,16 +30,16 @@ class X509Factory implements SecurityFactoryInterface $provider = 'security.authentication.provider.pre_authenticated.'.$id; $container ->setDefinition($provider, new DefinitionDecorator('security.authentication.provider.pre_authenticated')) - ->setArgument(0, new Reference($userProvider)) + ->replaceArgument(0, new Reference($userProvider)) ->addArgument($id) ; // listener $listenerId = 'security.authentication.listener.x509.'.$id; $listener = $container->setDefinition($listenerId, new DefinitionDecorator('security.authentication.listener.x509')); - $listener->setArgument(2, $id); - $listener->setArgument(3, $config['user']); - $listener->setArgument(4, $config['credentials']); + $listener->replaceArgument(2, $id); + $listener->replaceArgument(3, $config['user']); + $listener->replaceArgument(4, $config['credentials']); return array($provider, $listenerId, $defaultEntryPoint); } diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php index 51713df7f5..689678cdaf 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php @@ -11,7 +11,6 @@ namespace Symfony\Bundle\SecurityBundle\DependencyInjection; -use Symfony\Component\Config\Definition\Processor; use Symfony\Component\DependencyInjection\DefinitionDecorator; use Symfony\Component\DependencyInjection\Alias; use Symfony\Component\HttpKernel\DependencyInjection\Extension; @@ -20,6 +19,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\Parameter; use Symfony\Component\Config\FileLocator; +use Symfony\Component\Config\Definition\Processor; /** * SecurityExtension. @@ -32,14 +32,8 @@ class SecurityExtension extends Extension private $requestMatchers = array(); private $contextListeners = array(); private $listenerPositions = array('pre_auth', 'form', 'http', 'remember_me'); - private $configuration; private $factories; - public function __construct() - { - $this->configuration = new Configuration(); - } - public function load(array $configs, ContainerBuilder $container) { if (!array_filter($configs)) { @@ -49,11 +43,13 @@ class SecurityExtension extends Extension $processor = new Processor(); // first assemble the factories - $factories = $this->createListenerFactories($container, $processor->process($this->configuration->getFactoryConfigTree(), $configs)); + $factoriesConfig = new FactoryConfiguration(); + $config = $processor->processConfiguration($factoriesConfig, $configs); + $factories = $this->createListenerFactories($container, $config); // normalize and merge the actual configuration - $tree = $this->configuration->getMainConfigTree($factories); - $config = $processor->process($tree, $configs); + $mainConfig = new MainConfiguration($factories); + $config = $processor->processConfiguration($mainConfig, $configs); // load services $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); @@ -66,7 +62,14 @@ class SecurityExtension extends Extension // set some global scalars $container->setParameter('security.access.denied_url', $config['access_denied_url']); - $container->setParameter('security.authentication.session_strategy.strategy', $config['session_fixation_strategy']); + $container->getDefinition('security.authentication.session_strategy')->replaceArgument(0, $config['session_fixation_strategy']); + $container + ->getDefinition('security.access.decision_manager') + ->addArgument($config['access_decision_manager']['strategy']) + ->addArgument($config['access_decision_manager']['allow_if_all_abstain']) + ->addArgument($config['access_decision_manager']['allow_if_equal_granted_denied']) + ; + $container->setParameter('security.access.always_authenticate_before_granting', $config['always_authenticate_before_granting']); $this->createFirewalls($config, $container); $this->createAuthorization($config, $container); @@ -111,9 +114,18 @@ class SecurityExtension extends Extension $container->setAlias('security.acl.dbal.connection', sprintf('doctrine.dbal.%s_connection', $config['connection'])); } - if (isset($config['cache'])) { - $container->setAlias('security.acl.cache', sprintf('security.acl.cache.%s', $config['cache'])); + if (isset($config['cache']['id'])) { + $container->setAlias('security.acl.cache', $config['cache']['id']); } + $container->getDefinition('security.acl.cache.doctrine')->addArgument($config['cache']['prefix']); + + $container->setParameter('security.acl.dbal.class_table_name', $config['tables']['class']); + $container->setParameter('security.acl.dbal.entry_table_name', $config['tables']['entry']); + $container->setParameter('security.acl.dbal.oid_table_name', $config['tables']['object_identity']); + $container->setParameter('security.acl.dbal.oid_ancestors_table_name', $config['tables']['object_identity_ancestors']); + $container->setParameter('security.acl.dbal.sid_table_name', $config['tables']['security_identity']); + + $container->getDefinition('security.acl.voter.basic_permissions')->addArgument($config['voter']['allow_if_object_identity_unavailable']); } /** @@ -126,13 +138,13 @@ class SecurityExtension extends Extension private function createRoleHierarchy($config, ContainerBuilder $container) { if (!isset($config['role_hierarchy'])) { - $container->remove('security.access.role_hierarchy_voter'); + $container->removeDefinition('security.access.role_hierarchy_voter'); return; } $container->setParameter('security.role_hierarchy.roles', $config['role_hierarchy']); - $container->remove('security.access.simple_role_voter'); + $container->removeDefinition('security.access.simple_role_voter'); } private function createAuthorization($config, ContainerBuilder $container) @@ -190,12 +202,12 @@ class SecurityExtension extends Extension $contextId = 'security.firewall.map.context.'.$name; $context = $container->setDefinition($contextId, new DefinitionDecorator('security.firewall.context')); $context - ->setArgument(0, $listeners) - ->setArgument(1, $exceptionListener) + ->replaceArgument(0, $listeners) + ->replaceArgument(1, $exceptionListener) ; $map[$contextId] = $matcher; } - $mapDef->setArgument(1, $map); + $mapDef->replaceArgument(1, $map); // add authentication providers to authentication manager $authenticationProviders = array_map(function($id) { @@ -203,7 +215,7 @@ class SecurityExtension extends Extension }, array_values(array_unique($authenticationProviders))); $container ->getDefinition('security.authentication.manager') - ->setArgument(0, $authenticationProviders) + ->replaceArgument(0, $authenticationProviders) ; } @@ -251,13 +263,13 @@ class SecurityExtension extends Extension if (isset($firewall['logout'])) { $listenerId = 'security.logout_listener.'.$id; $listener = $container->setDefinition($listenerId, new DefinitionDecorator('security.logout_listener')); - $listener->setArgument(1, $firewall['logout']['path']); - $listener->setArgument(2, $firewall['logout']['target']); + $listener->replaceArgument(1, $firewall['logout']['path']); + $listener->replaceArgument(2, $firewall['logout']['target']); $listeners[] = new Reference($listenerId); // add logout success handler if (isset($firewall['logout']['success_handler'])) { - $listener->setArgument(3, new Reference($firewall['logout']['success_handler'])); + $listener->replaceArgument(3, new Reference($firewall['logout']['success_handler'])); } // add session logout handler @@ -312,7 +324,7 @@ class SecurityExtension extends Extension $listenerId = 'security.context_listener.'.count($this->contextListeners); $listener = $container->setDefinition($listenerId, new DefinitionDecorator('security.context_listener')); - $listener->setArgument(2, $contextKey); + $listener->replaceArgument(2, $contextKey); return $this->contextListeners[$contextKey] = $listenerId; } @@ -344,7 +356,7 @@ class SecurityExtension extends Extension $listenerId = 'security.authentication.listener.anonymous.'.$id; $container ->setDefinition($listenerId, new DefinitionDecorator('security.authentication.listener.anonymous')) - ->setArgument(1, $firewall['anonymous']['key']) + ->replaceArgument(1, $firewall['anonymous']['key']) ; $listeners[] = new Reference($listenerId); @@ -352,7 +364,7 @@ class SecurityExtension extends Extension $providerId = 'security.authentication.provider.anonymous.'.$id; $container ->setDefinition($providerId, new DefinitionDecorator('security.authentication.provider.anonymous')) - ->setArgument(0, $firewall['anonymous']['key']) + ->replaceArgument(0, $firewall['anonymous']['key']) ; $authenticationProviders[] = $providerId; @@ -484,13 +496,13 @@ class SecurityExtension extends Extension { $exceptionListenerId = 'security.exception_listener.'.$id; $listener = $container->setDefinition($exceptionListenerId, new DefinitionDecorator('security.exception_listener')); - $listener->setArgument(2, null === $defaultEntryPoint ? null : new Reference($defaultEntryPoint)); + $listener->replaceArgument(2, null === $defaultEntryPoint ? null : new Reference($defaultEntryPoint)); // access denied handler setup if (isset($config['access_denied_handler'])) { - $listener->setArgument(4, new Reference($config['access_denied_handler'])); + $listener->replaceArgument(4, new Reference($config['access_denied_handler'])); } else if (isset($config['access_denied_url'])) { - $listener->setArgument(3, $config['access_denied_url']); + $listener->replaceArgument(3, $config['access_denied_url']); } return $exceptionListenerId; @@ -502,10 +514,10 @@ class SecurityExtension extends Extension $switchUserListenerId = 'security.authentication.switchuser_listener.'.$id; $listener = $container->setDefinition($switchUserListenerId, new DefinitionDecorator('security.authentication.switchuser_listener')); - $listener->setArgument(1, new Reference($userProvider)); - $listener->setArgument(3, $id); - $listener->setArgument(6, $config['parameter']); - $listener->setArgument(7, $config['role']); + $listener->replaceArgument(1, new Reference($userProvider)); + $listener->replaceArgument(3, $id); + $listener->replaceArgument(6, $config['parameter']); + $listener->replaceArgument(7, $config['role']); return $switchUserListenerId; } diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/collectors.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/collectors.xml index 626db6eb04..f6106f7f70 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/collectors.xml +++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/collectors.xml @@ -10,7 +10,7 @@ - + diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml index 7d2b44b953..276a68880c 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml +++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml @@ -6,7 +6,6 @@ Symfony\Component\Security\Core\SecurityContext - false Symfony\Component\Security\Core\User\UserChecker @@ -26,12 +25,8 @@ Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager Symfony\Component\Security\Http\Session\SessionAuthenticationStrategy - migrate Symfony\Component\Security\Core\Authorization\AccessDecisionManager - affirmative - false - true Symfony\Component\Security\Core\Authorization\Voter\RoleVoter Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter @@ -49,7 +44,7 @@ - %security.context.always_authenticate% + %security.access.always_authenticate_before_granting% @@ -63,7 +58,7 @@
- %security.authentication.session_strategy.strategy% + @@ -78,9 +73,6 @@ - %security.access.decision_manager.strategy% - %security.access.decision_manager.allow_if_all_abstain% - %security.access.decision_manager.allow_if_equal_granted_denied% diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl.xml index c789929290..6942f4cf1f 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl.xml +++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl.xml @@ -5,24 +5,17 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - acl_classes - acl_entries - acl_object_identities - acl_object_identity_ancestors - acl_security_identities Symfony\Component\Security\Acl\Dbal\MutableAclProvider Symfony\Component\Security\Acl\Domain\PermissionGrantingStrategy Symfony\Component\Security\Acl\Voter\AclVoter - true Symfony\Component\Security\Acl\Permission\BasicPermissionMap Symfony\Component\Security\Acl\Domain\ObjectIdentityRetrievalStrategy Symfony\Component\Security\Acl\Domain\SecurityIdentityRetrievalStrategy Symfony\Component\Security\Acl\Domain\DoctrineAclCache - sf2_acl_ Symfony\Component\Security\Acl\Domain\AclCollectionCache @@ -60,8 +53,7 @@ - - %security.acl.cache.doctrine.prefix% + @@ -69,12 +61,12 @@ + - %security.acl.voter.allow_if_object_identity_unavailable%
diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml index 60af0fed64..246fb85a43 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml +++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml @@ -41,6 +41,7 @@ + @@ -57,6 +58,7 @@ + @@ -65,6 +67,7 @@ + @@ -86,6 +89,7 @@ + @@ -97,13 +101,14 @@ - + @@ -114,6 +119,7 @@ + @@ -122,6 +128,7 @@ + @@ -142,6 +149,7 @@ + @@ -151,6 +159,7 @@ + @@ -163,6 +172,7 @@ + diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_rememberme.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_rememberme.xml index 2d60fa0b4b..3dee5b0071 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_rememberme.xml +++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_rememberme.xml @@ -6,54 +6,56 @@ Symfony\Component\Security\Core\Authentication\Provider\RememberMeAuthenticationProvider - + Symfony\Component\Security\Http\Firewall\RememberMeListener - Symfony\Component\Security\Core\Authentication\RememberMe\InMemoryTokenProvider - + Symfony\Component\Security\Core\Authentication\RememberMe\InMemoryTokenProvider + Symfony\Component\Security\Http\RememberMe\PersistentTokenBasedRememberMeServices Symfony\Component\Security\Http\RememberMe\TokenBasedRememberMeServices - + Symfony\Bundle\SecurityBundle\ResponseListener - + + - + - - + + + - - - - - - + + + + - - \ No newline at end of file + + diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig b/src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig index dfbf6abc5a..5bece80c50 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig +++ b/src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig @@ -1,4 +1,4 @@ -{% extends 'WebProfiler:Profiler:layout.html.twig' %} +{% extends 'WebProfilerBundle:Profiler:layout.html.twig' %} {% block toolbar %} {% set icon %} @@ -13,7 +13,7 @@ disabled {% endif %} {% endset %} - {% include 'WebProfiler:Profiler:toolbar_item.html.twig' with { 'link': profiler_url } %} + {% include 'WebProfilerBundle:Profiler:toolbar_item.html.twig' with { 'link': profiler_url } %} {% endblock %} {% block menu %} diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/ConfigurationTest.php index 675c675190..c0e6070d8a 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/ConfigurationTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/ConfigurationTest.php @@ -11,7 +11,7 @@ namespace Symfony\Bundle\SecurityBundle\Tests\DependencyInjection; -use Symfony\Bundle\SecurityBundle\DependencyInjection\Configuration; +use Symfony\Bundle\SecurityBundle\DependencyInjection\MainConfiguration; use Symfony\Component\Config\Definition\Processor; class ConfigurationTest extends \PHPUnit_Framework_TestCase @@ -41,11 +41,10 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase 'factory' => array('foo' => 'bar'), 'factories' => array('lorem' => 'ipsum'), )); - - $configuration = new Configuration(); + $processor = new Processor(); - $tree = $configuration->getMainConfigTree(array()); - $config = $processor->process($tree, array($config)); + $configuration = new MainConfiguration(array()); + $config = $processor->processConfiguration($configuration, array($config)); $this->assertFalse(array_key_exists('factory', $config), 'The factory key is silently removed without an exception'); $this->assertEquals(array(), $config['factories'], 'The factories key is just an empty array'); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/container1.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/container1.php index ac3b060716..66594ae03b 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/container1.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/container1.php @@ -33,7 +33,7 @@ $container->loadFromExtension('security', array( ), ), 'doctrine' => array( - 'entity' => array('class' => 'Security:User', 'property' => 'username') + 'entity' => array('class' => 'SecurityBundle:User', 'property' => 'username') ), 'service' => array( 'id' => 'user.manager', diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/container1.xml b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/container1.xml index d0c5d45fcb..efd204ac95 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/container1.xml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/container1.xml @@ -28,7 +28,7 @@ - + diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/container1.yml b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/container1.yml index 136177e968..4f1d8a3c2c 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/container1.yml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/container1.yml @@ -22,7 +22,7 @@ security: foo: { password: 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33, roles: ROLE_SUPER_ADMIN } bar: { password: 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33, roles: [ROLE_USER, ROLE_ADMIN] } doctrine: - entity: { class: Security:User, property: username } + entity: { class: SecurityBundle:User, property: username } service: id: user.manager chain: diff --git a/src/Symfony/Bundle/SwiftmailerBundle/DataCollector/MessageDataCollector.php b/src/Symfony/Bundle/SwiftmailerBundle/DataCollector/MessageDataCollector.php index d038159e47..8f78d2498d 100644 --- a/src/Symfony/Bundle/SwiftmailerBundle/DataCollector/MessageDataCollector.php +++ b/src/Symfony/Bundle/SwiftmailerBundle/DataCollector/MessageDataCollector.php @@ -25,7 +25,7 @@ class MessageDataCollector extends DataCollector { protected $logger; protected $mailer; - + public function __construct(\Swift_Events_SendListener $logger, \Swift_Mailer $mailer) { $this->logger = $logger; @@ -51,7 +51,7 @@ class MessageDataCollector extends DataCollector { return $this->data['messages']; } - + public function isSpool() { return $this->data['isSpool']; diff --git a/src/Symfony/Bundle/SwiftmailerBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/SwiftmailerBundle/DependencyInjection/Configuration.php index d678be3792..ac2423ecb0 100644 --- a/src/Symfony/Bundle/SwiftmailerBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/SwiftmailerBundle/DependencyInjection/Configuration.php @@ -13,6 +13,7 @@ namespace Symfony\Bundle\SwiftmailerBundle\DependencyInjection; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; /** * This class contains the configuration information for the bundle @@ -22,16 +23,26 @@ use Symfony\Component\Config\Definition\Builder\TreeBuilder; * * @author Christophe Coevoet */ -class Configuration +class Configuration implements ConfigurationInterface { + private $debug; + /** - * Generates the configuration tree. + * Constructor. * - * @param Boolean $kernelDebug - * - * @return \Symfony\Component\Config\Definition\ArrayNode The config tree + * @param Boolean $debug The kernel.debug value */ - public function getConfigTree($kernelDebug) + public function __construct($debug) + { + $this->debug = (Boolean) $debug; + } + + /** + * Generates the configuration tree builder. + * + * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder + */ + public function getConfigTreeBuilder() { $treeBuilder = new TreeBuilder(); $rootNode = $treeBuilder->root('swiftmailer'); @@ -71,10 +82,10 @@ class Configuration ->end() ->scalarNode('delivery_address')->end() ->booleanNode('disable_delivery')->end() - ->booleanNode('logging')->defaultValue($kernelDebug)->end() + ->booleanNode('logging')->defaultValue($this->debug)->end() ->end() ; - return $treeBuilder->buildTree(); + return $treeBuilder; } } diff --git a/src/Symfony/Bundle/SwiftmailerBundle/DependencyInjection/SwiftmailerExtension.php b/src/Symfony/Bundle/SwiftmailerBundle/DependencyInjection/SwiftmailerExtension.php index 135fd96f18..76bd58468f 100644 --- a/src/Symfony/Bundle/SwiftmailerBundle/DependencyInjection/SwiftmailerExtension.php +++ b/src/Symfony/Bundle/SwiftmailerBundle/DependencyInjection/SwiftmailerExtension.php @@ -48,9 +48,9 @@ class SwiftmailerExtension extends Extension $r = new \ReflectionClass('Swift_Message'); $container->getDefinition('swiftmailer.mailer')->setFile(dirname(dirname(dirname($r->getFilename()))).'/swift_init.php'); - $configuration = new Configuration(); $processor = new Processor(); - $config = $processor->process($configuration->getConfigTree($container->getParameter('kernel.debug')), $configs); + $configuration = new Configuration($container->getParameter('kernel.debug')); + $config = $processor->processConfiguration($configuration, $configs); if (null === $config['transport']) { $transport = 'null'; @@ -95,7 +95,7 @@ class SwiftmailerExtension extends Extension if ($config['logging']) { $container->findDefinition('swiftmailer.transport')->addMethodCall('registerPlugin', array(new Reference('swiftmailer.plugin.messagelogger'))); - $container->findDefinition('swiftmailer.data_collector')->addTag('data_collector', array('template' => 'Swiftmailer:Collector:swiftmailer', 'id' => 'swiftmailer')); + $container->findDefinition('swiftmailer.data_collector')->addTag('data_collector', array('template' => 'SwiftmailerBundle:Collector:swiftmailer', 'id' => 'swiftmailer')); } if (isset($config['delivery_address']) && $config['delivery_address']) { diff --git a/src/Symfony/Bundle/SwiftmailerBundle/Logger/MessageLogger.php b/src/Symfony/Bundle/SwiftmailerBundle/Logger/MessageLogger.php index e5534dea31..62d72b862a 100644 --- a/src/Symfony/Bundle/SwiftmailerBundle/Logger/MessageLogger.php +++ b/src/Symfony/Bundle/SwiftmailerBundle/Logger/MessageLogger.php @@ -53,7 +53,7 @@ class MessageLogger implements \Swift_Events_SendListener /** * Empty the message list - * + * */ public function clear() { diff --git a/src/Symfony/Bundle/SwiftmailerBundle/Resources/views/Collector/swiftmailer.html.twig b/src/Symfony/Bundle/SwiftmailerBundle/Resources/views/Collector/swiftmailer.html.twig index 21303db0c0..bfd8a2d079 100644 --- a/src/Symfony/Bundle/SwiftmailerBundle/Resources/views/Collector/swiftmailer.html.twig +++ b/src/Symfony/Bundle/SwiftmailerBundle/Resources/views/Collector/swiftmailer.html.twig @@ -1,4 +1,4 @@ -{% extends 'WebProfiler:Profiler:layout.html.twig' %} +{% extends 'WebProfilerBundle:Profiler:layout.html.twig' %} {% block toolbar %} {% if collector.messagecount %} @@ -8,7 +8,7 @@ {% set text %} {{ collector.messagecount }} {% endset %} - {% include 'WebProfiler:Profiler:toolbar_item.html.twig' with { 'link': profiler_url } %} + {% include 'WebProfilerBundle:Profiler:toolbar_item.html.twig' with { 'link': profiler_url } %} {% endif %} {% endblock %} diff --git a/src/Symfony/Bundle/TwigBundle/CacheWarmer/TemplateCacheCacheWarmer.php b/src/Symfony/Bundle/TwigBundle/CacheWarmer/TemplateCacheCacheWarmer.php index 11fe3f809c..aaefc69950 100644 --- a/src/Symfony/Bundle/TwigBundle/CacheWarmer/TemplateCacheCacheWarmer.php +++ b/src/Symfony/Bundle/TwigBundle/CacheWarmer/TemplateCacheCacheWarmer.php @@ -25,8 +25,6 @@ use Symfony\Component\Finder\Finder; */ class TemplateCacheCacheWarmer extends CacheWarmer { - const TEMPLATES_PATH_IN_BUNDLE = '/Resources/views'; - protected $container; protected $parser; protected $kernel; @@ -59,12 +57,12 @@ class TemplateCacheCacheWarmer extends CacheWarmer $twig = $this->container->get('twig'); foreach ($this->kernel->getBundles() as $name => $bundle) { - foreach ($this->findTemplatesIn($bundle->getPath().self::TEMPLATES_PATH_IN_BUNDLE, $name) as $template) { + foreach ($this->findTemplatesIn($bundle->getPath().'/Resources/views', $name) as $template) { $twig->loadTemplate($template); } } - foreach ($this->findTemplatesIn($this->rootDir) as $template) { + foreach ($this->findTemplatesIn($this->rootDir.'/views') as $template) { $twig->loadTemplate($template); } } @@ -99,7 +97,7 @@ class TemplateCacheCacheWarmer extends CacheWarmer if (null !== $bundle) { $template->set('bundle', $bundle); } - $templates[] = $template; + $templates[] = $template->getLogicalName(); } } } diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php index 76c90fc0fe..d22d365f36 100644 --- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php @@ -4,27 +4,28 @@ namespace Symfony\Bundle\TwigBundle\DependencyInjection; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; /** * TwigExtension configuration structure. * * @author Jeremy Mikola */ -class Configuration +class Configuration implements ConfigurationInterface { /** - * Generates the configuration tree. + * Generates the configuration tree builder. * - * @return \Symfony\Component\Config\Definition\ArrayNode The config tree + * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder */ - public function getConfigTree() + public function getConfigTreeBuilder() { $treeBuilder = new TreeBuilder(); $rootNode = $treeBuilder->root('twig'); $rootNode ->children() - ->scalarNode('cache_warmer')->end() + ->scalarNode('cache_warmer')->defaultFalse()->end() ->end(); ; @@ -33,7 +34,7 @@ class Configuration $this->addGlobalsSection($rootNode); $this->addTwigOptions($rootNode); - return $treeBuilder->buildTree(); + return $treeBuilder; } private function addExtensionsSection(ArrayNodeDefinition $rootNode) @@ -42,12 +43,7 @@ class Configuration ->fixXmlConfig('extension') ->children() ->arrayNode('extensions') - ->prototype('scalar') - ->beforeNormalization() - ->ifTrue(function($v) { return is_array($v) && isset($v['id']); }) - ->then(function($v){ return $v['id']; }) - ->end() - ->end() + ->prototype('scalar')->end() ->end() ->end() ; @@ -63,11 +59,11 @@ class Configuration ->children() ->arrayNode('resources') ->addDefaultsIfNotSet() - ->defaultValue(array('Twig::form.html.twig')) + ->defaultValue(array('TwigBundle::form.html.twig')) ->validate() ->always() ->then(function($v){ - return array_merge(array('Twig::form.html.twig'), $v); + return array_merge(array('TwigBundle::form.html.twig'), $v); }) ->end() ->prototype('scalar')->end() diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php index 70212a2b5c..56501fe89b 100644 --- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php +++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php @@ -39,8 +39,7 @@ class TwigExtension extends Extension $processor = new Processor(); $configuration = new Configuration(); - - $config = $processor->process($configuration->getConfigTree(), $configs); + $config = $processor->processConfiguration($configuration, $configs); $container->setParameter('twig.form.resources', $config['form']['resources']); @@ -61,7 +60,7 @@ class TwigExtension extends Extension } } - if (!empty($config['cache_warmer'])) { + if ($config['cache_warmer']) { $container->getDefinition('twig.cache_warmer')->addTag('kernel.cache_warmer'); } diff --git a/src/Symfony/Bundle/TwigBundle/Extension/TemplatingExtension.php b/src/Symfony/Bundle/TwigBundle/Extension/TemplatingExtension.php index a57e8a31e6..8ed8321543 100644 --- a/src/Symfony/Bundle/TwigBundle/Extension/TemplatingExtension.php +++ b/src/Symfony/Bundle/TwigBundle/Extension/TemplatingExtension.php @@ -75,7 +75,7 @@ class TemplatingExtension extends \Twig_Extension /** * Returns the Response content for a given controller or URI. * - * @param string $controller A controller name to execute (a string like Blog:Post:index), or a relative URI + * @param string $controller A controller name to execute (a string like BlogBundle:Post:index), or a relative URI * @param array $attributes An array of request attributes * @param array $options An array of options * @@ -100,7 +100,7 @@ class TemplatingExtension extends \Twig_Extension public function getTokenParsers() { return array( - // {% render 'Blog:Post:list' with { 'limit': 2 }, { 'alt': 'Blog:Post:error' } %} + // {% render 'BlogBundle:Post:list' with { 'limit': 2 }, { 'alt': 'BlogBundle:Post:error' } %} new RenderTokenParser(), // {% include 'sometemplate.php' with { 'something' : 'something2' } %} diff --git a/src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.php b/src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.php index 0bacdd7269..292b4cfa37 100644 --- a/src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.php +++ b/src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.php @@ -76,12 +76,18 @@ class FilesystemLoader implements \Twig_LoaderInterface return filemtime($this->findTemplate($name)) < $time; } + /** + * Returns the path to the template file + * + * @param $name The template logical name + * + * @return string The path to the template file + */ protected function findTemplate($name) { - $tpl = ($name instanceof TemplateReferenceInterface) ? $name : $this->parser->parse($name); + $tpl = $this->parser->parse($name); - $key = $tpl->getSignature(); - if (isset($this->cache[$key])) { + if (isset($this->cache[$key = $tpl->getSignature()])) { return $this->cache[$key]; } @@ -94,7 +100,7 @@ class FilesystemLoader implements \Twig_LoaderInterface } if (false === $file || null === $file) { - throw new \Twig_Error_Loader(sprintf('Unable to find template "%s".', json_encode($name)), 0, null, $previous); + throw new \Twig_Error_Loader(sprintf('Unable to find template "%s".', $tpl), -1, null, $previous); } return $this->cache[$key] = $file; diff --git a/src/Symfony/Bundle/TwigBundle/Node/FormThemeNode.php b/src/Symfony/Bundle/TwigBundle/Node/FormThemeNode.php index 1a0b7edafd..418d1af1c1 100644 --- a/src/Symfony/Bundle/TwigBundle/Node/FormThemeNode.php +++ b/src/Symfony/Bundle/TwigBundle/Node/FormThemeNode.php @@ -12,7 +12,7 @@ namespace Symfony\Bundle\TwigBundle\Node; /** - * + * * * @author Fabien Potencier */ diff --git a/src/Symfony/Bundle/TwigBundle/Node/HelperNode.php b/src/Symfony/Bundle/TwigBundle/Node/HelperNode.php index 9a9709b6da..9df2baa668 100644 --- a/src/Symfony/Bundle/TwigBundle/Node/HelperNode.php +++ b/src/Symfony/Bundle/TwigBundle/Node/HelperNode.php @@ -12,7 +12,7 @@ namespace Symfony\Bundle\TwigBundle\Node; /** - * + * * * @author Fabien Potencier */ diff --git a/src/Symfony/Bundle/TwigBundle/Resources/config/schema/twig-1.0.xsd b/src/Symfony/Bundle/TwigBundle/Resources/config/schema/twig-1.0.xsd index d972068c7d..f6163abd33 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/config/schema/twig-1.0.xsd +++ b/src/Symfony/Bundle/TwigBundle/Resources/config/schema/twig-1.0.xsd @@ -11,7 +11,7 @@ - + @@ -36,10 +36,6 @@ - - - - diff --git a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml index 04dbb8a4a6..01ca99f3e6 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml +++ b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml @@ -19,7 +19,7 @@ - %kernel.root_dir%/views + %kernel.root_dir%/Resources diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/php/full.php b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/php/full.php index c092bd3cbc..840e393aa1 100644 --- a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/php/full.php +++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/php/full.php @@ -3,7 +3,7 @@ $container->loadFromExtension('twig', array( 'form' => array( 'resources' => array( - 'My::form.html.twig', + 'MyBundle::form.html.twig', ) ), 'extensions' => array( diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/xml/full.xml b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/xml/full.xml index 0a07ba8744..f0355e9bb2 100644 --- a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/xml/full.xml +++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/xml/full.xml @@ -8,11 +8,11 @@ - My::form.html.twig + MyBundle::form.html.twig 3.14 - - + twig.extension.debug + twig.extension.text diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/yml/full.yml b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/yml/full.yml index 2da6a19b2b..55378d6acc 100644 --- a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/yml/full.yml +++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/yml/full.yml @@ -1,7 +1,7 @@ twig: form: resources: - - My::form.html.twig + - MyBundle::form.html.twig extensions: - twig.extension.debug - twig.extension.text diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php index d37aa386ea..922f8efead 100644 --- a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php +++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php @@ -35,7 +35,7 @@ class TwigExtensionTest extends TestCase $this->assertEquals('Twig_Environment', $container->getParameter('twig.class'), '->load() loads the twig.xml file'); $this->assertFalse($container->getDefinition('twig.cache_warmer')->hasTag('kernel.cache_warmer'), '->load() does not enable cache warming by default'); - $this->assertContains('Twig::form.html.twig', $container->getParameter('twig.form.resources'), '->load() includes default template for form resources'); + $this->assertContains('TwigBundle::form.html.twig', $container->getParameter('twig.form.resources'), '->load() includes default template for form resources'); // Twig options $options = $container->getParameter('twig.options'); @@ -65,8 +65,8 @@ class TwigExtensionTest extends TestCase // Form resources $resources = $container->getParameter('twig.form.resources'); - $this->assertContains('Twig::form.html.twig', $resources, '->load() includes default template for form resources'); - $this->assertContains('My::form.html.twig', $resources, '->load() merges new templates into form resources'); + $this->assertContains('TwigBundle::form.html.twig', $resources, '->load() includes default template for form resources'); + $this->assertContains('MyBundle::form.html.twig', $resources, '->load() merges new templates into form resources'); // Globals $calls = $container->getDefinition('twig')->getMethodCalls(); diff --git a/src/Symfony/Bundle/TwigBundle/TokenParser/FormThemeTokenParser.php b/src/Symfony/Bundle/TwigBundle/TokenParser/FormThemeTokenParser.php index d30bb7a285..f2b80f064b 100644 --- a/src/Symfony/Bundle/TwigBundle/TokenParser/FormThemeTokenParser.php +++ b/src/Symfony/Bundle/TwigBundle/TokenParser/FormThemeTokenParser.php @@ -14,7 +14,7 @@ namespace Symfony\Bundle\TwigBundle\TokenParser; use Symfony\Bundle\TwigBundle\Node\FormThemeNode; /** - * + * * * @author Fabien Potencier */ diff --git a/src/Symfony/Bundle/TwigBundle/TokenParser/IncludeTokenParser.php b/src/Symfony/Bundle/TwigBundle/TokenParser/IncludeTokenParser.php index 42e1f81061..cb7db4fd52 100644 --- a/src/Symfony/Bundle/TwigBundle/TokenParser/IncludeTokenParser.php +++ b/src/Symfony/Bundle/TwigBundle/TokenParser/IncludeTokenParser.php @@ -14,7 +14,7 @@ namespace Symfony\Bundle\TwigBundle\TokenParser; use Symfony\Bundle\TwigBundle\Node\IncludeNode; /** - * + * * * @author Fabien Potencier */ diff --git a/src/Symfony/Bundle/WebProfilerBundle/Controller/ExceptionController.php b/src/Symfony/Bundle/WebProfilerBundle/Controller/ExceptionController.php index b069524312..72127a1d9a 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Controller/ExceptionController.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Controller/ExceptionController.php @@ -33,7 +33,7 @@ class ExceptionController extends BaseExceptionController $code = $exception->getStatusCode(); return $this->container->get('templating')->renderResponse( - 'Framework:Exception:'.$template.'.html.twig', + 'FrameworkBundle:Exception:'.$template.'.html.twig', array( 'status_code' => $code, 'status_text' => Response::$statusTexts[$code], diff --git a/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php b/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php index a55a9d0e32..8f944190a8 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php @@ -39,7 +39,7 @@ class ProfilerController extends ContainerAware $profiler = $this->container->get('profiler')->loadFromToken($token); if ($profiler->isEmpty()) { - return $this->container->get('templating')->renderResponse('WebProfiler:Profiler:notfound.html.twig', array('token' => $token)); + return $this->container->get('templating')->renderResponse('WebProfilerBundle:Profiler:notfound.html.twig', array('token' => $token)); } if (!$profiler->has($panel)) { @@ -129,8 +129,10 @@ class ProfilerController extends ContainerAware { $request = $this->container->get('request'); - // keep current flashes for one more request - $request->getSession()->setFlashes($request->getSession()->getFlashes()); + if (null !== $session = $request->getSession()) { + // keep current flashes for one more request + $session->setFlashes($session->getFlashes()); + } if (null === $token) { return new Response(); @@ -156,11 +158,12 @@ class ProfilerController extends ContainerAware // the profiler is not enabled } - return $this->container->get('templating')->renderResponse('WebProfiler:Profiler:toolbar.html.twig', array( + return $this->container->get('templating')->renderResponse('WebProfilerBundle:Profiler:toolbar.html.twig', array( 'position' => $position, 'profiler' => $profiler, 'templates' => $this->getTemplates($profiler), 'profiler_url' => $url, + 'verbose' => $this->container->get('web_profiler.debug.toolbar')->getVerbose() )); } @@ -174,17 +177,23 @@ class ProfilerController extends ContainerAware $profiler = $this->container->get('profiler'); $profiler->disable(); - $session = $this->container->get('request')->getSession(); - $ip = $session->get('_profiler_search_ip'); - $url = $session->get('_profiler_search_url'); - $limit = $session->get('_profiler_search_limit'); - $token = $session->get('_profiler_search_token'); + if (null === $session = $this->container->get('request')->getSession()) { + $ip = + $url = + $limit = + $token = null; + } else { + $ip = $session->get('_profiler_search_ip'); + $url = $session->get('_profiler_search_url'); + $limit = $session->get('_profiler_search_limit'); + $token = $session->get('_profiler_search_token'); + } - return $this->container->get('templating')->renderResponse('WebProfiler:Profiler:search.html.twig', array( - 'token' => $token, - 'ip' => $ip, - 'url' => $url, - 'limit' => $limit, + return $this->container->get('templating')->renderResponse('WebProfilerBundle:Profiler:search.html.twig', array( + 'token' => $token, + 'ip' => $ip, + 'url' => $url, + 'limit' => $limit, )); } @@ -200,12 +209,11 @@ class ProfilerController extends ContainerAware $pofiler = $profiler->loadFromToken($token); - $session = $this->container->get('request')->getSession(); - $ip = $session->get('_profiler_search_ip'); - $url = $session->get('_profiler_search_url'); - $limit = $session->get('_profiler_search_limit'); + $ip = $this->container->get('request')->query->get('ip'); + $url = $this->container->get('request')->query->get('url'); + $limit = $this->container->get('request')->query->get('limit'); - return $this->container->get('templating')->renderResponse('WebProfiler:Profiler:results.html.twig', array( + return $this->container->get('templating')->renderResponse('WebProfilerBundle:Profiler:results.html.twig', array( 'token' => $token, 'profiler' => $profiler, 'tokens' => $profiler->find($ip, $url, $limit), @@ -228,11 +236,17 @@ class ProfilerController extends ContainerAware $request = $this->container->get('request'); - $session = $request->getSession(); - $session->set('_profiler_search_ip', $ip = preg_replace('/[^\d\.]/', '', $request->query->get('ip'))); - $session->set('_profiler_search_url', $url = $request->query->get('url')); - $session->set('_profiler_search_limit', $limit = $request->query->get('limit')); - $session->set('_profiler_search_token', $token = $request->query->get('token')); + $ip = preg_replace('/[^\d\.]/', '', $request->query->get('ip')); + $url = $request->query->get('url'); + $limit = $request->query->get('limit'); + $token = $request->query->get('token'); + + if (null !== $session = $request->getSession()) { + $session->set('_profiler_search_ip', $ip); + $session->set('_profiler_search_url', $url); + $session->set('_profiler_search_limit', $limit); + $session->set('_profiler_search_token', $token); + } if (!empty($token)) { return new RedirectResponse($this->container->get('router')->generate('_profiler', array('token' => $token))); @@ -240,7 +254,12 @@ class ProfilerController extends ContainerAware $tokens = $profiler->find($ip, $url, $limit); - return new RedirectResponse($this->container->get('router')->generate('_profiler_search_results', array('token' => $tokens ? $tokens[0]['token'] : 'empty'))); + return new RedirectResponse($this->container->get('router')->generate('_profiler_search_results', array( + 'token' => $tokens ? $tokens[0]['token'] : 'empty', + 'ip' => $ip, + 'url' => $url, + 'limit' => $limit, + ))); } protected function getTemplateNames($profiler) diff --git a/src/Symfony/Bundle/WebProfilerBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/WebProfilerBundle/DependencyInjection/Configuration.php index c1252e9706..9b121e30c6 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/WebProfilerBundle/DependencyInjection/Configuration.php @@ -12,6 +12,7 @@ namespace Symfony\Bundle\WebProfilerBundle\DependencyInjection; use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; /** * This class contains the configuration information for the bundle @@ -21,25 +22,26 @@ use Symfony\Component\Config\Definition\Builder\TreeBuilder; * * @author Fabien Potencier */ -class Configuration +class Configuration implements ConfigurationInterface { /** - * Generates the configuration tree. + * Generates the configuration tree builder. * - * @return \Symfony\Component\Config\Definition\ArrayNode The config tree + * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder */ - public function getConfigTree() + public function getConfigTreeBuilder() { $treeBuilder = new TreeBuilder(); $rootNode = $treeBuilder->root('web_profiler'); $rootNode ->children() + ->booleanNode('verbose')->defaultTrue()->end() ->booleanNode('toolbar')->defaultFalse()->end() - ->scalarNode('intercept_redirects')->defaultFalse()->end() + ->booleanNode('intercept_redirects')->defaultFalse()->end() ->end() ; - return $treeBuilder->buildTree(); + return $treeBuilder; } } diff --git a/src/Symfony/Bundle/WebProfilerBundle/DependencyInjection/WebProfilerExtension.php b/src/Symfony/Bundle/WebProfilerBundle/DependencyInjection/WebProfilerExtension.php index 1e48d41ce6..2217e72679 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/DependencyInjection/WebProfilerExtension.php +++ b/src/Symfony/Bundle/WebProfilerBundle/DependencyInjection/WebProfilerExtension.php @@ -39,15 +39,18 @@ class WebProfilerExtension extends Extension */ public function load(array $configs, ContainerBuilder $container) { - $configuration = new Configuration(); $processor = new Processor(); - $config = $processor->process($configuration->getConfigTree(), $configs); + $configuration = new Configuration(); + $config = $processor->processConfiguration($configuration, $configs); if ($config['toolbar']) { $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); $loader->load('toolbar.xml'); - $container->getDefinition('web_profiler.debug.toolbar')->setArgument(1, $config['intercept_redirects']); + $container->getDefinition('web_profiler.debug.toolbar') + ->replaceArgument(1, $config['intercept_redirects']) + ->replaceArgument(2, $config['verbose']) + ; } } diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/profiler.xml b/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/profiler.xml index 0b0786470f..7c3d3232c0 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/profiler.xml +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/profiler.xml @@ -5,27 +5,27 @@ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd"> - WebProfiler:Profiler:search + WebProfilerBundle:Profiler:search - WebProfiler:Profiler:purge + WebProfilerBundle:Profiler:purge - WebProfiler:Profiler:import + WebProfilerBundle:Profiler:import - WebProfiler:Profiler:export + WebProfilerBundle:Profiler:export - WebProfiler:Profiler:searchResults + WebProfilerBundle:Profiler:searchResults - WebProfiler:Profiler:panel + WebProfilerBundle:Profiler:panel diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/wdt.xml b/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/wdt.xml index c707f7f91d..da52074b29 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/wdt.xml +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/wdt.xml @@ -5,6 +5,6 @@ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd"> - WebProfiler:Profiler:toolbar + WebProfilerBundle:Profiler:toolbar diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/config/schema/webprofiler-1.0.xsd b/src/Symfony/Bundle/WebProfilerBundle/Resources/config/schema/webprofiler-1.0.xsd index e22105a178..2fd744a1fc 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/config/schema/webprofiler-1.0.xsd +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/config/schema/webprofiler-1.0.xsd @@ -10,5 +10,6 @@ + diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/config/toolbar.xml b/src/Symfony/Bundle/WebProfilerBundle/Resources/config/toolbar.xml index 5918bb96a8..0f83e8d37e 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/config/toolbar.xml +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/config/toolbar.xml @@ -13,6 +13,7 @@ + diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/public/css/profiler.css b/src/Symfony/Bundle/WebProfilerBundle/Resources/public/css/profiler.css index 13f9a3901c..6dc81a5518 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/public/css/profiler.css +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/public/css/profiler.css @@ -100,6 +100,12 @@ fieldset border:none; } +abbr +{ + border-bottom: 1px dotted #000000; + cursor: help; +} + .clear { clear:both; diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/public/css/toolbar.css b/src/Symfony/Bundle/WebProfilerBundle/Resources/public/css/toolbar.css index bdabd8dcac..a656d21238 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/public/css/toolbar.css +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/public/css/toolbar.css @@ -5,7 +5,7 @@ http://developer.yahoo.com/yui/license.html version: 3.1.2 build: 56 */ -.sf-toolbarreset html{color:#000;background:#FFF;}.sf-toolbarreset body,.sf-toolbarreset div,.sf-toolbarreset dl,.sf-toolbarreset dt,.sf-toolbarreset dd,.sf-toolbarreset ul,.sf-toolbarreset ol,.sf-toolbarreset li,.sf-toolbarreset h1,.sf-toolbarreset h2,.sf-toolbarreset h3,.sf-toolbarreset h4,.sf-toolbarreset h5,.sf-toolbarreset h6,.sf-toolbarreset pre,.sf-toolbarreset code,.sf-toolbarreset form,.sf-toolbarreset fieldset,.sf-toolbarreset legend,.sf-toolbarreset input,.sf-toolbarreset textarea,.sf-toolbarreset p,.sf-toolbarreset blockquote,.sf-toolbarreset th,.sf-toolbarreset td{margin:0;padding:0;}.sf-toolbarreset table{border-collapse:collapse;border-spacing:0;}.sf-toolbarreset fieldset,.sf-toolbarreset img{border:0;}.sf-toolbarreset address,.sf-toolbarreset caption,.sf-toolbarreset cite,.sf-toolbarreset code,.sf-toolbarreset dfn,.sf-toolbarreset em,.sf-toolbarreset strong,.sf-toolbarreset th,.sf-toolbarreset var{font-style:normal;font-weight:normal;}.sf-toolbarreset li{list-style:none;}.sf-toolbarreset caption,.sf-toolbarreset th{text-align:left;}.sf-toolbarreset h1,.sf-toolbarreset h2,.sf-toolbarreset h3,.sf-toolbarreset h4,.sf-toolbarreset h5,.sf-toolbarreset h6{font-size:100%;font-weight:normal;}.sf-toolbarreset q:before,.sf-toolbarreset q:after{content:'';}.sf-toolbarreset abbr,.sf-toolbarreset acronym{border:0;font-variant:normal;}.sf-toolbarreset sup{vertical-align:text-top;}.sf-toolbarreset sub{vertical-align:text-bottom;}.sf-toolbarreset input,.sf-toolbarreset textarea,.sf-toolbarreset select{font-family:inherit;font-size:inherit;font-weight:inherit;}.sf-toolbarreset input,.sf-toolbarreset textarea,.sf-toolbarreset select{*font-size:100%;}.sf-toolbarreset legend{color:#000;} +.sf-toolbarreset div,.sf-toolbarreset dl,.sf-toolbarreset dt,.sf-toolbarreset dd,.sf-toolbarreset ul,.sf-toolbarreset ol,.sf-toolbarreset li,.sf-toolbarreset h1,.sf-toolbarreset h2,.sf-toolbarreset h3,.sf-toolbarreset h4,.sf-toolbarreset h5,.sf-toolbarreset h6,.sf-toolbarreset pre,.sf-toolbarreset code,.sf-toolbarreset form,.sf-toolbarreset fieldset,.sf-toolbarreset legend,.sf-toolbarreset input,.sf-toolbarreset textarea,.sf-toolbarreset p,.sf-toolbarreset blockquote,.sf-toolbarreset th,.sf-toolbarreset td{margin:0;padding:0;}.sf-toolbarreset table{border-collapse:collapse;border-spacing:0;}.sf-toolbarreset fieldset,.sf-toolbarreset img{border:0;}.sf-toolbarreset address,.sf-toolbarreset caption,.sf-toolbarreset cite,.sf-toolbarreset code,.sf-toolbarreset dfn,.sf-toolbarreset em,.sf-toolbarreset strong,.sf-toolbarreset th,.sf-toolbarreset var{font-style:normal;font-weight:normal;}.sf-toolbarreset li{list-style:none;}.sf-toolbarreset caption,.sf-toolbarreset th{text-align:left;}.sf-toolbarreset h1,.sf-toolbarreset h2,.sf-toolbarreset h3,.sf-toolbarreset h4,.sf-toolbarreset h5,.sf-toolbarreset h6{font-size:100%;font-weight:normal;}.sf-toolbarreset q:before,.sf-toolbarreset q:after{content:'';}.sf-toolbarreset abbr,.sf-toolbarreset acronym{border:0;font-variant:normal;}.sf-toolbarreset sup{vertical-align:text-top;}.sf-toolbarreset sub{vertical-align:text-bottom;}.sf-toolbarreset input,.sf-toolbarreset textarea,.sf-toolbarreset select{font-family:inherit;font-size:inherit;font-weight:inherit;}.sf-toolbarreset input,.sf-toolbarreset textarea,.sf-toolbarreset select{*font-size:100%;}.sf-toolbarreset legend{color:#000;} .sf-toolbarreset { background: #cbcbcb; @@ -21,3 +21,8 @@ build: 56 font: 11px Verdana, Arial, sans-serif; color: #000; } + +.sf-toolbarreset abbr { + border-bottom: 1px dotted #000000; + cursor: help; +} diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/config.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/config.html.twig index 732d260d92..2a2aae05e1 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/config.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/config.html.twig @@ -1,21 +1,23 @@ -{% extends 'WebProfiler:Profiler:layout.html.twig' %} +{% extends 'WebProfilerBundle:Profiler:layout.html.twig' %} {% block toolbar %} {% set icon %} Symfony {% endset %} - {% include 'WebProfiler:Profiler:toolbar_item.html.twig' with { 'link': false, 'text': collector.symfonyversion } %} + {% include 'WebProfilerBundle:Profiler:toolbar_item.html.twig' with { 'link': false, 'text': collector.symfonyversion } %} - {% set text %} - {% spaceless %} - PHP {{ collector.phpversion }} - | - xdebug - | - accel - {% endspaceless %} - {% endset %} - {% include 'WebProfiler:Profiler:toolbar_item.html.twig' with { 'link': false, 'icon': '' } %} + {% if verbose %} + {% set text %} + {% spaceless %} + PHP {{ collector.phpversion }} + | + xdebug + | + accel + {% endspaceless %} + {% endset %} + {% include 'WebProfilerBundle:Profiler:toolbar_item.html.twig' with { 'link': false, 'icon': '' } %} + {% endif %} {% set icon %} Environment| - {{ collector.env }} - | - {{ collector.debug ? 'debug' : 'no-debug' }} - | + {% if verbose %} + {{ collector.appname }} + | + {{ collector.env }} + | + {{ collector.debug ? 'debug' : 'no-debug' }} + | + {% endif %} {% if profiler_url %} {{ collector.token }} @@ -38,7 +42,7 @@ {% endspaceless %} {% endset %} - {% include 'WebProfiler:Profiler:toolbar_item.html.twig' with { 'link': profiler_url } %} + {% include 'WebProfilerBundle:Profiler:toolbar_item.html.twig' with { 'link': profiler_url } %} {% endblock %} {% block menu %} diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/events.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/events.html.twig index 0f9d418906..320ae35ea2 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/events.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/events.html.twig @@ -1,4 +1,6 @@ -{% extends 'WebProfiler:Profiler:layout.html.twig' %} +{% extends 'WebProfilerBundle:Profiler:layout.html.twig' %} + +{% from _self import display_listener %} {% block menu %} @@ -12,13 +14,13 @@ - - + + - {% for elements in collector.calledlisteners %} + {% for listener in collector.calledlisteners %} - - + + {% endfor %}
ClassEventEvent nameListener
{{ elements.class|abbr_class }}{{ elements.event }}{{ listener.event }}{{ display_listener(listener) }}
@@ -28,15 +30,24 @@ - + - {% for elements in collector.notcalledlisteners %} + {% for listener in collector.notcalledlisteners %} - - + + {% endfor %}
EventEvent name Listener
{{ elements.class|abbr_class }}{{ elements.event }}{{ listener.event }}{{ display_listener(listener) }}
{% endif %} {% endblock %} + +{% macro display_listener(listener) %} + {% if listener.type == "Closure" %} + Closure + {% else %} + {% set link = listener.file|file_link(listener.line) %} + {{ listener.class|abbr_class }}::{% if link %}{{ listener.event }}{% else %}{{ listener.event }}{% endif %} + {% endif %} +{% endmacro %} diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/exception.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/exception.html.twig index a18f4ced4b..0812957b7d 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/exception.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/exception.html.twig @@ -1,4 +1,4 @@ -{% extends 'WebProfiler:Profiler:layout.html.twig' %} +{% extends 'WebProfilerBundle:Profiler:layout.html.twig' %} {% block head %} @@ -25,6 +25,6 @@ No exception was thrown and uncaught during the request.

{% else %} - {% render 'WebProfiler:Exception:show' with { 'exception': collector.exception, 'format': 'html' } %} + {% render 'WebProfilerBundle:Exception:show' with { 'exception': collector.exception, 'format': 'html' } %} {% endif %} {% endblock %} diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/logger.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/logger.html.twig index 6c85c2b04f..80beec6da0 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/logger.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/logger.html.twig @@ -1,4 +1,4 @@ -{% extends 'WebProfiler:Profiler:layout.html.twig' %} +{% extends 'WebProfilerBundle:Profiler:layout.html.twig' %} {% block toolbar %} {% if collector.counterrors %} @@ -8,7 +8,7 @@ {% set text %} {{ collector.counterrors }} {% endset %} - {% include 'WebProfiler:Profiler:toolbar_item.html.twig' with { 'link': profiler_url } %} + {% include 'WebProfilerBundle:Profiler:toolbar_item.html.twig' with { 'link': profiler_url } %} {% endif %} {% endblock %} @@ -30,8 +30,7 @@ {% if collector.logs %}
    {% for log in collector.logs %} -
  • - {{ log.priorityName }} +
  • {{ log.message }}
  • {% endfor %} diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/memory.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/memory.html.twig index 396dd5aee5..4dd4ba6e71 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/memory.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/memory.html.twig @@ -1,4 +1,4 @@ -{% extends 'WebProfiler:Profiler:layout.html.twig' %} +{% extends 'WebProfilerBundle:Profiler:layout.html.twig' %} {% block toolbar %} {% set icon %} @@ -7,5 +7,5 @@ {% set text %} {{ '%.0f'|format(collector.memory / 1024) }} KB {% endset %} - {% include 'WebProfiler:Profiler:toolbar_item.html.twig' with { 'link': false } %} + {% include 'WebProfilerBundle:Profiler:toolbar_item.html.twig' with { 'link': false } %} {% endblock %} diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig index f5cbf6417a..b3752b7729 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig @@ -1,4 +1,4 @@ -{% extends 'WebProfiler:Profiler:layout.html.twig' %} +{% extends 'WebProfilerBundle:Profiler:layout.html.twig' %} {% block toolbar %} {% set icon %} @@ -17,14 +17,10 @@ | {{ collector.route ? collector.route : 'NONE' }} | - {{ collector.format }} - | {{ collector.statuscode }} - | - {{ collector.contenttype }} {% endspaceless %} {% endset %} - {% include 'WebProfiler:Profiler:toolbar_item.html.twig' with { 'link': profiler_url } %} + {% include 'WebProfilerBundle:Profiler:toolbar_item.html.twig' with { 'link': profiler_url } %} {% endblock %} {% block menu %} @@ -38,7 +34,7 @@

    Request GET Parameters

    {% if collector.requestquery.all|length %} - {% include 'WebProfiler:Profiler:bag.html.twig' with { 'bag': collector.requestquery } only %} + {% include 'WebProfilerBundle:Profiler:bag.html.twig' with { 'bag': collector.requestquery } only %} {% else %}

    No GET parameters @@ -48,7 +44,7 @@

    Request POST Parameters

    {% if collector.requestrequest.all|length %} - {% include 'WebProfiler:Profiler:bag.html.twig' with { 'bag': collector.requestrequest } only %} + {% include 'WebProfilerBundle:Profiler:bag.html.twig' with { 'bag': collector.requestrequest } only %} {% else %}

    No POST parameters @@ -58,7 +54,7 @@

    Request Attributes

    {% if collector.requestattributes.all|length %} - {% include 'WebProfiler:Profiler:bag.html.twig' with { 'bag': collector.requestattributes } only %} + {% include 'WebProfilerBundle:Profiler:bag.html.twig' with { 'bag': collector.requestattributes } only %} {% else %}

    No attributes @@ -68,7 +64,7 @@

    Request Cookies

    {% if collector.requestcookies.all|length %} - {% include 'WebProfiler:Profiler:bag.html.twig' with { 'bag': collector.requestcookies } only %} + {% include 'WebProfilerBundle:Profiler:bag.html.twig' with { 'bag': collector.requestcookies } only %} {% else %}

    No cookies @@ -77,15 +73,27 @@

    Request Headers

    - {% include 'WebProfiler:Profiler:bag.html.twig' with { 'bag': collector.requestheaders } only %} + {% include 'WebProfilerBundle:Profiler:bag.html.twig' with { 'bag': collector.requestheaders } only %} + +

    Request Content

    + +

    + {% if collector.content == false %} + Request content not available (it was retrieved as a resource). + {% elseif collector.content %} +

    {{ collector.content }}
    + {% else %} + No content + {% endif %} +

    Request Server Parameters

    - {% include 'WebProfiler:Profiler:bag.html.twig' with { 'bag': collector.requestserver } only %} + {% include 'WebProfilerBundle:Profiler:bag.html.twig' with { 'bag': collector.requestserver } only %}

    Response Headers

    - {% include 'WebProfiler:Profiler:bag.html.twig' with { 'bag': collector.responseheaders } only %} + {% include 'WebProfilerBundle:Profiler:bag.html.twig' with { 'bag': collector.responseheaders } only %}

    Session Attributes

    @@ -113,7 +121,7 @@ {% if profiler.parent %}

    Parent request: {{ profiler.parent }}

    - {% include 'WebProfiler:Profiler:bag.html.twig' with { 'bag': profiler.parenttoken.get('request').requestattributes } only %} + {% include 'WebProfilerBundle:Profiler:bag.html.twig' with { 'bag': profiler.parenttoken.get('request').requestattributes } only %} {% endif %} {% if profiler.children|length %} @@ -121,7 +129,7 @@ {% for subrequest in profiler.children %}

    {{ subrequest.token }}

    - {% include 'WebProfiler:Profiler:bag.html.twig' with { 'bag': subrequest.get('request').requestattributes } only %} + {% include 'WebProfilerBundle:Profiler:bag.html.twig' with { 'bag': subrequest.get('request').requestattributes } only %} {% endfor %} {% endif %} diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/timer.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/timer.html.twig index 9c39a315a9..bc734ad3d3 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/timer.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/timer.html.twig @@ -1,4 +1,4 @@ -{% extends 'WebProfiler:Profiler:layout.html.twig' %} +{% extends 'WebProfilerBundle:Profiler:layout.html.twig' %} {% block toolbar %} {% set icon %} @@ -7,5 +7,5 @@ {% set text %} {{ '%.0f'|format(collector.time * 1000) }} ms {% endset %} - {% include 'WebProfiler:Profiler:toolbar_item.html.twig' with { 'link': false } %} + {% include 'WebProfilerBundle:Profiler:toolbar_item.html.twig' with { 'link': false } %} {% endblock %} diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/admin.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/admin.html.twig index d5cc534f18..c266ba3ff8 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/admin.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/admin.html.twig @@ -16,7 +16,7 @@ diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig index 507683abfc..99c9d22f49 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig @@ -1,11 +1,11 @@ -{% extends 'WebProfiler:Profiler:base.html.twig' %} +{% extends 'WebProfilerBundle:Profiler:base.html.twig' %} {% block body %} - {% render 'WebProfiler:Profiler:toolbar' with { 'token': token, 'position': 'normal' } %} + {% render 'WebProfilerBundle:Profiler:toolbar' with { 'token': token, 'position': 'normal' } %}
    - {% include 'WebProfiler:Profiler:header.html.twig' only %} + {% include 'WebProfilerBundle:Profiler:header.html.twig' only %} {% if not profiler.isempty %}
    @@ -39,8 +39,8 @@ {% endfor %}
{% endif %} - {% render 'WebProfiler:Profiler:searchBar' %} - {% include 'WebProfiler:Profiler:admin.html.twig' with { 'token': token } only %} + {% render 'WebProfilerBundle:Profiler:searchBar' %} + {% include 'WebProfilerBundle:Profiler:admin.html.twig' with { 'token': token } only %} diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/notfound.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/notfound.html.twig index 73eae6ae7e..ad3f1b4c8b 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/notfound.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/notfound.html.twig @@ -1,8 +1,8 @@ -{% extends 'WebProfiler:Profiler:base.html.twig' %} +{% extends 'WebProfilerBundle:Profiler:base.html.twig' %} {% block body %}
- {% include 'WebProfiler:Profiler:header.html.twig' only %} + {% include 'WebProfilerBundle:Profiler:header.html.twig' only %}

@@ -23,8 +23,8 @@

diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/results.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/results.html.twig index c3b6ae0e3d..b71ece6158 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/results.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/results.html.twig @@ -1,4 +1,4 @@ -{% extends 'WebProfiler:Profiler:layout.html.twig' %} +{% extends 'WebProfilerBundle:Profiler:layout.html.twig' %} {% block panel %}

Search Results

diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/search.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/search.html.twig index 346fa175c9..ef94237b28 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/search.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/search.html.twig @@ -23,7 +23,7 @@ diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.html.twig index dfeaee986a..e9d6caca3e 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.html.twig @@ -25,7 +25,14 @@   {% for name, template in templates %} - {{ template.renderblock('toolbar', { 'collector': profiler.get(name), 'profiler_url': profiler_url, 'token': profiler.token, 'name': name }) }} + {{ template.renderblock('toolbar', { + 'collector': profiler.get(name), + 'profiler_url': profiler_url, + 'token': profiler.token, + 'name': name, + 'verbose': verbose + }) + }} {% endfor %} {% if 'normal' != position %} diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_redirect.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_redirect.html.twig index e607b09345..013723edf6 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_redirect.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_redirect.html.twig @@ -1,10 +1,18 @@ - - - - Redirection Intercepted - - -

This Request redirects to
{{ location }}.

-

The redirect was intercepted by the web debug toolbar to help debugging.
For more information, see the "intercept-redirects" option of the Profiler.

- - +{% extends 'FrameworkBundle::layout.html.twig' %} + +{% block title 'Redirection Intercepted' %} + +{% block body %} +
+
+

This request redirects to {{ location }}.

+ +

+ + The redirect was intercepted by the web debug toolbar to help debugging. + For more information, see the "intercept-redirects" option of the Profiler. + +

+
+
+{% endblock %} diff --git a/src/Symfony/Bundle/WebProfilerBundle/WebDebugToolbarListener.php b/src/Symfony/Bundle/WebProfilerBundle/WebDebugToolbarListener.php index 1caf38c84e..5b68986bc2 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/WebDebugToolbarListener.php +++ b/src/Symfony/Bundle/WebProfilerBundle/WebDebugToolbarListener.php @@ -32,11 +32,18 @@ class WebDebugToolbarListener { protected $templating; protected $interceptRedirects; + protected $verbose; - public function __construct(TwigEngine $templating, $interceptRedirects = false) + public function __construct(TwigEngine $templating, $interceptRedirects = false, $verbose = true) { $this->templating = $templating; - $this->interceptRedirects = $interceptRedirects; + $this->interceptRedirects = (Boolean) $interceptRedirects; + $this->verbose = (Boolean) $verbose; + } + + public function getVerbose() + { + return $this->verbose; } public function onCoreResponse(FilterResponseEvent $event) @@ -48,11 +55,18 @@ class WebDebugToolbarListener $response = $event->getResponse(); $request = $event->getRequest(); - if ($response->headers->has('X-Debug-Token') && $response->isRedirect() && $this->interceptRedirects) { - // keep current flashes for one more request - $request->getSession()->setFlashes($request->getSession()->getFlashes()); + // do not capture redirects or modify XML HTTP Requests + if ($request->isXmlHttpRequest()) { + return; + } - $response->setContent($this->templating->render('WebProfiler:Profiler:toolbar_redirect.html.twig', array('location' => $response->headers->get('Location')))); + if ($response->headers->has('X-Debug-Token') && $response->isRedirect() && $this->interceptRedirects) { + if (null !== $session = $request->getSession()) { + // keep current flashes for one more request + $session->setFlashes($session->getFlashes()); + } + + $response->setContent($this->templating->render('WebProfilerBundle:Profiler:toolbar_redirect.html.twig', array('location' => $response->headers->get('Location')))); $response->setStatusCode(200); $response->headers->remove('Location'); } @@ -61,7 +75,6 @@ class WebDebugToolbarListener || '3' === substr($response->getStatusCode(), 0, 1) || ($response->headers->has('Content-Type') && false === strpos($response->headers->get('Content-Type'), 'html')) || 'html' !== $request->getRequestFormat() - || $request->isXmlHttpRequest() ) { return; } @@ -87,7 +100,10 @@ class WebDebugToolbarListener $content = $response->getContent(); if (false !== $pos = $posrFunction($content, '')) { - $toolbar = "\n".str_replace("\n", '', $this->templating->render('WebProfiler:Profiler:toolbar_js.html.twig', array('token' => $response->headers->get('X-Debug-Token'))))."\n"; + $toolbar = "\n".str_replace("\n", '', $this->templating->render( + 'WebProfilerBundle:Profiler:toolbar_js.html.twig', + array('token' => $response->headers->get('X-Debug-Token')) + ))."\n"; $content = $substrFunction($content, 0, $pos).$toolbar.$substrFunction($content, $pos); $response->setContent($content); } diff --git a/src/Symfony/Bundle/ZendBundle/DependencyInjection/Compiler/ZendLoggerWriterPass.php b/src/Symfony/Bundle/ZendBundle/DependencyInjection/Compiler/ZendLoggerWriterPass.php deleted file mode 100644 index 6bfedcfbfa..0000000000 --- a/src/Symfony/Bundle/ZendBundle/DependencyInjection/Compiler/ZendLoggerWriterPass.php +++ /dev/null @@ -1,37 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\ZendBundle\DependencyInjection\Compiler; - -use Symfony\Component\DependencyInjection\Reference; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; - -/** - * Adds tagged zend.logger.writer services to zend.logger service - * - * @author Fabien Potencier - */ -class ZendLoggerWriterPass implements CompilerPassInterface -{ - public function process(ContainerBuilder $container) - { - if (false === $container->hasDefinition('zend.logger')) { - return; - } - - $definition = $container->getDefinition('zend.logger'); - - foreach ($container->findTaggedServiceIds('zend.logger.writer') as $id => $attributes) { - $definition->addMethodCall('addWriter', array(new Reference($id))); - } - } -} diff --git a/src/Symfony/Bundle/ZendBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/ZendBundle/DependencyInjection/Configuration.php deleted file mode 100644 index 41e5b1db1f..0000000000 --- a/src/Symfony/Bundle/ZendBundle/DependencyInjection/Configuration.php +++ /dev/null @@ -1,52 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\ZendBundle\DependencyInjection; - -use Symfony\Component\Config\Definition\Builder\TreeBuilder; - -/** - * This class contains the configuration information for the bundle - * - * This information is solely responsible for how the different configuration - * sections are normalized, and merged. - * - * @author Christophe Coevoet - */ -class Configuration -{ - /** - * Generates the configuration tree. - * - * @return \Symfony\Component\Config\Definition\ArrayNode The config tree - */ - public function getConfigTree() - { - $treeBuilder = new TreeBuilder(); - $rootNode = $treeBuilder->root('zend'); - - $rootNode - ->children() - ->arrayNode('logger') - ->canBeUnset() - ->children() - ->scalarNode('priority')->defaultValue('INFO')->end() - ->scalarNode('path')->defaultValue('%kernel.logs_dir%/%kernel.environment%.log')->end() - ->scalarNode('format')->defaultValue("%%timestamp%% %%priorityName%%: %%message%%\n")->end() - ->booleanNode('log_errors')->defaultFalse()->end() - ->end() - ->end() - ->end() - ; - - return $treeBuilder->buildTree(); - } -} diff --git a/src/Symfony/Bundle/ZendBundle/DependencyInjection/ZendExtension.php b/src/Symfony/Bundle/ZendBundle/DependencyInjection/ZendExtension.php deleted file mode 100644 index df9aab0cc8..0000000000 --- a/src/Symfony/Bundle/ZendBundle/DependencyInjection/ZendExtension.php +++ /dev/null @@ -1,93 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\ZendBundle\DependencyInjection; - -use Symfony\Component\HttpKernel\DependencyInjection\Extension; -use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\Config\FileLocator; -use Symfony\Component\Config\Definition\Processor; - -/** - * ZendExtension is an extension for the Zend Framework libraries. - * - * @author Fabien Potencier - */ -class ZendExtension extends Extension -{ - /** - * Loads the Zend Framework configuration. - * - * Usage example: - * - * - * - * - * - * @param array $config An array of configuration settings - * @param ContainerBuilder $container A ContainerBuilder instance - */ - public function load(array $configs, ContainerBuilder $container) - { - $configuration = new Configuration(); - $processor = new Processor(); - $config = $processor->process($configuration->getConfigTree(), $configs); - - if (isset($config['logger'])) { - $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); - $loader->load('logger.xml'); - $container->setAlias('logger', 'zend.logger'); - - $config = $config['logger']; - - $container->getDefinition('zend.logger.filter')->setArgument(0, is_int($config['priority']) ? $config['priority'] : constant('\\Zend\\Log\\Logger::'.strtoupper($config['priority']))); - $container->getDefinition('zend.logger.writer.filesystem')->setArgument(0, $config['path']); - - $definition = $container->findDefinition('zend.logger'); - if ($config['log_errors']) { - $container->findDefinition('zend.logger')->addMethodCall('registerErrorHandler'); - } - - $container->getDefinition('zend.formatter.filesystem')->setArgument(0, $config['format']); - - $this->addClassesToCompile(array( - 'Zend\\Log\\Factory', - 'Zend\\Log\\Filter', - 'Zend\\Log\\Filter\\AbstractFilter', - 'Zend\\Log\\Filter\\Priority', - 'Zend\\Log\\Formatter', - 'Zend\\Log\\Formatter\\Simple', - 'Zend\\Log\\Logger', - 'Zend\\Log\\Writer', - 'Zend\\Log\\Writer\\AbstractWriter', - 'Zend\\Log\\Writer\\Stream', - 'Symfony\\Bundle\\ZendBundle\\Logger\\DebugLogger', - 'Symfony\\Bundle\\ZendBundle\\Logger\\Logger', - )); - } - } - - /** - * Returns the base path for the XSD files. - * - * @return string The XSD base path - */ - public function getXsdValidationBasePath() - { - return __DIR__.'/../Resources/config/schema'; - } - - public function getNamespace() - { - return 'http://symfony.com/schema/dic/zend'; - } -} diff --git a/src/Symfony/Bundle/ZendBundle/Logger/DebugLogger.php b/src/Symfony/Bundle/ZendBundle/Logger/DebugLogger.php deleted file mode 100644 index 59674b12d0..0000000000 --- a/src/Symfony/Bundle/ZendBundle/Logger/DebugLogger.php +++ /dev/null @@ -1,62 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\ZendBundle\Logger; - -use Zend\Log\Writer\AbstractWriter; -use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; - -/** - * DebugLogger. - * - * @author Fabien Potencier - */ -class DebugLogger extends AbstractWriter implements DebugLoggerInterface -{ - protected $logs = array(); - - /** - * {@inheritdoc} - */ - public function getLogs() - { - return $this->logs; - } - - /** - * {@inheritdoc} - */ - public function countErrors() - { - $count = 0; - foreach ($this->getLogs() as $log) { - if ('ERR' === $log['priorityName']) { - ++$count; - } - } - - return $count; - } - - /** - * Write a message to the log. - * - * @param array $event Event data - */ - protected function _write($event) - { - $this->logs[] = $event; - } - - static public function factory($config = array()) - { - } -} diff --git a/src/Symfony/Bundle/ZendBundle/Logger/Logger.php b/src/Symfony/Bundle/ZendBundle/Logger/Logger.php deleted file mode 100644 index e54d1994d9..0000000000 --- a/src/Symfony/Bundle/ZendBundle/Logger/Logger.php +++ /dev/null @@ -1,80 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\ZendBundle\Logger; - -use Zend\Log\Logger as BaseLogger; -use Symfony\Component\HttpKernel\Log\LoggerInterface; -use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; - -/** - * Logger. - * - * @author Fabien Potencier - */ -class Logger extends BaseLogger implements LoggerInterface -{ - /** - * Returns a DebugLoggerInterface instance if one is registered with this logger. - * - * @return DebugLoggerInterface A DebugLoggerInterface instance or null if none is registered - */ - public function getDebugLogger() - { - foreach ($this->_writers as $writer) { - if ($writer instanceof DebugLoggerInterface) { - return $writer; - } - } - - return null; - } - - public function emerg($message) - { - return parent::log($message, 0); - } - - public function alert($message) - { - return parent::log($message, 1); - } - - public function crit($message) - { - return parent::log($message, 2); - } - - public function err($message) - { - return parent::log($message, 3); - } - - public function warn($message) - { - return parent::log($message, 4); - } - - public function notice($message) - { - return parent::log($message, 5); - } - - public function info($message) - { - return parent::log($message, 6); - } - - public function debug($message) - { - return parent::log($message, 7); - } -} diff --git a/src/Symfony/Bundle/ZendBundle/Resources/config/logger.xml b/src/Symfony/Bundle/ZendBundle/Resources/config/logger.xml deleted file mode 100644 index f10fd5c8de..0000000000 --- a/src/Symfony/Bundle/ZendBundle/Resources/config/logger.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - Symfony\Bundle\ZendBundle\Logger\Logger - Symfony\Bundle\ZendBundle\Logger\DebugLogger - Zend\Log\Writer\Stream - Zend\Log\Formatter\Simple - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Symfony/Bundle/ZendBundle/Resources/config/schema/zend-1.0.xsd b/src/Symfony/Bundle/ZendBundle/Resources/config/schema/zend-1.0.xsd deleted file mode 100644 index 354043e4ee..0000000000 --- a/src/Symfony/Bundle/ZendBundle/Resources/config/schema/zend-1.0.xsd +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Symfony/Component/BrowserKit/Client.php b/src/Symfony/Component/BrowserKit/Client.php index 07b8f93690..bf8a14efd6 100644 --- a/src/Symfony/Component/BrowserKit/Client.php +++ b/src/Symfony/Component/BrowserKit/Client.php @@ -108,6 +108,29 @@ abstract class Client ), $server); } + /** + * Sets single server parameter. + * + * @param string $key A key of the parameter + * @param string $value A value of the parameter + */ + public function setServerParameter($key, $value) + { + $this->server[$key] = $value; + } + + /** + * Gets single server parameter for specified key. + * + * @param string $key A key of the parameter to get + * @param string $default A default value when key is undefined + * @return string A value of the parameter + */ + public function getServerParameter($key, $default = '') + { + return (isset($this->server[$key])) ? $this->server[$key] : $default; + } + /** * Returns the History instance. * diff --git a/src/Symfony/Component/Config/Definition/BaseNode.php b/src/Symfony/Component/Config/Definition/BaseNode.php index d8c51ac66c..4ba29a6aa3 100644 --- a/src/Symfony/Component/Config/Definition/BaseNode.php +++ b/src/Symfony/Component/Config/Definition/BaseNode.php @@ -56,8 +56,8 @@ abstract class BaseNode implements NodeInterface /** * Adds an equivalent value. * - * @param mixed $originalValue - * @param mixed $equivalentValue + * @param mixed $originalValue + * @param mixed $equivalentValue */ public function addEquivalentValue($originalValue, $equivalentValue) { @@ -143,8 +143,8 @@ abstract class BaseNode implements NodeInterface /** * Merges two values together. * - * @param mixed $leftSide - * @param mixed $rightSide + * @param mixed $leftSide + * @param mixed $rightSide * @return mixed The merged value * @throws ForbiddenOverwriteException */ @@ -196,7 +196,7 @@ abstract class BaseNode implements NodeInterface /** * Finalizes a value, applying all finalization closures. * - * @param mixed $value The value to finalize + * @param mixed $value The value to finalize * @return mixed The finalized value */ public final function finalize($value) @@ -231,7 +231,7 @@ abstract class BaseNode implements NodeInterface * @throws InvalidTypeException when the value is invalid */ abstract protected function validateType($value); - + /** * Normalizes the value. * @@ -239,16 +239,16 @@ abstract class BaseNode implements NodeInterface * @return mixed The normalized value */ abstract protected function normalizeValue($value); - + /** * Merges two values together * - * @param mixed $leftSide - * @param mixed $rightSide + * @param mixed $leftSide + * @param mixed $rightSide * @return mixed The merged value */ abstract protected function mergeValues($leftSide, $rightSide); - + /** * Finalizes a value * diff --git a/src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php b/src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php index ca1712f853..bede6e991b 100644 --- a/src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php +++ b/src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php @@ -97,7 +97,7 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition return $this; } - + /** * Requires the node to have at least one element. * @@ -238,7 +238,7 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition /** * Returns a node builder to be used to add children and protoype - * + * * @return NodeBuilder The node builder */ protected function getNodeBuilder() diff --git a/src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php b/src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php index c6eb376224..ca8d222ef2 100644 --- a/src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php +++ b/src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php @@ -96,7 +96,7 @@ class NodeBuilder implements NodeParentInterface { return $this->node($name, 'variable'); } - + /** * Returns the parent node. * @@ -154,9 +154,9 @@ class NodeBuilder implements NodeParentInterface /** * Returns the class name of the node definition - * + * * @param string $type The node type - * + * * @return string The node definition class name * * @throws \RuntimeException When the node type is not registered diff --git a/src/Symfony/Component/Config/Definition/Builder/NodeParentInterface.php b/src/Symfony/Component/Config/Definition/Builder/NodeParentInterface.php index ca2f5a8148..24f397193e 100644 --- a/src/Symfony/Component/Config/Definition/Builder/NodeParentInterface.php +++ b/src/Symfony/Component/Config/Definition/Builder/NodeParentInterface.php @@ -19,4 +19,3 @@ namespace Symfony\Component\Config\Definition\Builder; interface NodeParentInterface { } - \ No newline at end of file diff --git a/src/Symfony/Component/Config/Definition/Builder/ParentNodeDefinitionInterface.php b/src/Symfony/Component/Config/Definition/Builder/ParentNodeDefinitionInterface.php index a67ed52701..2d95954239 100644 --- a/src/Symfony/Component/Config/Definition/Builder/ParentNodeDefinitionInterface.php +++ b/src/Symfony/Component/Config/Definition/Builder/ParentNodeDefinitionInterface.php @@ -24,4 +24,3 @@ interface ParentNodeDefinitionInterface function setBuilder(NodeBuilder $builder); } - \ No newline at end of file diff --git a/src/Symfony/Component/Config/Definition/Builder/TreeBuilder.php b/src/Symfony/Component/Config/Definition/Builder/TreeBuilder.php index 047235081c..3c1362a8d1 100644 --- a/src/Symfony/Component/Config/Definition/Builder/TreeBuilder.php +++ b/src/Symfony/Component/Config/Definition/Builder/TreeBuilder.php @@ -24,7 +24,7 @@ class TreeBuilder implements NodeParentInterface /** * Creates the root node. - * + * * @param string $name The name of the root node * @param string $type The type of the root node * @param NodeBuilder $builder A custom node builder instance @@ -36,7 +36,7 @@ class TreeBuilder implements NodeParentInterface public function root($name, $type = 'array', NodeBuilder $builder = null) { $builder = null === $builder ? new NodeBuilder() : $builder; - + $this->root = $builder->node($name, $type); $this->root->setParent($this); @@ -56,7 +56,7 @@ class TreeBuilder implements NodeParentInterface if (null !== $this->tree) { return $this->tree; } - + return $this->tree = $this->root->getNode(true); } } \ No newline at end of file diff --git a/src/Symfony/Component/Config/Definition/Builder/VariableNodeDefinition.php b/src/Symfony/Component/Config/Definition/Builder/VariableNodeDefinition.php index f9439fbdb2..f7da120661 100644 --- a/src/Symfony/Component/Config/Definition/Builder/VariableNodeDefinition.php +++ b/src/Symfony/Component/Config/Definition/Builder/VariableNodeDefinition.php @@ -37,7 +37,7 @@ class VariableNodeDefinition extends NodeDefinition protected function createNode() { $node = $this->instantiateNode(); - + if (null !== $this->normalization) { $node->setNormalizationClosures($this->normalization->before); } @@ -65,5 +65,5 @@ class VariableNodeDefinition extends NodeDefinition return $node; } - + } \ No newline at end of file diff --git a/src/Symfony/Component/Config/Definition/ConfigurationInterface.php b/src/Symfony/Component/Config/Definition/ConfigurationInterface.php new file mode 100644 index 0000000000..9d0a049246 --- /dev/null +++ b/src/Symfony/Component/Config/Definition/ConfigurationInterface.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition; + +/** + * Configuration interface + * + * @author Victor Berchet + */ +interface ConfigurationInterface +{ + /** + * Generates the configuration tree builder. + * + * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder + */ + function getConfigTreeBuilder(); +} \ No newline at end of file diff --git a/src/Symfony/Component/Config/Definition/NodeInterface.php b/src/Symfony/Component/Config/Definition/NodeInterface.php index 33d53feb99..74f50aed58 100644 --- a/src/Symfony/Component/Config/Definition/NodeInterface.php +++ b/src/Symfony/Component/Config/Definition/NodeInterface.php @@ -34,21 +34,21 @@ interface NodeInterface * @return string The node path */ function getPath(); - + /** * Returns true when the node is required. * * @return Boolean If the node is required */ function isRequired(); - + /** * Returns true when the node has a default value. * * @return Boolean If the node has a default value */ function hasDefaultValue(); - + /** * Returns the default value of the node. * @@ -56,7 +56,7 @@ interface NodeInterface * @throws \RuntimeException if the node has no default value */ function getDefaultValue(); - + /** * Normalizes the supplied value. * @@ -64,16 +64,16 @@ interface NodeInterface * @return mixed The normalized value */ function normalize($value); - + /** * Merges two values together. * - * @param mixed $leftSide - * @param mixed $rightSide + * @param mixed $leftSide + * @param mixed $rightSide * @return mixed The merged values */ function merge($leftSide, $rightSide); - + /** * Finalizes a value. * diff --git a/src/Symfony/Component/Config/Definition/Processor.php b/src/Symfony/Component/Config/Definition/Processor.php index 2a2e3e050e..42a184e61c 100644 --- a/src/Symfony/Component/Config/Definition/Processor.php +++ b/src/Symfony/Component/Config/Definition/Processor.php @@ -19,11 +19,12 @@ namespace Symfony\Component\Config\Definition; class Processor { /** - * Processes a node tree. + * Processes an array of configurations. * - * @param NodeInterface $configTree The node tree to process - * @param array $configs An array of configuration items - * @return Boolean + * @param NodeInterface $configTree The node tree describing the configuration + * @param array $configs An array of configuration items to process + * + * @return array The processed configuration */ public function process(NodeInterface $configTree, array $configs) { @@ -38,6 +39,19 @@ class Processor return $configTree->finalize($currentConfig); } + /** + * Processes an array of configurations. + * + * @param ConfigurationInterface $configuration The configuration class + * @param array $configs An array of configuration items to process + * + * @return array The processed configuration + */ + public function processConfiguration(ConfigurationInterface $configuration, array $configs) + { + return $this->process($configuration->getConfigTreeBuilder()->buildTree(), $configs); + } + /** * This method normalizes keys between the different configuration formats * diff --git a/src/Symfony/Component/Config/Definition/PrototypedArrayNode.php b/src/Symfony/Component/Config/Definition/PrototypedArrayNode.php index 14d4ed9fce..64048c22ad 100644 --- a/src/Symfony/Component/Config/Definition/PrototypedArrayNode.php +++ b/src/Symfony/Component/Config/Definition/PrototypedArrayNode.php @@ -194,6 +194,11 @@ class PrototypedArrayNode extends ArrayNode if ($this->removeKeyAttribute) { unset($v[$this->keyAttribute]); } + + // if only "value" is left + if (1 == count($v) && isset($v['value'])) { + $v = $v['value']; + } } if (array_key_exists($k, $normalized)) { diff --git a/src/Symfony/Component/Config/Loader/Loader.php b/src/Symfony/Component/Config/Loader/Loader.php index 584b7b3734..f02110c28e 100644 --- a/src/Symfony/Component/Config/Loader/Loader.php +++ b/src/Symfony/Component/Config/Loader/Loader.php @@ -63,7 +63,7 @@ abstract class Loader implements LoaderInterface */ public function resolve($resource, $type = null) { - + if ($this->supports($resource, $type)) { return $this; } @@ -76,5 +76,5 @@ abstract class Loader implements LoaderInterface return $loader; } - + } diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index 9e88575a54..1ad936321a 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -759,7 +759,7 @@ class Application * Gets the name of the command based on input. * * @param InputInterface $input The input interface - * + * * @return string The command name */ protected function getCommandName(InputInterface $input) diff --git a/src/Symfony/Component/CssSelector/Node/ClassNode.php b/src/Symfony/Component/CssSelector/Node/ClassNode.php index 10950f90b7..b54d2f1539 100644 --- a/src/Symfony/Component/CssSelector/Node/ClassNode.php +++ b/src/Symfony/Component/CssSelector/Node/ClassNode.php @@ -39,7 +39,7 @@ class ClassNode implements NodeInterface } /** - * {@inheritDoc} + * {@inheritDoc} */ public function __toString() { diff --git a/src/Symfony/Component/CssSelector/Node/ElementNode.php b/src/Symfony/Component/CssSelector/Node/ElementNode.php index 97c96f7a9d..37e8ce0f61 100644 --- a/src/Symfony/Component/CssSelector/Node/ElementNode.php +++ b/src/Symfony/Component/CssSelector/Node/ElementNode.php @@ -31,7 +31,7 @@ class ElementNode implements NodeInterface * * @param string $namespace Namespace * @param string $element Element - */ + */ public function __construct($namespace, $element) { $this->namespace = $namespace; diff --git a/src/Symfony/Component/CssSelector/Node/FunctionNode.php b/src/Symfony/Component/CssSelector/Node/FunctionNode.php index 6a1bdbcbc4..c8b0b76a59 100644 --- a/src/Symfony/Component/CssSelector/Node/FunctionNode.php +++ b/src/Symfony/Component/CssSelector/Node/FunctionNode.php @@ -37,7 +37,7 @@ class FunctionNode implements NodeInterface * @param NodeInterface $selector The XPath expression * @param string $type * @param string $name - * @param XPathExpr $expr + * @param XPathExpr $expr */ public function __construct($selector, $type, $name, $expr) { @@ -76,10 +76,10 @@ class FunctionNode implements NodeInterface /** * undocumented function * - * @param XPathExpr $xpath - * @param mixed $expr - * @param string $last - * @param string $addNameTest + * @param XPathExpr $xpath + * @param mixed $expr + * @param string $last + * @param string $addNameTest * @return XPathExpr */ protected function _xpath_nth_child($xpath, $expr, $last = false, $addNameTest = true) @@ -148,8 +148,8 @@ class FunctionNode implements NodeInterface /** * undocumented function * - * @param XPathExpr $xpath - * @param XPathExpr $expr + * @param XPathExpr $xpath + * @param XPathExpr $expr * @return XPathExpr */ protected function _xpath_nth_last_child($xpath, $expr) @@ -160,8 +160,8 @@ class FunctionNode implements NodeInterface /** * undocumented function * - * @param XPathExpr $xpath - * @param XPathExpr $expr + * @param XPathExpr $xpath + * @param XPathExpr $expr * @return XPathExpr */ protected function _xpath_nth_of_type($xpath, $expr) @@ -176,8 +176,8 @@ class FunctionNode implements NodeInterface /** * undocumented function * - * @param XPathExpr $xpath - * @param XPathExpr $expr + * @param XPathExpr $xpath + * @param XPathExpr $expr * @return XPathExpr */ protected function _xpath_nth_last_of_type($xpath, $expr) @@ -188,8 +188,8 @@ class FunctionNode implements NodeInterface /** * undocumented function * - * @param XPathExpr $xpath - * @param XPathExpr $expr + * @param XPathExpr $xpath + * @param XPathExpr $expr * @return XPathExpr */ protected function _xpath_contains($xpath, $expr) @@ -211,8 +211,8 @@ class FunctionNode implements NodeInterface /** * undocumented function * - * @param XPathExpr $xpath - * @param XPathExpr $expr + * @param XPathExpr $xpath + * @param XPathExpr $expr * @return XPathExpr */ protected function _xpath_not($xpath, $expr) @@ -229,7 +229,7 @@ class FunctionNode implements NodeInterface /** * Parses things like '1n+2', or 'an+b' generally, returning (a, b) * - * @param mixed $s + * @param mixed $s * @return array */ protected function parseSeries($s) diff --git a/src/Symfony/Component/CssSelector/Node/HashNode.php b/src/Symfony/Component/CssSelector/Node/HashNode.php index 9507277c8c..54d51ee045 100644 --- a/src/Symfony/Component/CssSelector/Node/HashNode.php +++ b/src/Symfony/Component/CssSelector/Node/HashNode.php @@ -38,7 +38,7 @@ class HashNode implements NodeInterface $this->id = $id; } - /** + /** * {@inheritDoc} */ public function __toString() diff --git a/src/Symfony/Component/CssSelector/Node/PseudoNode.php b/src/Symfony/Component/CssSelector/Node/PseudoNode.php index f1988c7092..d15f0e5289 100644 --- a/src/Symfony/Component/CssSelector/Node/PseudoNode.php +++ b/src/Symfony/Component/CssSelector/Node/PseudoNode.php @@ -119,7 +119,7 @@ class PseudoNode implements NodeInterface return $xpath; } - /** + /** * Sets the XPath to be the last child. * * @param XPathExpr $xpath The XPath expression diff --git a/src/Symfony/Component/DependencyInjection/Alias.php b/src/Symfony/Component/DependencyInjection/Alias.php index 76e7624a91..c6aa80c069 100644 --- a/src/Symfony/Component/DependencyInjection/Alias.php +++ b/src/Symfony/Component/DependencyInjection/Alias.php @@ -31,7 +31,7 @@ class Alias /** * Checks if this DI Alias should be public or not. * - * @return boolean + * @return boolean */ public function isPublic() { diff --git a/src/Symfony/Component/DependencyInjection/Compiler/CheckDefinitionValidityPass.php b/src/Symfony/Component/DependencyInjection/Compiler/CheckDefinitionValidityPass.php index 928ef081d5..547e11c3ee 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/CheckDefinitionValidityPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/CheckDefinitionValidityPass.php @@ -23,7 +23,7 @@ class CheckDefinitionValidityPass implements CompilerPassInterface /** * Processes the ContainerBuilder to validate the Definition. * - * @param ContainerBuilder $container + * @param ContainerBuilder $container * @throws \RuntimeException When the Definition is invalid */ public function process(ContainerBuilder $container) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php b/src/Symfony/Component/DependencyInjection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php new file mode 100644 index 0000000000..55bef03c10 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php @@ -0,0 +1,55 @@ + + */ +class CheckExceptionOnInvalidReferenceBehaviorPass implements CompilerPassInterface +{ + private $container; + private $sourceId; + + public function process(ContainerBuilder $container) + { + $this->container = $container; + + foreach ($container->getDefinitions() as $id => $definition) { + $this->sourceId = $id; + $this->processDefinition($definition); + } + } + + private function processDefinition(Definition $definition) + { + $this->processReferences($definition->getArguments()); + $this->processReferences($definition->getMethodCalls()); + $this->processReferences($definition->getProperties()); + } + + private function processReferences(array $arguments) + { + foreach ($arguments as $argument) { + if (is_array($argument)) { + $this->processReferences($argument); + } else if ($argument instanceof Definition) { + $this->processDefinition($argument); + } else if ($argument instanceof Reference && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE === $argument->getInvalidBehavior()) { + $destId = (string) $argument; + + if (!$this->container->has($destId)) { + throw new NonExistentServiceException($destId, $this->sourceId); + } + } + } + } +} \ No newline at end of file diff --git a/src/Symfony/Component/DependencyInjection/Compiler/Compiler.php b/src/Symfony/Component/DependencyInjection/Compiler/Compiler.php index bf41c8470d..9158d41f68 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/Compiler.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/Compiler.php @@ -22,9 +22,8 @@ use Symfony\Component\DependencyInjection\Compiler\PassConfig; class Compiler { private $passConfig; - private $currentPass; - private $currentStartTime; private $log; + private $loggingFormatter; private $serviceReferenceGraph; /** @@ -34,6 +33,7 @@ class Compiler { $this->passConfig = new PassConfig(); $this->serviceReferenceGraph = new ServiceReferenceGraph(); + $this->loggingFormatter = new LoggingFormatter(); $this->log = array(); } @@ -57,6 +57,16 @@ class Compiler return $this->serviceReferenceGraph; } + /** + * Returns the logging formatter which can be used by compilation passes. + * + * @return LoggingFormatter + */ + public function getLoggingFormatter() + { + return $this->loggingFormatter; + } + /** * Adds a pass to the PassConfig. * @@ -71,7 +81,7 @@ class Compiler /** * Adds a log message. * - * @param string $string The log message + * @param string $string The log message */ public function addLogMessage($string) { @@ -91,36 +101,13 @@ class Compiler /** * Run the Compiler and process all Passes. * - * @param ContainerBuilder $container + * @param ContainerBuilder $container */ public function compile(ContainerBuilder $container) { + $start = microtime(true); foreach ($this->passConfig->getPasses() as $pass) { - $this->startPass($pass); $pass->process($container); - $this->endPass($pass); } } - - /** - * Starts an individual pass. - * - * @param CompilerPassInterface $pass The pass to start - */ - private function startPass(CompilerPassInterface $pass) - { - $this->currentPass = $pass; - $this->currentStartTime = microtime(true); - } - - /** - * Ends an individual pass. - * - * @param CompilerPassInterface $pass The compiler pass - */ - private function endPass(CompilerPassInterface $pass) - { - $this->currentPass = null; - $this->addLogMessage(sprintf('%s finished in %.3fs', get_class($pass), microtime(true) - $this->currentStartTime)); - } } \ No newline at end of file diff --git a/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php index 842a5b3f65..1341745119 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php @@ -25,6 +25,9 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface { private $repeatedPass; private $graph; + private $compiler; + private $formatter; + private $currentId; /** * {@inheritDoc} @@ -41,9 +44,13 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface */ public function process(ContainerBuilder $container) { - $this->graph = $container->getCompiler()->getServiceReferenceGraph(); + $this->compiler = $container->getCompiler(); + $this->formatter = $this->compiler->getLoggingFormatter(); + $this->graph = $this->compiler->getServiceReferenceGraph(); + + foreach ($container->getDefinitions() as $id => $definition) { + $this->currentId = $id; - foreach ($container->getDefinitions() as $definition) { $definition->setArguments( $this->inlineArguments($container, $definition->getArguments()) ); @@ -75,6 +82,8 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface } if ($this->isInlinableDefinition($container, $id, $definition = $container->getDefinition($id))) { + $this->compiler->addLogMessage($this->formatter->formatInlineService($this, $id, $this->currentId)); + if (ContainerInterface::SCOPE_PROTOTYPE !== $definition->getScope()) { $arguments[$k] = $definition; } else { diff --git a/src/Symfony/Component/DependencyInjection/Compiler/LoggingFormatter.php b/src/Symfony/Component/DependencyInjection/Compiler/LoggingFormatter.php new file mode 100644 index 0000000000..af359e5d2c --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Compiler/LoggingFormatter.php @@ -0,0 +1,38 @@ + + */ +class LoggingFormatter +{ + public function formatRemoveService(CompilerPassInterface $pass, $id, $reason) + { + return $this->format($pass, sprintf('Removed service "%s"; reason: %s', $id, $reason)); + } + + public function formatInlineService(CompilerPassInterface $pass, $id, $target) + { + return $this->format($pass, sprintf('Inlined service "%s" to "%s".', $id, $target)); + } + + public function formatUpdateReference(CompilerPassInterface $pass, $serviceId, $oldDestId, $newDestId) + { + return $this->format($pass, sprintf('Changed reference of service "%s" previously pointing to "%s" to "%s".', $serviceId, $oldDestId, $newDestId)); + } + + public function formatResolveInheritance(CompilerPassInterface $pass, $childId, $parentId) + { + return $this->format($pass, sprintf('Resolving inheritance for "%s" (parent: %s).', $childId, $parentId)); + } + + public function format(CompilerPassInterface $pass, $message) + { + return sprintf('%s: %s', get_class($pass), $message); + } +} \ No newline at end of file diff --git a/src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php b/src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php index b340c38616..fc48e0b25f 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php @@ -66,6 +66,7 @@ class PassConfig new AnalyzeServiceReferencesPass(), new RemoveUnusedDefinitionsPass(), )), + new CheckExceptionOnInvalidReferenceBehaviorPass(), ); } diff --git a/src/Symfony/Component/DependencyInjection/Compiler/RemoveAbstractDefinitionsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/RemoveAbstractDefinitionsPass.php index 91882ac942..45857a1712 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/RemoveAbstractDefinitionsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/RemoveAbstractDefinitionsPass.php @@ -13,13 +13,17 @@ class RemoveAbstractDefinitionsPass implements CompilerPassInterface /** * Removes abstract definitions from the ContainerBuilder * - * @param ContainerBuilder $container + * @param ContainerBuilder $container */ public function process(ContainerBuilder $container) { + $compiler = $container->getCompiler(); + $formatter = $compiler->getLoggingFormatter(); + foreach ($container->getDefinitions() as $id => $definition) { if ($definition->isAbstract()) { - $container->remove($id); + $container->removeDefinition($id); + $compiler->addLogMessage($formatter->formatRemoveService($this, $id, 'abstract')); } } } diff --git a/src/Symfony/Component/DependencyInjection/Compiler/RemovePrivateAliasesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/RemovePrivateAliasesPass.php index 03fb92afa0..5b7d36289f 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/RemovePrivateAliasesPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/RemovePrivateAliasesPass.php @@ -25,16 +25,20 @@ class RemovePrivateAliasesPass implements CompilerPassInterface /** * Removes private aliases from the ContainerBuilder * - * @param ContainerBuilder $container + * @param ContainerBuilder $container */ public function process(ContainerBuilder $container) { + $compiler = $container->getCompiler(); + $formatter = $compiler->getLoggingFormatter(); + foreach ($container->getAliases() as $id => $alias) { if ($alias->isPublic()) { continue; } $container->removeAlias($id); + $compiler->addLogMessage($formatter->formatRemoveService($this, $id, 'private alias')); } } } \ No newline at end of file diff --git a/src/Symfony/Component/DependencyInjection/Compiler/RemoveUnusedDefinitionsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/RemoveUnusedDefinitionsPass.php index c87e790b72..7c7974e4b1 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/RemoveUnusedDefinitionsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/RemoveUnusedDefinitionsPass.php @@ -36,12 +36,14 @@ class RemoveUnusedDefinitionsPass implements RepeatablePassInterface /** * Processes the ContainerBuilder to remove unused definitions. * - * @param ContainerBuilder $container + * @param ContainerBuilder $container * @return void */ public function process(ContainerBuilder $container) { - $graph = $container->getCompiler()->getServiceReferenceGraph(); + $compiler = $container->getCompiler(); + $formatter = $compiler->getLoggingFormatter(); + $graph = $compiler->getServiceReferenceGraph(); $hasChanged = false; foreach ($container->getDefinitions() as $id => $definition) { @@ -70,9 +72,11 @@ class RemoveUnusedDefinitionsPass implements RepeatablePassInterface if (1 === count($referencingAliases) && false === $isReferenced) { $container->setDefinition((string) reset($referencingAliases), $definition); $definition->setPublic(true); - $container->remove($id); + $container->removeDefinition($id); + $compiler->addLogMessage($formatter->formatRemoveService($this, $id, 'replaces alias '.reset($referencingAliases))); } else if (0 === count($referencingAliases) && false === $isReferenced) { - $container->remove($id); + $container->removeDefinition($id); + $compiler->addLogMessage($formatter->formatRemoveService($this, $id, 'unused')); $hasChanged = true; } } diff --git a/src/Symfony/Component/DependencyInjection/Compiler/RepeatablePassInterface.php b/src/Symfony/Component/DependencyInjection/Compiler/RepeatablePassInterface.php index 43bbdf1ca5..a737052072 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/RepeatablePassInterface.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/RepeatablePassInterface.php @@ -22,7 +22,7 @@ interface RepeatablePassInterface extends CompilerPassInterface /** * Sets the RepeatedPass interface. * - * @param RepeatedPass $repeatedPass + * @param RepeatedPass $repeatedPass */ function setRepeatedPass(RepeatedPass $repeatedPass); } \ No newline at end of file diff --git a/src/Symfony/Component/DependencyInjection/Compiler/RepeatedPass.php b/src/Symfony/Component/DependencyInjection/Compiler/RepeatedPass.php index 4b14337ed6..7ed16bc7ca 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/RepeatedPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/RepeatedPass.php @@ -44,7 +44,7 @@ class RepeatedPass implements CompilerPassInterface /** * Process the repeatable passes that run more than once. * - * @param ContainerBuilder $container + * @param ContainerBuilder $container */ public function process(ContainerBuilder $container) { @@ -53,9 +53,6 @@ class RepeatedPass implements CompilerPassInterface foreach ($this->passes as $pass) { $time = microtime(true); $pass->process($container); - $compiler->addLogMessage(sprintf( - '%s finished in %.3fs', get_class($pass), microtime(true) - $time - )); } if ($this->repeat) { diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ReplaceAliasByActualDefinitionPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ReplaceAliasByActualDefinitionPass.php index 509e9746db..17ccc9fa13 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ReplaceAliasByActualDefinitionPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ReplaceAliasByActualDefinitionPass.php @@ -22,13 +22,20 @@ use Symfony\Component\DependencyInjection\Reference; */ class ReplaceAliasByActualDefinitionPass implements CompilerPassInterface { + private $compiler; + private $formatter; + private $sourceId; + /** * Process the Container to replace aliases with service definitions. * - * @param ContainerBuilder $container + * @param ContainerBuilder $container */ public function process(ContainerBuilder $container) { + $this->compiler = $container->getCompiler(); + $this->formatter = $this->compiler->getLoggingFormatter(); + foreach ($container->getAliases() as $id => $alias) { $aliasId = (string) $alias; @@ -40,7 +47,7 @@ class ReplaceAliasByActualDefinitionPass implements CompilerPassInterface $definition->setPublic(true); $container->setDefinition($id, $definition); - $container->remove($aliasId); + $container->removeDefinition($aliasId); $this->updateReferences($container, $aliasId, $id); @@ -67,7 +74,9 @@ class ReplaceAliasByActualDefinitionPass implements CompilerPassInterface } } - foreach ($container->getDefinitions() as $definition) { + foreach ($container->getDefinitions() as $id => $definition) { + $this->sourceId = $id; + $definition->setArguments( $this->updateArgumentReferences($definition->getArguments(), $currentId, $newId) ); @@ -75,6 +84,10 @@ class ReplaceAliasByActualDefinitionPass implements CompilerPassInterface $definition->setMethodCalls( $this->updateArgumentReferences($definition->getMethodCalls(), $currentId, $newId) ); + + $definition->setProperties( + $this->updateArgumentReferences($definition->getProperties(), $currentId, $newId) + ); } } @@ -93,6 +106,7 @@ class ReplaceAliasByActualDefinitionPass implements CompilerPassInterface } else if ($argument instanceof Reference) { if ($currentId === (string) $argument) { $arguments[$k] = new Reference($newId, $argument->getInvalidBehavior()); + $this->compiler->addLogMessage($this->formatter->formatUpdateReference($this, $this->sourceId, $currentId, $newId)); } } } diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php index a19370e1ec..ca263d3a5c 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php @@ -15,6 +15,8 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; class ResolveDefinitionTemplatesPass implements CompilerPassInterface { private $container; + private $compiler; + private $formatter; /** * Process the ContainerBuilder to replace DefinitionDecorator instances with their real Definition instances. @@ -24,6 +26,9 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface public function process(ContainerBuilder $container) { $this->container = $container; + $this->compiler = $container->getCompiler(); + $this->formatter = $this->compiler->getLoggingFormatter(); + foreach (array_keys($container->getDefinitions()) as $id) { // yes, we are specifically fetching the definition from the // container to ensure we are not operating on stale data @@ -54,6 +59,7 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface $parentDef = $this->resolveDefinition($parent, $parentDef); } + $this->compiler->addLogMessage($this->formatter->formatResolveInheritance($this, $id, $parent)); $def = new Definition(); // merge in parent definition @@ -105,7 +111,7 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface } $index = (integer) substr($k, strlen('index_')); - $def->setArgument($index, $v); + $def->replaceArgument($index, $v); } // merge properties diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php index 9d7980ddfa..15a2d888b9 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php @@ -24,27 +24,6 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; class ResolveInvalidReferencesPass implements CompilerPassInterface { private $container; - private $exceptions; - - /** - * Constructor. - * - * @param array $exceptions An array of exceptions - */ - public function __construct(array $exceptions = array('kernel', 'service_container', 'templating.loader.wrapped', 'pdo_connection')) - { - $this->exceptions = $exceptions; - } - - /** - * Add an exception. - * - * @param string $id Exception identifier - */ - public function addException($id) - { - $this->exceptions[] = $id; - } /** * Process the ContainerBuilder to resolve invalid references. @@ -100,10 +79,6 @@ class ResolveInvalidReferencesPass implements CompilerPassInterface } else if ($argument instanceof Reference) { $id = (string) $argument; - if (in_array($id, $this->exceptions, true)) { - continue; - } - $invalidBehavior = $argument->getInvalidBehavior(); $exists = $this->container->has($id); @@ -124,4 +99,4 @@ class ResolveInvalidReferencesPass implements CompilerPassInterface return $arguments; } -} \ No newline at end of file +} diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraph.php b/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraph.php index ce512e7d64..8eb76ddb6a 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraph.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraph.php @@ -46,7 +46,7 @@ class ServiceReferenceGraph * * @param string $id The id to retrieve * @return ServiceReferenceGraphNode The node matching the supplied identifier - * @throws \InvalidArgumentException + * @throws \InvalidArgumentException */ public function getNode($id) { @@ -78,11 +78,11 @@ class ServiceReferenceGraph /** * Connects 2 nodes together in the Graph. * - * @param string $sourceId - * @param string $sourceValue - * @param string $destId - * @param string $destValue - * @param string $reference + * @param string $sourceId + * @param string $sourceValue + * @param string $destId + * @param string $destValue + * @param string $reference */ public function connect($sourceId, $sourceValue, $destId, $destValue = null, $reference = null) { @@ -97,8 +97,8 @@ class ServiceReferenceGraph /** * Creates a graph node. * - * @param string $id - * @param string $value + * @param string $id + * @param string $value * @return ServiceReferenceGraphNode */ private function createNode($id, $value) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraphEdge.php b/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraphEdge.php index b768b59bf3..6331edc22c 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraphEdge.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraphEdge.php @@ -27,9 +27,9 @@ class ServiceReferenceGraphEdge /** * Constructor. * - * @param ServiceReferenceGraphNode $sourceNode - * @param ServiceReferenceGraphNode $destNode - * @param string $value + * @param ServiceReferenceGraphNode $sourceNode + * @param ServiceReferenceGraphNode $destNode + * @param string $value */ public function __construct(ServiceReferenceGraphNode $sourceNode, ServiceReferenceGraphNode $destNode, $value = null) { diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraphNode.php b/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraphNode.php index 0070781ca9..6c71683d5f 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraphNode.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraphNode.php @@ -45,7 +45,7 @@ class ServiceReferenceGraphNode /** * Adds an in edge to this node. * - * @param ServiceReferenceGraphEdge $edge + * @param ServiceReferenceGraphEdge $edge */ public function addInEdge(ServiceReferenceGraphEdge $edge) { @@ -55,7 +55,7 @@ class ServiceReferenceGraphNode /** * Adds an out edge to this node. * - * @param ServiceReferenceGraphEdge $edge + * @param ServiceReferenceGraphEdge $edge */ public function addOutEdge(ServiceReferenceGraphEdge $edge) { diff --git a/src/Symfony/Component/DependencyInjection/Container.php b/src/Symfony/Component/DependencyInjection/Container.php index 1cd5733aaa..2a0af61409 100644 --- a/src/Symfony/Component/DependencyInjection/Container.php +++ b/src/Symfony/Component/DependencyInjection/Container.php @@ -11,6 +11,7 @@ namespace Symfony\Component\DependencyInjection; +use Symfony\Component\DependencyInjection\Exception\NonExistentServiceException; use Symfony\Component\DependencyInjection\Exception\CircularReferenceException; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; @@ -237,7 +238,7 @@ class Container implements ContainerInterface } if (self::EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior) { - throw new \InvalidArgumentException(sprintf('The service "%s" does not exist.', $id)); + throw new NonExistentServiceException($id); } } @@ -256,7 +257,7 @@ class Container implements ContainerInterface } } - return array_merge($ids, array_keys($this->services)); + return array_unique(array_merge($ids, array_keys($this->services))); } /** diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 40a2a0affd..89408969ba 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -241,11 +241,11 @@ class ContainerBuilder extends Container implements TaggedContainerInterface } /** - * Removes a service. + * Removes a service definition. * * @param string $id The service identifier */ - public function remove($id) + public function removeDefinition($id) { unset($this->definitions[strtolower($id)]); } diff --git a/src/Symfony/Component/DependencyInjection/Definition.php b/src/Symfony/Component/DependencyInjection/Definition.php index 550aa59b20..b44983d61d 100644 --- a/src/Symfony/Component/DependencyInjection/Definition.php +++ b/src/Symfony/Component/DependencyInjection/Definition.php @@ -205,7 +205,7 @@ class Definition * * @return Definition The current instance */ - public function setArgument($index, $argument) + public function replaceArgument($index, $argument) { if ($index < 0 || $index > count($this->arguments) - 1) { throw new \OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, count($this->arguments) - 1)); diff --git a/src/Symfony/Component/DependencyInjection/DefinitionDecorator.php b/src/Symfony/Component/DependencyInjection/DefinitionDecorator.php index 0b68b7c215..53ac89a3b6 100644 --- a/src/Symfony/Component/DependencyInjection/DefinitionDecorator.php +++ b/src/Symfony/Component/DependencyInjection/DefinitionDecorator.php @@ -44,7 +44,7 @@ class DefinitionDecorator extends Definition { return $this->changes; } - + /** * {@inheritDoc} */ @@ -54,7 +54,7 @@ class DefinitionDecorator extends Definition return parent::setClass($class); } - + /** * {@inheritDoc} */ @@ -64,7 +64,7 @@ class DefinitionDecorator extends Definition return parent::setFactoryClass($class); } - + /** * {@inheritDoc} */ @@ -74,7 +74,7 @@ class DefinitionDecorator extends Definition return parent::setFactoryMethod($method); } - + /** * {@inheritDoc} */ @@ -84,7 +84,7 @@ class DefinitionDecorator extends Definition return parent::setFactoryService($service); } - + /** * {@inheritDoc} */ @@ -94,7 +94,7 @@ class DefinitionDecorator extends Definition return parent::setConfigurator($callable); } - + /** * {@inheritDoc} */ @@ -104,7 +104,7 @@ class DefinitionDecorator extends Definition return parent::setFile($file); } - + /** * {@inheritDoc} */ @@ -129,7 +129,7 @@ class DefinitionDecorator extends Definition * @return DefinitionDecorator the current instance * @throws \InvalidArgumentException when $index isnt an integer */ - public function setArgument($index, $value) + public function replaceArgument($index, $value) { if (!is_int($index)) { throw new \InvalidArgumentException('$index must be an integer.'); diff --git a/src/Symfony/Component/DependencyInjection/Exception/NonExistentServiceException.php b/src/Symfony/Component/DependencyInjection/Exception/NonExistentServiceException.php new file mode 100644 index 0000000000..ee42ea9972 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Exception/NonExistentServiceException.php @@ -0,0 +1,38 @@ + + */ +class NonExistentServiceException extends InvalidArgumentException +{ + private $id; + private $sourceId; + + public function __construct($id, $sourceId = null) + { + if (null === $sourceId) { + $msg = sprintf('You have requested a non-existent service "%s".', $id); + } else { + $msg = sprintf('The service "%s" has a dependency on a non-existent service "%s".', $sourceId, $id); + } + + parent::__construct($msg); + + $this->id = $id; + $this->sourceId = $sourceId; + } + + public function getId() + { + return $this->id; + } + + public function getSourceId() + { + return $this->sourceId; + } +} \ No newline at end of file diff --git a/src/Symfony/Component/DependencyInjection/ParameterBag/FrozenParameterBag.php b/src/Symfony/Component/DependencyInjection/ParameterBag/FrozenParameterBag.php index 75cc168b4d..e9590933cd 100644 --- a/src/Symfony/Component/DependencyInjection/ParameterBag/FrozenParameterBag.php +++ b/src/Symfony/Component/DependencyInjection/ParameterBag/FrozenParameterBag.php @@ -12,7 +12,7 @@ namespace Symfony\Component\DependencyInjection\ParameterBag; /** - * + * * @author Fabien Potencier */ class FrozenParameterBag extends ParameterBag diff --git a/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php b/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php index cb3de82639..75d862d5b4 100644 --- a/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php +++ b/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php @@ -12,7 +12,7 @@ namespace Symfony\Component\DependencyInjection\ParameterBag; /** - * + * * @author Fabien Potencier */ class ParameterBag implements ParameterBagInterface @@ -149,7 +149,7 @@ class ParameterBag implements ParameterBagInterface * * @see resolveValue * - * @param array $match + * @param array $match * @return string */ private function resolveValueCallback($match) diff --git a/src/Symfony/Component/DependencyInjection/Variable.php b/src/Symfony/Component/DependencyInjection/Variable.php index 894107b4a4..11f255649f 100644 --- a/src/Symfony/Component/DependencyInjection/Variable.php +++ b/src/Symfony/Component/DependencyInjection/Variable.php @@ -31,7 +31,7 @@ class Variable /** * Constructor * - * @param string $name + * @param string $name */ public function __construct($name) { diff --git a/src/Symfony/Component/DomCrawler/Form.php b/src/Symfony/Component/DomCrawler/Form.php index d6b002551a..10efb7f2a4 100644 --- a/src/Symfony/Component/DomCrawler/Form.php +++ b/src/Symfony/Component/DomCrawler/Form.php @@ -190,10 +190,14 @@ class Form implements \ArrayAccess $uri = $this->node->getAttribute('action'); $urlHaveScheme = 'http' === substr($uri, 0, 4); - if (!$uri || '#' === $uri) { + if (!$uri) { $uri = $this->path; } + if ('#' === $uri[0]) { + $uri = $this->path.$uri; + } + if (!in_array($this->getMethod(), array('post', 'put', 'delete')) && $queryString = http_build_query($this->getValues(), null, '&')) { $sep = false === strpos($uri, '?') ? '?' : '&'; $uri .= $sep.$queryString; diff --git a/src/Symfony/Component/DomCrawler/Link.php b/src/Symfony/Component/DomCrawler/Link.php index 17c8bab7b6..27e7f2d6f9 100644 --- a/src/Symfony/Component/DomCrawler/Link.php +++ b/src/Symfony/Component/DomCrawler/Link.php @@ -76,6 +76,14 @@ class Link $uri = $this->node->getAttribute('href'); $urlHaveScheme = 'http' === substr($uri, 0, 4); + if (!$uri) { + $uri = $this->path; + } + + if ('#' === $uri[0]) { + $uri = $this->path.$uri; + } + $path = $this->path; if ('?' !== substr($uri, 0, 1) && '/' !== substr($path, -1)) { $path = substr($path, 0, strrpos($path, '/') + 1); diff --git a/src/Symfony/Component/EventDispatcher/EventSubscriberInterface.php b/src/Symfony/Component/EventDispatcher/EventSubscriberInterface.php index 9ad999c3cf..edd9081c55 100644 --- a/src/Symfony/Component/EventDispatcher/EventSubscriberInterface.php +++ b/src/Symfony/Component/EventDispatcher/EventSubscriberInterface.php @@ -37,9 +37,9 @@ namespace Symfony\Component\EventDispatcher; interface EventSubscriberInterface { /** - * Returns an array of events this subscriber wants to listen to. + * Returns an array of event names this subscriber wants to listen to. * - * @return array + * @return array The event names to listen to */ static function getSubscribedEvents(); } diff --git a/src/Symfony/Component/Form/MoneyField.php b/src/Symfony/Component/Form/MoneyField.php index ac8e4cf256..7bd1fb8d1e 100644 --- a/src/Symfony/Component/Form/MoneyField.php +++ b/src/Symfony/Component/Form/MoneyField.php @@ -24,7 +24,7 @@ use Symfony\Component\Form\ValueTransformer\MoneyToLocalizedStringTransformer; * * currency: The currency to display the money with. This is the 3-letter * ISO 4217 currency code. * * divisor: A number to divide the money by before displaying. Default 1. - * + * * @see Symfony\Component\Form\NumberField * @author Bernhard Schussek */ diff --git a/src/Symfony/Component/HttpFoundation/Cookie.php b/src/Symfony/Component/HttpFoundation/Cookie.php index bf4b6beb52..6a3438677c 100644 --- a/src/Symfony/Component/HttpFoundation/Cookie.php +++ b/src/Symfony/Component/HttpFoundation/Cookie.php @@ -26,7 +26,7 @@ class Cookie protected $secure; protected $httpOnly; - public function __construct($name, $value = null, $expire = 0, $path = '/', $domain = null, $secure = false, $httpOnly = true) + public function __construct($name, $value = null, $expire = 0, $path = '/', $domain = null, $secure = false, $httpOnly = false) { // from PHP source code if (preg_match("/[=,; \t\r\n\013\014]/", $name)) { @@ -41,9 +41,15 @@ class Cookie throw new \InvalidArgumentException('The cookie name cannot be empty'); } - // check if the expiration is valid - if (!$expire instanceof \DateTime && !is_numeric($expire) && (strtotime($expire) === false || strtotime($expire) === -1)) { - throw new \InvalidArgumentException('The cookie expiration is not valid'); + // convert expiration time to a Unix timestamp + if ($expire instanceof \DateTime) { + $expire = $expire->format('U'); + } elseif (!is_numeric($expire)) { + $expire = strtotime($expire); + + if (false === $expire || -1 === $expire) { + throw new \InvalidArgumentException('The cookie expiration time is not valid.'); + } } $this->name = $name; @@ -70,7 +76,7 @@ class Cookie return $this->domain; } - public function getExpire() + public function getExpiresTime() { return $this->expire; } diff --git a/src/Symfony/Component/HttpFoundation/File/Exception/AccessDeniedException.php b/src/Symfony/Component/HttpFoundation/File/Exception/AccessDeniedException.php index aa1a1ad01a..fc6ea5e807 100644 --- a/src/Symfony/Component/HttpFoundation/File/Exception/AccessDeniedException.php +++ b/src/Symfony/Component/HttpFoundation/File/Exception/AccessDeniedException.php @@ -2,7 +2,7 @@ /* * This file is part of the Symfony package. - * + * * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE diff --git a/src/Symfony/Component/HttpFoundation/File/Exception/FileException.php b/src/Symfony/Component/HttpFoundation/File/Exception/FileException.php index ff1c2dbb81..7d8310909f 100644 --- a/src/Symfony/Component/HttpFoundation/File/Exception/FileException.php +++ b/src/Symfony/Component/HttpFoundation/File/Exception/FileException.php @@ -2,7 +2,7 @@ /* * This file is part of the Symfony package. - * + * * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE diff --git a/src/Symfony/Component/HttpFoundation/File/Exception/FileNotFoundException.php b/src/Symfony/Component/HttpFoundation/File/Exception/FileNotFoundException.php index 07d368b611..60ba964745 100644 --- a/src/Symfony/Component/HttpFoundation/File/Exception/FileNotFoundException.php +++ b/src/Symfony/Component/HttpFoundation/File/Exception/FileNotFoundException.php @@ -2,7 +2,7 @@ /* * This file is part of the Symfony package. - * + * * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE diff --git a/src/Symfony/Component/HttpFoundation/File/File.php b/src/Symfony/Component/HttpFoundation/File/File.php index 4675332e17..bda63e9a6b 100644 --- a/src/Symfony/Component/HttpFoundation/File/File.php +++ b/src/Symfony/Component/HttpFoundation/File/File.php @@ -491,7 +491,7 @@ class File throw new FileNotFoundException($path); } - $this->path = realpath($path); + $this->path = $path; } /** diff --git a/src/Symfony/Component/HttpFoundation/File/MimeType/ContentTypeMimeTypeGuesser.php b/src/Symfony/Component/HttpFoundation/File/MimeType/ContentTypeMimeTypeGuesser.php index f0a1fdecad..fb900b2bc2 100644 --- a/src/Symfony/Component/HttpFoundation/File/MimeType/ContentTypeMimeTypeGuesser.php +++ b/src/Symfony/Component/HttpFoundation/File/MimeType/ContentTypeMimeTypeGuesser.php @@ -2,7 +2,7 @@ /* * This file is part of the Symfony package. - * + * * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE diff --git a/src/Symfony/Component/HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php b/src/Symfony/Component/HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php index e9a352f0ec..84862b0124 100644 --- a/src/Symfony/Component/HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php +++ b/src/Symfony/Component/HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php @@ -2,7 +2,7 @@ /* * This file is part of the Symfony package. - * + * * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE @@ -48,7 +48,7 @@ class FileBinaryMimeTypeGuesser implements MimeTypeGuesserInterface if (!self::isSupported()) { return null; } - + ob_start(); // need to use --mime instead of -i. see #6641 diff --git a/src/Symfony/Component/HttpFoundation/File/MimeType/FileinfoMimeTypeGuesser.php b/src/Symfony/Component/HttpFoundation/File/MimeType/FileinfoMimeTypeGuesser.php index e55e7d54cb..f3b39a3eb0 100644 --- a/src/Symfony/Component/HttpFoundation/File/MimeType/FileinfoMimeTypeGuesser.php +++ b/src/Symfony/Component/HttpFoundation/File/MimeType/FileinfoMimeTypeGuesser.php @@ -2,7 +2,7 @@ /* * This file is part of the Symfony package. - * + * * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE diff --git a/src/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeGuesser.php b/src/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeGuesser.php index 2cecb141b7..cfb0cb8fcd 100644 --- a/src/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeGuesser.php +++ b/src/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeGuesser.php @@ -2,7 +2,7 @@ /* * This file is part of the Symfony package. - * + * * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE diff --git a/src/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeGuesserInterface.php b/src/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeGuesserInterface.php index adf29479d5..0665970c79 100644 --- a/src/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeGuesserInterface.php +++ b/src/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeGuesserInterface.php @@ -2,7 +2,7 @@ /* * This file is part of the Symfony package. - * + * * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE diff --git a/src/Symfony/Component/HttpFoundation/ParameterBag.php b/src/Symfony/Component/HttpFoundation/ParameterBag.php index f261b59cd4..0d4d8bf8d9 100644 --- a/src/Symfony/Component/HttpFoundation/ParameterBag.php +++ b/src/Symfony/Component/HttpFoundation/ParameterBag.php @@ -81,6 +81,61 @@ class ParameterBag return array_key_exists($key, $this->parameters) ? $this->parameters[$key] : $default; } + /** + * Returns a parameter by name allowing to specify a path with arbitrary depth. + * + * @param string $path The path, e.g. foo[bar] + * @param mixed $default The default value + */ + public function getDeep($path, $default = null) + { + if (false === $pos = strpos($path, '[')) { + return $this->get($path, $default); + } + + $root = substr($path, 0, $pos); + if (!array_key_exists($root, $this->parameters)) { + return $default; + } + + $value = $this->parameters[$root]; + $currentKey = null; + for ($i=$pos,$c=strlen($path); $i<$c; $i++) { + $char = $path[$i]; + + if ('[' === $char) { + if (null !== $currentKey) { + throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "[" at position %d.', $i)); + } + + $currentKey = ''; + } else if (']' === $char) { + if (null === $currentKey) { + throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "]" at position %d.', $i)); + } + + if (!is_array($value) || !array_key_exists($currentKey, $value)) { + return $default; + } + + $value = $value[$currentKey]; + $currentKey = null; + } else { + if (null === $currentKey) { + throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "%s" at position %d.', $char, $i)); + } + + $currentKey .= $char; + } + } + + if (null !== $currentKey) { + throw new \InvalidArgumentException(sprintf('Malformed path. Path must end with "]".')); + } + + return $value; + } + /** * Sets a parameter by name. * diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index c390c4b6d6..466236da67 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -126,7 +126,7 @@ class Request * * @return Request A new request */ - static public function createfromGlobals() + static public function createFromGlobals() { return new static($_GET, $_POST, array(), $_COOKIE, $_FILES, $_SERVER); } @@ -311,7 +311,8 @@ class Request public function hasSession() { - return $this->cookies->has(session_name()); + // the check for $this->session avoids malicious users trying to fake a session cookie with proper name + return $this->cookies->has(session_name()) && null !== $this->session; } public function setSession(Session $session) @@ -408,7 +409,7 @@ class Request public function getScheme() { - return ($this->server->get('HTTPS') == 'on') ? 'https' : 'http'; + return $this->isSecure() ? 'https' : 'http'; } public function getPort() diff --git a/src/Symfony/Component/HttpFoundation/Response.php b/src/Symfony/Component/HttpFoundation/Response.php index c16010e551..813cab9c60 100644 --- a/src/Symfony/Component/HttpFoundation/Response.php +++ b/src/Symfony/Component/HttpFoundation/Response.php @@ -145,7 +145,7 @@ class Response // cookies foreach ($this->headers->getCookies() as $cookie) { - setcookie($cookie->getName(), $cookie->getValue(), $cookie->getExpire(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly()); + setcookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly()); } } @@ -458,6 +458,7 @@ class Response */ public function setSharedMaxAge($value) { + $this->setPublic(); $this->headers->addCacheControlDirective('s-maxage', $value); } @@ -737,7 +738,7 @@ class Response public function isRedirect() { - return in_array($this->statusCode, array(301, 302, 303, 307)); + return in_array($this->statusCode, array(201, 301, 302, 303, 307)); } public function isEmpty() diff --git a/src/Symfony/Component/HttpFoundation/SessionStorage/ArraySessionStorage.php b/src/Symfony/Component/HttpFoundation/SessionStorage/ArraySessionStorage.php old mode 100755 new mode 100644 diff --git a/src/Symfony/Component/HttpFoundation/SessionStorage/FilesystemSessionStorage.php b/src/Symfony/Component/HttpFoundation/SessionStorage/FilesystemSessionStorage.php new file mode 100644 index 0000000000..5cc70ff452 --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/SessionStorage/FilesystemSessionStorage.php @@ -0,0 +1,103 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\SessionStorage; + +/** + * FilesystemSessionStorage. + * + * @author Fabien Potencier + */ +class FilesystemSessionStorage extends NativeSessionStorage +{ + private $path; + private $data; + private $started; + + public function __construct($path, array $options = array()) + { + $this->path = $path; + $this->started = false; + + parent::__construct($options); + } + + public function start() + { + if ($this->started) { + return; + } + + session_set_cookie_params( + $this->options['lifetime'], + $this->options['path'], + $this->options['domain'], + $this->options['secure'], + $this->options['httponly'] + ); + + if (!ini_get('session.use_cookies') && $this->options['id'] && $this->options['id'] != session_id()) { + session_id($this->options['id']); + } + + if (!session_id()) { + session_id(hash('md5', uniqid(mt_rand(), true))); + } + + if (!is_dir($this->path)) { + mkdir($this->path, 0777, true); + } + + $file = $this->path.'/'.session_id().'.session'; + + $this->data = file_exists($file) ? unserialize(file_get_contents($file)) : array(); + $this->started = true; + } + + public function getId() + { + if (!$this->started) { + throw new \RuntimeException('The session must be started before reading its ID'); + } + + return session_id(); + } + + public function read($key, $default = null) + { + return array_key_exists($key, $this->data) ? $this->data[$key] : $default; + } + + public function remove($key) + { + $retval = $this->data[$key]; + + unset($this->data[$key]); + + return $retval; + } + + public function write($key, $data) + { + $this->data[$key] = $data; + + file_put_contents($this->path.'/'.session_id().'.session', serialize($this->data)); + } + + public function regenerate($destroy = false) + { + if ($destroy) { + $this->data = array(); + } + + return true; + } +} diff --git a/src/Symfony/Component/HttpFoundation/SessionStorage/PdoSessionStorage.php b/src/Symfony/Component/HttpFoundation/SessionStorage/PdoSessionStorage.php index 62fb61a83d..10083f8d6d 100644 --- a/src/Symfony/Component/HttpFoundation/SessionStorage/PdoSessionStorage.php +++ b/src/Symfony/Component/HttpFoundation/SessionStorage/PdoSessionStorage.php @@ -15,6 +15,7 @@ namespace Symfony\Component\HttpFoundation\SessionStorage; * PdoSessionStorage. * * @author Fabien Potencier + * @author Michael Williams */ class PdoSessionStorage extends NativeSessionStorage { @@ -174,13 +175,7 @@ class PdoSessionStorage extends NativeSessionStorage } // session does not exist, create it - $sql = 'INSERT INTO '.$dbTable.'('.$dbIdCol.', '.$dbDataCol.', '.$dbTimeCol.') VALUES (?, ?, ?)'; - - $stmt = $this->db->prepare($sql); - $stmt->bindParam(1, $id, \PDO::PARAM_STR); - $stmt->bindValue(2, '', \PDO::PARAM_STR); - $stmt->bindValue(3, time(), \PDO::PARAM_INT); - $stmt->execute(); + $this->createNewSession($id); return ''; } catch (\PDOException $e) { @@ -213,10 +208,41 @@ class PdoSessionStorage extends NativeSessionStorage $stmt->bindParam(1, $data, \PDO::PARAM_STR); $stmt->bindParam(2, $id, \PDO::PARAM_STR); $stmt->execute(); + + if (!$stmt->rowCount()) { + // No session exists in the database to update. This happens when we have called + // session_regenerate_id() + $this->createNewSession($id, $data); + } } catch (\PDOException $e) { throw new \RuntimeException(sprintf('PDOException was thrown when trying to manipulate session data: %s', $e->getMessage()), 0, $e); } return true; } + + /** + * Creates a new session with the given $id and $data + * + * @param string $id + * @param string $data + */ + private function createNewSession($id, $data = '') + { + // get table/column + $dbTable = $this->options['db_table']; + $dbDataCol = $this->options['db_data_col']; + $dbIdCol = $this->options['db_id_col']; + $dbTimeCol = $this->options['db_time_col']; + + $sql = 'INSERT INTO '.$dbTable.'('.$dbIdCol.', '.$dbDataCol.', '.$dbTimeCol.') VALUES (?, ?, ?)'; + + $stmt = $this->db->prepare($sql); + $stmt->bindParam(1, $id, \PDO::PARAM_STR); + $stmt->bindValue(2, $data, \PDO::PARAM_STR); + $stmt->bindValue(3, time(), \PDO::PARAM_INT); + $stmt->execute(); + + return true; + } } diff --git a/src/Symfony/Component/HttpKernel/Bundle/Bundle.php b/src/Symfony/Component/HttpKernel/Bundle/Bundle.php index 61276adef2..7910a0bfe6 100644 --- a/src/Symfony/Component/HttpKernel/Bundle/Bundle.php +++ b/src/Symfony/Component/HttpKernel/Bundle/Bundle.php @@ -61,10 +61,10 @@ abstract class Bundle extends ContainerAware implements BundleInterface */ public function build(ContainerBuilder $container) { - $class = $this->getNamespace().'\\DependencyInjection\\'.$this->getName().'Extension'; + $class = $this->getNamespace().'\\DependencyInjection\\'.str_replace('Bundle', 'Extension', $this->getName()); if (class_exists($class)) { $extension = new $class(); - $alias = Container::underscore($this->getName()); + $alias = Container::underscore(str_replace('Bundle', '', $this->getName())); if ($alias !== $extension->getAlias()) { throw new \LogicException(sprintf('The extension alias for the default extension of a bundle must be the underscored version of the bundle name ("%s" vs "%s")', $alias, $extension->getAlias())); } @@ -98,7 +98,7 @@ abstract class Bundle extends ContainerAware implements BundleInterface $this->reflected = new \ReflectionObject($this); } - return strtr(dirname($this->reflected->getFileName()), '\\', '/'); + return dirname($this->reflected->getFileName()); } /** @@ -115,8 +115,6 @@ abstract class Bundle extends ContainerAware implements BundleInterface * Returns the bundle name (the class short name). * * @return string The Bundle name - * - * @throws RuntimeException If the bundle class name does not end with "Bundle" */ final public function getName() { @@ -124,14 +122,10 @@ abstract class Bundle extends ContainerAware implements BundleInterface return $this->name; } - $fqcn = get_class($this); - $name = false === ($pos = strrpos($fqcn, '\\')) ? $fqcn : substr($fqcn, $pos + 1); + $name = get_class($this); + $pos = strrpos($name, '\\'); - if ('Bundle' != substr($name, -6)) { - throw new \RuntimeException(sprintf('The bundle class name "%s" must end with "Bundle" to be valid.', $name)); - } - - return $this->name = substr($name, 0, -6); + return $this->name = false === $pos ? $name : substr($name, $pos + 1); } /** diff --git a/src/Symfony/Component/HttpKernel/Client.php b/src/Symfony/Component/HttpKernel/Client.php index 75b4ff9182..2c6ad0e885 100644 --- a/src/Symfony/Component/HttpKernel/Client.php +++ b/src/Symfony/Component/HttpKernel/Client.php @@ -17,6 +17,7 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\BrowserKit\Client as BaseClient; use Symfony\Component\BrowserKit\Request as DomRequest; use Symfony\Component\BrowserKit\Response as DomResponse; +use Symfony\Component\BrowserKit\Cookie as DomCookie; use Symfony\Component\BrowserKit\History; use Symfony\Component\BrowserKit\CookieJar; @@ -139,6 +140,15 @@ EOF; */ protected function filterResponse($response) { - return new DomResponse($response->getContent(), $response->getStatusCode(), $response->headers->all()); + $headers = $response->headers->all(); + if ($response->headers->getCookies()) { + $cookies = array(); + foreach ($response->headers->getCookies() as $cookie) { + $cookies[] = new DomCookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly()); + } + $headers['Set-Cookie'] = implode(', ', $cookies); + } + + return new DomResponse($response->getContent(), $response->getStatusCode(), $headers); } } diff --git a/src/Symfony/Component/HttpKernel/Config/FileLocator.php b/src/Symfony/Component/HttpKernel/Config/FileLocator.php index 652198d488..387a4a9428 100644 --- a/src/Symfony/Component/HttpKernel/Config/FileLocator.php +++ b/src/Symfony/Component/HttpKernel/Config/FileLocator.php @@ -22,16 +22,20 @@ use Symfony\Component\HttpKernel\KernelInterface; class FileLocator extends BaseFileLocator { private $kernel; + private $path; /** * Constructor. * * @param KernelInterface $kernel A KernelInterface instance - * @param string|array $paths A path or an array of paths where to look for resources + * @param string $path The path the global resource directory + * @param string|array $paths A path or an array of paths where to look for resources */ - public function __construct(KernelInterface $kernel, array $paths = array()) + public function __construct(KernelInterface $kernel, $path = null, array $paths = array()) { $this->kernel = $kernel; + $this->path = $path; + $paths[] = $path; parent::__construct($paths); } @@ -42,7 +46,7 @@ class FileLocator extends BaseFileLocator public function locate($file, $currentPath = null, $first = true) { if ('@' === $file[0]) { - return $this->kernel->locateResource($file, $currentPath, $first); + return $this->kernel->locateResource($file, $this->path, $first); } return parent::locate($file, $currentPath, $first); diff --git a/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php b/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php index c4ddddbdcf..ce95590f97 100644 --- a/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php +++ b/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php @@ -60,7 +60,7 @@ class ControllerResolver implements ControllerResolverInterface return false; } - if ($controller instanceof \Closure) { + if (is_array($controller) || method_exists($controller, '__invoke')) { return $controller; } @@ -92,15 +92,21 @@ class ControllerResolver implements ControllerResolverInterface if (is_array($controller)) { $r = new \ReflectionMethod($controller[0], $controller[1]); $repr = sprintf('%s::%s()', get_class($controller[0]), $controller[1]); + } elseif (is_object($controller)) { + $r = new \ReflectionObject($controller); + $r = $r->getMethod('__invoke'); + $repr = get_class($controller); } else { $r = new \ReflectionFunction($controller); - $repr = 'Closure'; + $repr = $controller; } $arguments = array(); foreach ($r->getParameters() as $param) { if (array_key_exists($param->getName(), $attributes)) { $arguments[] = $attributes[$param->getName()]; + } elseif ($param->getClass() && $param->getClass()->isInstance($request)) { + $arguments[] = $request; } elseif ($param->isDefaultValueAvailable()) { $arguments[] = $param->getDefaultValue(); } else { diff --git a/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php index c3f1703432..69c38f59ab 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php @@ -33,7 +33,7 @@ class RequestDataCollector extends DataCollector $responseHeaders = $response->headers->all(); $cookies = array(); foreach ($response->headers->getCookies() as $cookie) { - $cookies[] = $this->getCookieHeader($cookie->getName(), $cookie->getValue(), $cookie->getExpire(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly()); + $cookies[] = $this->getCookieHeader($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly()); } if (count($cookies) > 0) { $responseHeaders['Set-Cookie'] = $cookies; @@ -44,8 +44,17 @@ class RequestDataCollector extends DataCollector $attributes[$key] = is_object($value) ? sprintf('Object(%s)', get_class($value)) : $value; } + $content = null; + try { + $content = $request->getContent(); + } catch (\LogicException $e) { + // the user already got the request content as a resource + $content = false; + } + $this->data = array( 'format' => $request->getRequestFormat(), + 'content' => $content, 'content_type' => $response->headers->get('Content-Type') ? $response->headers->get('Content-Type') : 'text/html', 'status_code' => $response->getStatusCode(), 'request_query' => $request->query->all(), @@ -99,6 +108,11 @@ class RequestDataCollector extends DataCollector return $this->data['session_attributes']; } + public function getContent() + { + return $this->data['content']; + } + public function getContentType() { return $this->data['content_type']; diff --git a/src/Symfony/Component/HttpKernel/DependencyInjection/Extension.php b/src/Symfony/Component/HttpKernel/DependencyInjection/Extension.php index a2a31375aa..aa7a77fbd8 100644 --- a/src/Symfony/Component/HttpKernel/DependencyInjection/Extension.php +++ b/src/Symfony/Component/HttpKernel/DependencyInjection/Extension.php @@ -82,7 +82,7 @@ abstract class Extension implements ExtensionInterface */ public function getNamespace() { - return false; + return 'http://example.org/schema/dic/'.$this->getAlias(); } /** diff --git a/src/Symfony/Component/HttpKernel/DependencyInjection/MergeExtensionConfigurationPass.php b/src/Symfony/Component/HttpKernel/DependencyInjection/MergeExtensionConfigurationPass.php index 2d6734ebd2..05f6fa32d9 100644 --- a/src/Symfony/Component/HttpKernel/DependencyInjection/MergeExtensionConfigurationPass.php +++ b/src/Symfony/Component/HttpKernel/DependencyInjection/MergeExtensionConfigurationPass.php @@ -25,7 +25,7 @@ class MergeExtensionConfigurationPass extends BaseMergeExtensionConfigurationPas { foreach ($container->getParameter('kernel.bundles') as $bundleName => $bundleClass) { $bundleRefl = new \ReflectionClass($bundleClass); - $extClass = $bundleRefl->getNamespaceName().'\\DependencyInjection\\'.$bundleName.'Extension'; + $extClass = $bundleRefl->getNamespaceName().'\\DependencyInjection\\'.substr($bundleName, 0, -6).'Extension'; if (class_exists($extClass)) { $ext = new $extClass(); diff --git a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php index 8e3bf2e69b..d27e85da73 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php @@ -91,6 +91,7 @@ class HttpCache implements HttpKernelInterface 'stale_if_error' => 60, ), $options); $this->esi = $esi; + $this->traces = array(); } /** diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 35b6ff470d..8a2da2f19f 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -192,9 +192,9 @@ abstract class Kernel implements KernelInterface if (true === $first) { return $this->bundleMap[$name][0]; - } elseif (false === $first) { - return $this->bundleMap[$name]; } + + return $this->bundleMap[$name]; } /** @@ -204,15 +204,17 @@ abstract class Kernel implements KernelInterface * * The resource name must follow the following pattern: * - * @BundleName/path/to/a/file.something + * @/path/to/a/file.something * * where BundleName is the name of the bundle * and the remaining part is the relative path in the bundle. * - * If $dir is passed, and the first segment of the path is Resources, + * If $dir is passed, and the first segment of the path is "Resources", * this method will look for a file named: * - * $dir/BundleName/path/without/Resources + * $dir//path/without/Resources + * + * before looking in the bundle resource folder. * * @param string $name A resource name to locate * @param string $dir A directory where to look for the resource first @@ -221,7 +223,8 @@ abstract class Kernel implements KernelInterface * @return string|array The absolute path of the resource or an array if $first is false * * @throws \InvalidArgumentException if the file cannot be found or the name is not valid - * @throws \RuntimeException if the name contains invalid/unsafe characters + * @throws \RuntimeException if the name contains invalid/unsafe + * @throws \RuntimeException if a custom resource is hidden by a resource in a derived bundle */ public function locateResource($name, $dir = null, $first = true) { @@ -234,30 +237,41 @@ abstract class Kernel implements KernelInterface } $name = substr($name, 1); - list($bundle, $path) = explode('/', $name, 2); - - $isResource = 0 === strpos($path, 'Resources'); + list($bundleName, $path) = explode('/', $name, 2); + $isResource = 0 === strpos($path, 'Resources') && null !== $dir; + $overridePath = substr($path, 9); + $resourceBundle = null; + $bundles = $this->getBundle($bundleName, false); $files = array(); - if (true === $isResource && null !== $dir && file_exists($file = $dir.'/'.$bundle.'/'.substr($path, 10))) { - if ($first) { - return $file; - } - $files[] = $file; - } + foreach ($bundles as $bundle) { + if ($isResource && file_exists($file = $dir.'/'.$bundle->getName().$overridePath)) { + if (null !== $resourceBundle) { + throw new \RuntimeException(sprintf('"%s" resource is hidden by a resource from the "%s" derived bundle. Create a "%s" file to override the bundle resource.', + $file, + $resourceBundle, + $dir.'/'.$bundles[0]->getName().$overridePath + )); + } - foreach ($this->getBundle($bundle, false) as $bundle) { - if (file_exists($file = $bundle->getPath().'/'.$path)) { if ($first) { return $file; } $files[] = $file; } + + if (file_exists($file = $bundle->getPath().'/'.$path)) { + if ($first && !$isResource) { + return $file; + } + $files[] = $file; + $resourceBundle = $bundle->getName(); + } } - if ($files) { - return $files; + if (count($files) > 0) { + return $first && $isResource ? $files[0] : $files; } throw new \InvalidArgumentException(sprintf('Unable to find file "@%s".', $name)); @@ -356,6 +370,7 @@ abstract class Kernel implements KernelInterface * * @throws \LogicException if two bundles share a common name * @throws \LogicException if a bundle tries to extend a non-registered bundle + * @throws \LogicException if a bundle tries to extend itself * @throws \LogicException if two bundles extend the same ancestor */ protected function initializeBundles() @@ -376,6 +391,9 @@ abstract class Kernel implements KernelInterface if (isset($directChildren[$parentName])) { throw new \LogicException(sprintf('Bundle "%s" is directly extended by two bundles "%s" and "%s".', $parentName, $name, $directChildren[$parentName])); } + if ($parentName == $name) { + throw new \LogicException(sprintf('Bundle "%s" can not extend itself.', $name)); + } $directChildren[$parentName] = $name; } else { $topMostBundles[$name] = $bundle; @@ -417,6 +435,18 @@ abstract class Kernel implements KernelInterface return $this->name.ucfirst($this->environment).($this->debug ? 'Debug' : '').'ProjectContainer'; } + /** + * Gets the container's base class. + * + * All names except Container must be fully qualified. + * + * @return string + */ + protected function getContainerBaseClass() + { + return 'Container'; + } + /** * Initializes the service container. * @@ -430,7 +460,7 @@ abstract class Kernel implements KernelInterface $fresh = true; if (!$cache->isFresh()) { $container = $this->buildContainer(); - $this->dumpContainer($cache, $container, $class); + $this->dumpContainer($cache, $container, $class, $this->getContainerBaseClass()); $fresh = false; } @@ -538,12 +568,13 @@ abstract class Kernel implements KernelInterface * @param ConfigCache $cache The config cache * @param ContainerBuilder $container The service container * @param string $class The name of the class to generate + * @param string $baseClass The name of the container's base class */ - protected function dumpContainer(ConfigCache $cache, ContainerBuilder $container, $class) + protected function dumpContainer(ConfigCache $cache, ContainerBuilder $container, $class, $baseClass) { // cache the container $dumper = new PhpDumper($container); - $content = $dumper->dump(array('class' => $class)); + $content = $dumper->dump(array('class' => $class, 'base_class' => $baseClass)); if (!$this->debug) { $content = self::stripComments($content); } diff --git a/src/Symfony/Component/Locale/Resources/data/update-data.php b/src/Symfony/Component/Locale/Resources/data/update-data.php index 7a056d6358..8a7837d628 100644 --- a/src/Symfony/Component/Locale/Resources/data/update-data.php +++ b/src/Symfony/Component/Locale/Resources/data/update-data.php @@ -109,7 +109,7 @@ function get_data($index, $dataDir, $locale = 'en', $constraint = null) $bundle = load_resource_bundle($locale, __DIR__.DIRECTORY_SEPARATOR.$dataDir); foreach ($bundle->get($index) as $code => $name) { - if (!is_null($constraint)) { + if (null !== $constraint) { if ($constraint($code)) { $data[$code] = $name; } diff --git a/src/Symfony/Component/Locale/Stub/StubIntlDateFormatter.php b/src/Symfony/Component/Locale/Stub/StubIntlDateFormatter.php index be8568400a..65b8e33907 100644 --- a/src/Symfony/Component/Locale/Stub/StubIntlDateFormatter.php +++ b/src/Symfony/Component/Locale/Stub/StubIntlDateFormatter.php @@ -307,7 +307,7 @@ class StubIntlDateFormatter public function parse($value, &$position = null) { // We don't calculate the position when parsing the value - if (!is_null($position)) { + if (null !== $position) { throw new MethodArgumentNotImplementedException(__METHOD__, 'position'); } @@ -375,7 +375,7 @@ class StubIntlDateFormatter */ public function setTimeZoneId($timeZoneId) { - if (is_null($timeZoneId)) { + if (null === $timeZoneId) { $timeZoneId = date_default_timezone_get(); $this->unitializedTimeZoneId = true; } diff --git a/src/Symfony/Component/Locale/Stub/StubNumberFormatter.php b/src/Symfony/Component/Locale/Stub/StubNumberFormatter.php index 36b54c6f32..6ef99f3d0e 100644 --- a/src/Symfony/Component/Locale/Stub/StubNumberFormatter.php +++ b/src/Symfony/Component/Locale/Stub/StubNumberFormatter.php @@ -227,7 +227,7 @@ class StubNumberFormatter throw new MethodArgumentValueNotImplementedException(__METHOD__, 'style', $style, $message); } - if (!is_null($pattern)) { + if (null !== $pattern) { throw new MethodArgumentNotImplementedException(__METHOD__, 'pattern'); } @@ -446,7 +446,7 @@ class StubNumberFormatter } // We don't calculate the position when parsing the value - if (!is_null($position)) { + if (null !== $position) { throw new MethodArgumentNotImplementedException(__METHOD__, 'position'); } diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index d56fe2c769..92dbaab853 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -60,7 +60,7 @@ class Process } $this->stdin = $stdin; $this->timeout = $timeout; - $this->options = array_merge($options, array('suppress_errors' => true, 'binary_pipes' => true)); + $this->options = array_merge(array('suppress_errors' => true, 'binary_pipes' => true, 'bypass_shell' => true), $options); } /** diff --git a/src/Symfony/Component/Routing/Generator/Dumper/PhpGeneratorDumper.php b/src/Symfony/Component/Routing/Generator/Dumper/PhpGeneratorDumper.php index 87e85dad3a..4649ed961e 100644 --- a/src/Symfony/Component/Routing/Generator/Dumper/PhpGeneratorDumper.php +++ b/src/Symfony/Component/Routing/Generator/Dumper/PhpGeneratorDumper.php @@ -54,10 +54,7 @@ class PhpGeneratorDumper extends GeneratorDumper $compiledRoute = $route->compile(); $variables = str_replace("\n", '', var_export($compiledRoute->getVariables(), true)); - $defaultsMerge = ''; - foreach ($compiledRoute->getDefaults() as $key => $value) { - $defaultsMerge .= ' $defaults[\''.$key.'\'] = '.str_replace("\n", '', var_export($value, true)).';'."\n"; - } + $defaults = str_replace("\n", '', var_export($compiledRoute->getDefaults(), true)); $requirements = str_replace("\n", '', var_export($compiledRoute->getRequirements(), true)); $tokens = str_replace("\n", '', var_export($compiledRoute->getTokens(), true)); @@ -66,9 +63,7 @@ class PhpGeneratorDumper extends GeneratorDumper $methods[] = <<defaults; -$defaultsMerge - return array($variables, \$defaults, $requirements, $tokens); + return array($variables, $defaults, $requirements, $tokens); } EOF @@ -107,6 +102,8 @@ EOF; return <<context = \$context; - \$this->defaults = \$defaults; } EOF; diff --git a/src/Symfony/Component/Routing/Generator/UrlGenerator.php b/src/Symfony/Component/Routing/Generator/UrlGenerator.php index e83d40d612..5c02f2f69d 100644 --- a/src/Symfony/Component/Routing/Generator/UrlGenerator.php +++ b/src/Symfony/Component/Routing/Generator/UrlGenerator.php @@ -13,6 +13,7 @@ namespace Symfony\Component\Routing\Generator; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Routing\RequestContext; /** * UrlGenerator generates URL based on a set of routes. @@ -21,7 +22,6 @@ use Symfony\Component\Routing\RouteCollection; */ class UrlGenerator implements UrlGeneratorInterface { - protected $defaults; protected $context; private $routes; @@ -31,27 +31,35 @@ class UrlGenerator implements UrlGeneratorInterface * Constructor. * * @param RouteCollection $routes A RouteCollection instance - * @param array $context The context - * @param array $defaults The default values + * @param RequestContext $context The context */ - public function __construct(RouteCollection $routes, array $context = array(), array $defaults = array()) + public function __construct(RouteCollection $routes, RequestContext $context) { $this->routes = $routes; $this->context = $context; - $this->defaults = $defaults; $this->cache = array(); } /** * Sets the request context. * - * @param array $context The context + * @param RequestContext $context The context */ - public function setContext(array $context = array()) + public function setContext(RequestContext $context) { $this->context = $context; } + /** + * Gets the request context. + * + * @return RequestContext The context + */ + public function getContext() + { + return $this->context; + } + /** * Generates a URL from the given parameters. * @@ -81,8 +89,9 @@ class UrlGenerator implements UrlGeneratorInterface */ protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $absolute) { - $defaults = array_merge($this->defaults, $defaults); - $tparams = array_merge($defaults, $parameters); + $originParameters = $parameters; + $parameters = array_replace($this->context->getParameters(), $parameters); + $tparams = array_replace($defaults, $parameters); // all params must be given if ($diff = array_diff_key($variables, $tparams)) { @@ -99,8 +108,11 @@ class UrlGenerator implements UrlGeneratorInterface throw new \InvalidArgumentException(sprintf('Parameter "%s" for route "%s" must match "%s" ("%s" given).', $token[3], $name, $requirements[$token[3]], $tparams[$token[3]])); } - // %2F is not valid in a URL, so we don't encode it (which is fine as the requirements explicitely allowed it) - $url = $token[1].str_replace('%2F', '/', urlencode($tparams[$token[3]])).$url; + if (isset($tparams[$token[3]])) { + // %2F is not valid in a URL, so we don't encode it (which is fine as the requirements explicitly allowed it) + $url = $token[1].str_replace('%2F', '/', urlencode($tparams[$token[3]])).$url; + } + $optional = false; } } elseif ('text' === $token[0]) { @@ -120,20 +132,29 @@ class UrlGenerator implements UrlGeneratorInterface } // add a query string if needed - if ($extra = array_diff_key($parameters, $variables, $defaults)) { + if ($extra = array_diff_key($originParameters, $variables, $defaults)) { $url .= '?'.http_build_query($extra); } - $url = (isset($this->context['base_url']) ? $this->context['base_url'] : '').$url; + $url = $this->context->getBaseUrl().$url; - if ($absolute && isset($this->context['host'])) { - $isSecure = (isset($this->context['is_secure']) && $this->context['is_secure']); - $port = isset($this->context['port']) ? $this->context['port'] : 80; - $urlBeginning = 'http'.($isSecure ? 's' : '').'://'.$this->context['host']; - if (($isSecure && $port != 443) || (!$isSecure && $port != 80)) { - $urlBeginning .= ':'.$port; + if ($this->context->getHost()) { + $scheme = $this->context->getScheme(); + if (isset($requirements['_scheme']) && ($req = strtolower($requirements['_scheme'])) && $scheme != $req) { + $absolute = true; + $scheme = $req; + } + + if ($absolute) { + $port = ''; + if ('http' === $scheme && 80 != $this->context->getHttpPort()) { + $port = ':'.$this->context->getHttpPort(); + } elseif ('https' === $scheme && 443 != $this->context->getHttpsPort()) { + $port = ':'.$this->context->getHttpsPort(); + } + + $url = $scheme.'://'.$this->context->getHost().$port.$url; } - $url = $urlBeginning.$url; } return $url; diff --git a/src/Symfony/Component/Routing/Loader/AnnotationFileLoader.php b/src/Symfony/Component/Routing/Loader/AnnotationFileLoader.php index 032d6883c9..3d7dbac5c6 100644 --- a/src/Symfony/Component/Routing/Loader/AnnotationFileLoader.php +++ b/src/Symfony/Component/Routing/Loader/AnnotationFileLoader.php @@ -84,7 +84,7 @@ class AnnotationFileLoader extends FileLoader * * @param string $file A PHP file path * - * @return string|false Full class name if found, false otherwise + * @return string|false Full class name if found, false otherwise */ protected function findClass($file) { diff --git a/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php b/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php index 7576fea804..339715be64 100644 --- a/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php +++ b/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php @@ -39,88 +39,115 @@ class PhpMatcherDumper extends MatcherDumper 'base_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher', ), $options); + // trailing slash support is only enabled if we know how to redirect the user + $interfaces = class_implements($options['base_class']); + $supportsRedirections = isset($interfaces['Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface']); + return $this->startClass($options['class'], $options['base_class']). $this->addConstructor(). - $this->addMatcher(). + $this->addMatcher($supportsRedirections). $this->endClass() ; } - private function addMatcher() + private function addMatcher($supportsRedirections) { $code = array(); foreach ($this->getRoutes()->all() as $name => $route) { $compiledRoute = $route->compile(); - $conditions = array(); - $hasTrailingSlash = false; + $matches = false; if (!count($compiledRoute->getVariables()) && false !== preg_match('#^(.)\^(?P.*?)\$\1#', $compiledRoute->getRegex(), $m)) { - if (substr($m['url'], -1) === '/') { + if ($supportsRedirections && substr($m['url'], -1) === '/') { $conditions[] = sprintf("rtrim(\$pathinfo, '/') === '%s'", rtrim(str_replace('\\', '', $m['url']), '/')); $hasTrailingSlash = true; } else { $conditions[] = sprintf("\$pathinfo === '%s'", str_replace('\\', '', $m['url'])); } - - $matches = 'array()'; } else { if ($compiledRoute->getStaticPrefix()) { $conditions[] = sprintf("0 === strpos(\$pathinfo, '%s')", $compiledRoute->getStaticPrefix()); } $regex = $compiledRoute->getRegex(); - if ($pos = strpos($regex, '/$')) { - $regex = substr($regex, 0, $pos) . '/?$' . substr($regex, $pos+2); - $conditions[] = sprintf("preg_match('%s', \$pathinfo, \$matches)", $regex); + if ($supportsRedirections && $pos = strpos($regex, '/$')) { + $regex = substr($regex, 0, $pos).'/?$'.substr($regex, $pos + 2); $hasTrailingSlash = true; - } else { - $conditions[] = sprintf("preg_match('%s', \$pathinfo, \$matches)", $regex); } + $conditions[] = sprintf("preg_match('%s', \$pathinfo, \$matches)", $regex); - $matches = '$matches'; + $matches = true; } $conditions = implode(' && ', $conditions); $gotoname = 'not_'.preg_replace('/[^A-Za-z0-9_]/', '', $name); - + $code[] = <<getRequirement('_method')) { - $req = implode('\', \'', array_map('strtolower', explode('|', $req))); - $code[] = <<context['method']) && !in_array(strtolower(\$this->context['method']), array('$req'))) { - \$allow = array_merge(\$allow, array('$req')); + $methods = array_map('strtolower', explode('|', $req)); + if (1 === count($methods)) { + $code[] = <<context->getMethod() != '$methods[0]') { + \$allow[] = '$methods[0]'; goto $gotoname; } EOF; + } else { + $methods = implode('\', \'', $methods); + $code[] = <<context->getMethod(), array('$methods'))) { + \$allow = array_merge(\$allow, array('$methods')); + goto $gotoname; + } +EOF; + } } if ($hasTrailingSlash) { $code[] = sprintf(<< 'Symfony\\Bundle\\FrameworkBundle\\Controller\\RedirectController::urlRedirectAction', 'url' => \$this->context['base_url'].\$pathinfo.'/', 'permanent' => true, '_route' => '%s'); + return \$this->redirect(\$pathinfo.'/', '%s'); } EOF - , $name); + , $name); } - $code[] = sprintf(<<mergeDefaults($matches, %s), array('_route' => '%s')); - } + if ($scheme = $route->getRequirement('_scheme')) { + if (!$supportsRedirections) { + throw new \LogicException('The "_scheme" requirement is only supported for route dumper that implements RedirectableUrlMatcherInterface.'); + } + + $code[] = sprintf(<<context->getScheme() !== '$scheme') { + return \$this->redirect(\$pathinfo, '%s', '$scheme'); + } EOF - , str_replace("\n", '', var_export($compiledRoute->getDefaults(), true)), $name); + , $name); + } + + // optimize parameters array + if (true === $matches && $compiledRoute->getDefaults()) { + $code[] = sprintf(" return array_merge(\$this->mergeDefaults(\$matches, %s), array('_route' => '%s'));" + , str_replace("\n", '', var_export($compiledRoute->getDefaults(), true)), $name); + } elseif (true === $matches) { + $code[] = sprintf(" \$matches['_route'] = '%s';\n return \$matches;", $name); + } elseif ($compiledRoute->getDefaults()) { + $code[] = sprintf(' return %s;', str_replace("\n", '', var_export(array_merge($compiledRoute->getDefaults(), array('_route' => $name)), true))); + } else { + $code[] = sprintf(" return array('_route' => '%s');", $name); + } + $code[] = " }"; if ($req) { - $code[] = <<context = \$context; - \$this->defaults = \$defaults; } EOF; diff --git a/src/Symfony/Component/Routing/Matcher/RedirectableUrlMatcher.php b/src/Symfony/Component/Routing/Matcher/RedirectableUrlMatcher.php new file mode 100644 index 0000000000..e18ea8df2f --- /dev/null +++ b/src/Symfony/Component/Routing/Matcher/RedirectableUrlMatcher.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Matcher; + +use Symfony\Component\Routing\Matcher\Exception\NotFoundException; + +/** + * @author Fabien Potencier + */ +abstract class RedirectableUrlMatcher extends UrlMatcher implements RedirectableUrlMatcherInterface +{ + private $trailingSlashTest = false; + + /** + * @see UrlMatcher::match() + */ + public function match($pathinfo) + { + try { + $parameters = parent::match($pathinfo); + } catch (NotFoundException $e) { + if ('/' === substr($pathinfo, -1)) { + throw $e; + } + + // try with a / at the end + $this->trailingSlashTest = true; + + return $this->match($pathinfo.'/'); + } + + if ($this->trailingSlashTest) { + $this->trailingSlashTest = false; + + return $this->redirect($pathinfo, null); + } + + return $parameters; + } +} diff --git a/src/Symfony/Component/Routing/Matcher/RedirectableUrlMatcherInterface.php b/src/Symfony/Component/Routing/Matcher/RedirectableUrlMatcherInterface.php new file mode 100644 index 0000000000..3ed93e7a52 --- /dev/null +++ b/src/Symfony/Component/Routing/Matcher/RedirectableUrlMatcherInterface.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Matcher; + +/** + * RedirectableUrlMatcherInterface knows how to redirect the user. + * + * @author Fabien Potencier + */ +interface RedirectableUrlMatcherInterface +{ + /** + * Redirects the user to another URL. + * + * @param string $path The path info to redirect to. + * @param string $route The route that matched + * @param string $scheme The URL scheme (null to keep the current one) + * + * @return array An array of parameters + */ + function redirect($path, $route, $scheme = null); +} diff --git a/src/Symfony/Component/Routing/Matcher/UrlMatcher.php b/src/Symfony/Component/Routing/Matcher/UrlMatcher.php index ab47ed1bf2..aa1ddf4db6 100644 --- a/src/Symfony/Component/Routing/Matcher/UrlMatcher.php +++ b/src/Symfony/Component/Routing/Matcher/UrlMatcher.php @@ -15,6 +15,7 @@ use Symfony\Component\Routing\Matcher\Exception\MethodNotAllowedException; use Symfony\Component\Routing\Matcher\Exception\NotFoundException; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Routing\RequestContext; /** * UrlMatcher matches URL based on a set of routes. @@ -23,7 +24,6 @@ use Symfony\Component\Routing\RouteCollection; */ class UrlMatcher implements UrlMatcherInterface { - protected $defaults; protected $context; private $routes; @@ -32,26 +32,34 @@ class UrlMatcher implements UrlMatcherInterface * Constructor. * * @param RouteCollection $routes A RouteCollection instance - * @param array $context The context - * @param array $defaults The default values + * @param RequestContext $context The context */ - public function __construct(RouteCollection $routes, array $context = array(), array $defaults = array()) + public function __construct(RouteCollection $routes, RequestContext $context) { $this->routes = $routes; $this->context = $context; - $this->defaults = $defaults; } /** * Sets the request context. * - * @param array $context The context + * @param RequestContext $context The context */ - public function setContext(array $context = array()) + public function setContext(RequestContext $context) { $this->context = $context; } + /** + * Gets the request context. + * + * @return RequestContext The context + */ + public function getContext() + { + return $this->context; + } + /** * Tries to match a URL with a set of routes. * @@ -79,7 +87,7 @@ class UrlMatcher implements UrlMatcherInterface } // check HTTP method requirement - if (isset($this->context['method']) && $route->getRequirement('_method') && ($req = explode('|', $route->getRequirement('_method'))) && !in_array(strtolower($this->context['method']), array_map('strtolower', $req))) { + if ($route->getRequirement('_method') && ($req = explode('|', $route->getRequirement('_method'))) && !in_array($this->context->getMethod(), array_map('strtolower', $req))) { $allow = array_merge($allow, $req); continue; } @@ -94,7 +102,7 @@ class UrlMatcher implements UrlMatcherInterface protected function mergeDefaults($params, $defaults) { - $parameters = array_merge($this->defaults, $defaults); + $parameters = $defaults; foreach ($params as $key => $value) { if (!is_int($key)) { $parameters[$key] = urldecode($value); diff --git a/src/Symfony/Component/Routing/RequestContext.php b/src/Symfony/Component/Routing/RequestContext.php new file mode 100644 index 0000000000..1110efe222 --- /dev/null +++ b/src/Symfony/Component/Routing/RequestContext.php @@ -0,0 +1,230 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing; + +/** + * Holds information about the current request. + * + * @author Fabien Potencier + */ +class RequestContext +{ + private $baseUrl; + private $method; + private $host; + private $scheme; + private $httpPort; + private $httpsPort; + private $parameters; + + /** + * Constructor. + * + * @param string $baseUrl The base URL + * @param string $method The HTTP method + * @param string $host The HTTP host name + * @param string $scheme The HTTP scheme + * @param integer $httpPort The HTTP port + * @param integer $httpsPort The HTTPS port + */ + public function __construct($baseUrl = '', $method = 'get', $host = 'localhost', $scheme = 'http', $httpPort = 80, $httpsPort = 443) + { + $this->baseUrl = $baseUrl; + $this->method = strtolower($method); + $this->host = $host; + $this->scheme = strtolower($scheme); + $this->httpPort = $httpPort; + $this->httpsPort = $httpsPort; + $this->parameters = array(); + } + + /** + * Gets the base URL. + * + * @return string The base URL + */ + public function getBaseUrl() + { + return $this->baseUrl; + } + + /** + * Sets the base URL. + * + * @param string $baseUrl The base URL + */ + public function setBaseUrl($baseUrl) + { + $this->baseUrl = $baseUrl; + } + + /** + * Gets the HTTP method. + * + * @return string The HTTP method + */ + public function getMethod() + { + return $this->method; + } + + /** + * Sets the HTTP method. + * + * @param string $method The HTTP method + */ + public function setMethod($method) + { + $this->method = strtolower($method); + } + + /** + * Gets the HTTP host. + * + * @return string The HTTP host + */ + public function getHost() + { + return $this->host; + } + + /** + * Sets the HTTP host. + * + * @param string $host The HTTP host + */ + public function setHost($host) + { + $this->host = $host; + } + + /** + * Gets the HTTP scheme. + * + * @return string The HTTP scheme + */ + public function getScheme() + { + return $this->scheme; + } + + /** + * Sets the HTTP scheme. + * + * @param string $scheme The HTTP scheme + */ + public function setScheme($scheme) + { + $this->scheme = strtolower($scheme); + } + + /** + * Gets the HTTP port. + * + * @return string The HTTP port + */ + public function getHttpPort() + { + return $this->httpPort; + } + + /** + * Sets the HTTP port. + * + * @param string $httpPort The HTTP port + */ + public function setHttpPort($httpPort) + { + $this->httpPort = $httpPort; + } + + /** + * Gets the HTTPS port. + * + * @return string The HTTPS port + */ + public function getHttpsPort() + { + return $this->httpsPort; + } + + /** + * Sets the HTTPS port. + * + * @param string $httpsPort The HTTPS port + */ + public function setHttpsPort($httpsPort) + { + $this->httpsPort = $httpsPort; + } + + /** + * Returns the parameters. + * + * @return array The parameters + */ + public function getParameters() + { + return $this->parameters; + } + + /** + * Sets the parameters. + * + * This method implements a fluent interface. + * + * @param array $parameters The parameters + * + * @return Route The current Route instance + */ + public function setParameters(array $parameters) + { + $this->parameters = $parameters; + + return $this; + } + + /** + * Gets a parameter value. + * + * @param string $name A parameter name + * + * @return mixed The parameter value + */ + public function getParameter($name) + { + return isset($this->parameters[$name]) ? $this->parameters[$name] : null; + } + + /** + * Checks if a parameter value is set for the given parameter. + * + * @param string $name A parameter name + * + * @return Boolean true if the parameter value is set, false otherwise + */ + public function hasParameter($name) + { + return array_key_exists($name, $this->parameters); + } + + /** + * Sets a parameter value. + * + * @param string $name A parameter name + * @param mixed $parameter The parameter value + */ + public function setParameter($name, $parameter) + { + $this->parameters[$name] = $parameter; + } +} diff --git a/src/Symfony/Component/Routing/Route.php b/src/Symfony/Component/Routing/Route.php index fb2e90507d..bcd54e506e 100644 --- a/src/Symfony/Component/Routing/Route.php +++ b/src/Symfony/Component/Routing/Route.php @@ -159,6 +159,18 @@ class Route return isset($this->defaults[$name]) ? $this->defaults[$name] : null; } + /** + * Checks if a default value is set for the given variable. + * + * @param string $name A variable name + * + * @return Boolean true if the default value is set, false otherwise + */ + public function hasDefault($name) + { + return array_key_exists($name, $this->defaults); + } + /** * Sets a default value. * diff --git a/src/Symfony/Component/Routing/RouteCompiler.php b/src/Symfony/Component/Routing/RouteCompiler.php index 0bff64903e..7c1bd5da5e 100644 --- a/src/Symfony/Component/Routing/RouteCompiler.php +++ b/src/Symfony/Component/Routing/RouteCompiler.php @@ -212,7 +212,7 @@ class RouteCompiler implements RouteCompilerInterface $this->segments[] = preg_quote($separator, '#').'(?P<'.$variable.'>'.$requirement.')'; $this->variables[$variable] = $name; - if (null === $this->route->getDefault($variable)) { + if (!$this->route->hasDefault($variable)) { $this->firstOptional = count($this->segments); } } diff --git a/src/Symfony/Component/Routing/Router.php b/src/Symfony/Component/Routing/Router.php index 5e5961d5e4..6459fc658e 100644 --- a/src/Symfony/Component/Routing/Router.php +++ b/src/Symfony/Component/Routing/Router.php @@ -48,11 +48,11 @@ class Router implements RouterInterface * * @throws \InvalidArgumentException When unsupported option is provided */ - public function __construct(LoaderInterface $loader, $resource, array $options = array(), array $context = array(), array $defaults = array()) + public function __construct(LoaderInterface $loader, $resource, array $options = array(), RequestContext $context = null, array $defaults = array()) { $this->loader = $loader; $this->resource = $resource; - $this->context = $context; + $this->context = null === $context ? new RequestContext() : $context; $this->defaults = $defaults; $this->options = array( 'cache_dir' => null, @@ -102,14 +102,26 @@ class Router implements RouterInterface /** * Sets the request context. * - * @param array $context The context + * @param RequestContext $context The context */ - public function setContext(array $context = array()) + public function setContext(RequestContext $context) { + $this->context = $context; + $this->getMatcher()->setContext($context); $this->getGenerator()->setContext($context); } + /** + * Gets the request context. + * + * @return RequestContext The context + */ + public function getContext() + { + return $this->context; + } + /** * Generates a URL from the given parameters. * diff --git a/src/Symfony/Component/Security/Acl/Dbal/MutableAclProvider.php b/src/Symfony/Component/Security/Acl/Dbal/MutableAclProvider.php index 52d1a9b8f0..62667c8939 100644 --- a/src/Symfony/Component/Security/Acl/Dbal/MutableAclProvider.php +++ b/src/Symfony/Component/Security/Acl/Dbal/MutableAclProvider.php @@ -776,7 +776,7 @@ QUERY; $aceId = $this->connection->executeQuery($this->getSelectAccessControlEntryIdSql($classId, $objectIdentityId, $field, $i))->fetchColumn(); $this->loadedAces[$aceId] = $ace; - $aceIdProperty = new \ReflectionProperty($ace, 'id'); + $aceIdProperty = new \ReflectionProperty('Symfony\Component\Security\Acl\Domain\Entry', 'id'); $aceIdProperty->setAccessible(true); $aceIdProperty->setValue($ace, intval($aceId)); } else { diff --git a/src/Symfony/Component/Security/Acl/Domain/Acl.php b/src/Symfony/Component/Security/Acl/Domain/Acl.php index 20f300b539..09bcb34390 100644 --- a/src/Symfony/Component/Security/Acl/Domain/Acl.php +++ b/src/Symfony/Component/Security/Acl/Domain/Acl.php @@ -10,6 +10,7 @@ namespace Symfony\Component\Security\Acl\Domain; +use Doctrine\Common\NotifyPropertyChanged; use Doctrine\Common\PropertyChangedListener; use Symfony\Component\Security\Acl\Model\AclInterface; use Symfony\Component\Security\Acl\Model\AuditableAclInterface; @@ -33,7 +34,7 @@ use Symfony\Component\Security\Acl\Model\SecurityIdentityInterface; * * @author Johannes M. Schmitt */ -class Acl implements AuditableAclInterface +class Acl implements AuditableAclInterface, NotifyPropertyChanged { private $parentAcl; private $permissionGrantingStrategy; diff --git a/src/Symfony/Component/Security/Acl/Domain/FieldEntry.php b/src/Symfony/Component/Security/Acl/Domain/FieldEntry.php index 0f71237831..1510df2411 100644 --- a/src/Symfony/Component/Security/Acl/Domain/FieldEntry.php +++ b/src/Symfony/Component/Security/Acl/Domain/FieldEntry.php @@ -12,7 +12,7 @@ namespace Symfony\Component\Security\Acl\Domain; use Symfony\Component\Security\Acl\Model\AclInterface; -use Symfony\Component\Security\Acl\Model\FieldAwareEntryInterface; +use Symfony\Component\Security\Acl\Model\FieldEntryInterface; use Symfony\Component\Security\Acl\Model\SecurityIdentityInterface; /** @@ -20,7 +20,7 @@ use Symfony\Component\Security\Acl\Model\SecurityIdentityInterface; * * @author Johannes M. Schmitt */ -class FieldEntry extends Entry implements FieldAwareEntryInterface +class FieldEntry extends Entry implements FieldEntryInterface { private $field; diff --git a/src/Symfony/Component/Security/Acl/Domain/PermissionGrantingStrategy.php b/src/Symfony/Component/Security/Acl/Domain/PermissionGrantingStrategy.php index 8bee157ae4..37bbe4eb0f 100644 --- a/src/Symfony/Component/Security/Acl/Domain/PermissionGrantingStrategy.php +++ b/src/Symfony/Component/Security/Acl/Domain/PermissionGrantingStrategy.php @@ -30,16 +30,8 @@ class PermissionGrantingStrategy implements PermissionGrantingStrategyInterface const ALL = 'all'; const ANY = 'any'; - private static $noAceException; private $auditLogger; - public function __construct() - { - if (null === static::$noAceException) { - static::$noAceException = new NoAceFoundException('No ACE.'); - } - } - /** * Sets the audit logger * @@ -61,7 +53,7 @@ class PermissionGrantingStrategy implements PermissionGrantingStrategyInterface $aces = $acl->getObjectAces(); if (!$aces) { - throw static::$noAceException; + throw new NoAceFoundException(); } return $this->hasSufficientPermissions($acl, $aces, $masks, $sids, $administrativeMode); @@ -69,7 +61,7 @@ class PermissionGrantingStrategy implements PermissionGrantingStrategyInterface $aces = $acl->getClassAces(); if (!$aces) { - throw static::$noAceException; + throw $noObjectAce; } return $this->hasSufficientPermissions($acl, $aces, $masks, $sids, $administrativeMode); @@ -79,7 +71,7 @@ class PermissionGrantingStrategy implements PermissionGrantingStrategyInterface return $parentAcl->isGranted($masks, $sids, $administrativeMode); } - throw new NoAceFoundException('No applicable ACE was found.'); + throw $noClassAce; } } @@ -92,14 +84,14 @@ class PermissionGrantingStrategy implements PermissionGrantingStrategyInterface try { $aces = $acl->getObjectFieldAces($field); if (!$aces) { - throw static::$noAceException; + throw new NoAceFoundException(); } return $this->hasSufficientPermissions($acl, $aces, $masks, $sids, $administrativeMode); } catch (NoAceFoundException $noObjectAces) { $aces = $acl->getClassFieldAces($field); if (!$aces) { - throw static::$noAceException; + throw $noObjectAces; } return $this->hasSufficientPermissions($acl, $aces, $masks, $sids, $administrativeMode); @@ -109,7 +101,7 @@ class PermissionGrantingStrategy implements PermissionGrantingStrategyInterface return $parentAcl->isFieldGranted($field, $masks, $sids, $administrativeMode); } - throw new NoAceFoundException('No applicable ACE was found.'); + throw $noClassAces; } } @@ -177,7 +169,7 @@ class PermissionGrantingStrategy implements PermissionGrantingStrategyInterface return false; } - throw static::$noAceException; + throw new NoAceFoundException(); } /** diff --git a/src/Symfony/Component/Security/Acl/Exception/NoAceFoundException.php b/src/Symfony/Component/Security/Acl/Exception/NoAceFoundException.php index 0ecad61349..994efc012b 100644 --- a/src/Symfony/Component/Security/Acl/Exception/NoAceFoundException.php +++ b/src/Symfony/Component/Security/Acl/Exception/NoAceFoundException.php @@ -19,4 +19,8 @@ namespace Symfony\Component\Security\Acl\Exception; */ class NoAceFoundException extends Exception { + public function __construct() + { + parent::__construct('No applicable ACE was found.'); + } } \ No newline at end of file diff --git a/src/Symfony/Component/Security/Acl/Model/FieldAwareEntryInterface.php b/src/Symfony/Component/Security/Acl/Model/FieldEntryInterface.php similarity index 75% rename from src/Symfony/Component/Security/Acl/Model/FieldAwareEntryInterface.php rename to src/Symfony/Component/Security/Acl/Model/FieldEntryInterface.php index 032d6e34a1..68aa10c9f1 100644 --- a/src/Symfony/Component/Security/Acl/Model/FieldAwareEntryInterface.php +++ b/src/Symfony/Component/Security/Acl/Model/FieldEntryInterface.php @@ -16,7 +16,12 @@ namespace Symfony\Component\Security\Acl\Model; * * @author Johannes M. Schmitt */ -interface FieldAwareEntryInterface +interface FieldEntryInterface extends EntryInterface { + /** + * Returns the field used for this entry. + * + * @return string + */ function getField(); } \ No newline at end of file diff --git a/src/Symfony/Component/Security/Acl/Model/MutableAclInterface.php b/src/Symfony/Component/Security/Acl/Model/MutableAclInterface.php index 4e52e65cef..fdd671236b 100644 --- a/src/Symfony/Component/Security/Acl/Model/MutableAclInterface.php +++ b/src/Symfony/Component/Security/Acl/Model/MutableAclInterface.php @@ -11,8 +11,6 @@ namespace Symfony\Component\Security\Acl\Model; -use Doctrine\Common\NotifyPropertyChanged; - /** * This interface adds mutators for the AclInterface. * @@ -21,7 +19,7 @@ use Doctrine\Common\NotifyPropertyChanged; * * @author Johannes M. Schmitt */ -interface MutableAclInterface extends AclInterface, NotifyPropertyChanged +interface MutableAclInterface extends AclInterface { /** * Deletes a class-based ACE diff --git a/src/Symfony/Component/Security/Core/Authentication/Provider/DaoAuthenticationProvider.php b/src/Symfony/Component/Security/Core/Authentication/Provider/DaoAuthenticationProvider.php index 21bec8292a..fa08955969 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Provider/DaoAuthenticationProvider.php +++ b/src/Symfony/Component/Security/Core/Authentication/Provider/DaoAuthenticationProvider.php @@ -59,11 +59,11 @@ class DaoAuthenticationProvider extends UserAuthenticationProvider } } else { if (!$presentedPassword = $token->getCredentials()) { - throw new BadCredentialsException('Bad credentials'); + throw new BadCredentialsException('The presented password cannot be empty.'); } if (!$this->encoderFactory->getEncoder($user)->isPasswordValid($user->getPassword(), $presentedPassword, $user->getSalt())) { - throw new BadCredentialsException('Bad credentials'); + throw new BadCredentialsException('The presented password is invalid.'); } } } diff --git a/src/Symfony/Component/Security/Core/Authentication/RememberMe/PersistentTokenInterface.php b/src/Symfony/Component/Security/Core/Authentication/RememberMe/PersistentTokenInterface.php index bfd077e151..fe1db512d6 100644 --- a/src/Symfony/Component/Security/Core/Authentication/RememberMe/PersistentTokenInterface.php +++ b/src/Symfony/Component/Security/Core/Authentication/RememberMe/PersistentTokenInterface.php @@ -14,7 +14,7 @@ namespace Symfony\Component\Security\Core\Authentication\RememberMe; /** * Interface to be implemented by persistent token classes (such as * Doctrine entities representing a remember-me token) - * + * * @author Johannes M. Schmitt */ interface PersistentTokenInterface @@ -24,19 +24,19 @@ interface PersistentTokenInterface * @return string */ function getUsername(); - + /** * Returns the series * @return string */ function getSeries(); - + /** * Returns the token value * @return string */ function getTokenValue(); - + /** * Returns the last time the cookie was used * @return \DateTime diff --git a/src/Symfony/Component/Security/Core/Exception/CookieTheftException.php b/src/Symfony/Component/Security/Core/Exception/CookieTheftException.php index 6dbead5462..83e61d737f 100644 --- a/src/Symfony/Component/Security/Core/Exception/CookieTheftException.php +++ b/src/Symfony/Component/Security/Core/Exception/CookieTheftException.php @@ -14,7 +14,7 @@ namespace Symfony\Component\Security\Core\Exception; /** * This exception is thrown when the RememberMeServices implementation * detects that a presented cookie has already been used by someone else. - * + * * @author Johannes M. Schmitt */ class CookieTheftException extends AuthenticationException diff --git a/src/Symfony/Component/Security/Core/Exception/TokenNotFoundException.php b/src/Symfony/Component/Security/Core/Exception/TokenNotFoundException.php index f25905d3f7..593f3ad269 100644 --- a/src/Symfony/Component/Security/Core/Exception/TokenNotFoundException.php +++ b/src/Symfony/Component/Security/Core/Exception/TokenNotFoundException.php @@ -1,4 +1,4 @@ -alwaysAuthenticate = $alwaysAuthenticate; } + /** + * Checks if the attributes are granted against the current token. + * + * @throws AuthenticationCredentialsNotFoundException when the security context has no authentication token. + * @param mixed $attributes + * @param mixed|null $object + * @return boolean + */ public final function isGranted($attributes, $object = null) { if (null === $this->token) { diff --git a/src/Symfony/Component/Security/Core/SecurityContextInterface.php b/src/Symfony/Component/Security/Core/SecurityContextInterface.php index a811557727..c54ca0e3c9 100644 --- a/src/Symfony/Component/Security/Core/SecurityContextInterface.php +++ b/src/Symfony/Component/Security/Core/SecurityContextInterface.php @@ -15,7 +15,27 @@ interface SecurityContextInterface const AUTHENTICATION_ERROR = '_security.last_error'; const LAST_USERNAME = '_security.last_username'; + /** + * Returns the current security token. + * + * @return TokenInterface|null A TokenInterface instance or null if no authentication information is available + */ function getToken(); - function setToken(TokenInterface $token); + + /** + * Sets the authentication token. + * + * @param TokenInterface $token + * @return void + */ + function setToken(TokenInterface $token = null); + + /** + * Checks if the attributes are granted against the current authentication token and optionally supplied object. + * + * @param array $attributes + * @param mixed $object + * @return boolean + */ function isGranted($attributes, $object = null); } \ No newline at end of file diff --git a/src/Symfony/Component/Security/Http/EntryPoint/RetryAuthenticationEntryPoint.php b/src/Symfony/Component/Security/Http/EntryPoint/RetryAuthenticationEntryPoint.php index 114d12282e..cb549e6c20 100644 --- a/src/Symfony/Component/Security/Http/EntryPoint/RetryAuthenticationEntryPoint.php +++ b/src/Symfony/Component/Security/Http/EntryPoint/RetryAuthenticationEntryPoint.php @@ -51,7 +51,7 @@ class RetryAuthenticationEntryPoint implements AuthenticationEntryPointInterface $qs = '?'.$qs; } - $url = $scheme.'://'.$request->getHost().$port.$request->getScriptName().$request->getPathInfo().$qs; + $url = $scheme.'://'.$request->getHost().$port.$request->getBaseUrl().$request->getPathInfo().$qs; return new RedirectResponse($url, 301); } diff --git a/src/Symfony/Component/Security/Http/Firewall.php b/src/Symfony/Component/Security/Http/Firewall.php index 7bdda2a353..d5af39b5c6 100644 --- a/src/Symfony/Component/Security/Http/Firewall.php +++ b/src/Symfony/Component/Security/Http/Firewall.php @@ -12,7 +12,6 @@ namespace Symfony\Component\Security\Http; use Symfony\Component\HttpKernel\HttpKernelInterface; -use Symfony\Component\HttpKernel\Events; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\EventDispatcher\EventDispatcherInterface; diff --git a/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php b/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php index 5d69aa25d4..0977cb16fe 100644 --- a/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Security\Http\Firewall; +use Symfony\Component\Security\Core\Exception\AccessDeniedException; use Symfony\Component\Security\Core\SecurityContextInterface; use Symfony\Component\Security\Core\User\UserProviderInterface; use Symfony\Component\Security\Core\User\UserCheckerInterface; @@ -112,7 +113,9 @@ class SwitchUserListener implements ListenerInterface throw new \LogicException(sprintf('You are already switched to "%s" user.', $token->getUsername())); } - $this->accessDecisionManager->decide($token, array($this->role)); + if (false === $this->accessDecisionManager->decide($token, array($this->role))) { + throw new AccessDeniedException(); + } $username = $request->get($this->usernameParameter); diff --git a/src/Symfony/Component/Serializer/Encoder/AbstractEncoder.php b/src/Symfony/Component/Serializer/Encoder/AbstractEncoder.php index eb7245d6f7..a2e9035696 100644 --- a/src/Symfony/Component/Serializer/Encoder/AbstractEncoder.php +++ b/src/Symfony/Component/Serializer/Encoder/AbstractEncoder.php @@ -3,6 +3,7 @@ namespace Symfony\Component\Serializer\Encoder; use Symfony\Component\Serializer\SerializerInterface; +use Symfony\Component\Serializer\SerializerAwareInterface; /* * This file is part of the Symfony framework. @@ -18,7 +19,7 @@ use Symfony\Component\Serializer\SerializerInterface; * * @author Jordi Boggiano */ -abstract class AbstractEncoder implements EncoderInterface +abstract class AbstractEncoder implements SerializerAwareInterface, EncoderInterface { protected $serializer; @@ -37,4 +38,4 @@ abstract class AbstractEncoder implements EncoderInterface { return $this->serializer; } -} \ No newline at end of file +} diff --git a/src/Symfony/Component/Serializer/Encoder/DecoderInterface.php b/src/Symfony/Component/Serializer/Encoder/DecoderInterface.php new file mode 100644 index 0000000000..ab49c69fab --- /dev/null +++ b/src/Symfony/Component/Serializer/Encoder/DecoderInterface.php @@ -0,0 +1,32 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * Defines the interface of encoders + * + * @author Jordi Boggiano + */ +interface DecoderInterface +{ + /** + * Decodes a string into PHP data + * + * @param string $data data to decode + * @param string $format format to decode from + * @return mixed + * @api + */ + function decode($data, $format); +} diff --git a/src/Symfony/Component/Serializer/Encoder/EncoderInterface.php b/src/Symfony/Component/Serializer/Encoder/EncoderInterface.php index 0a97b1c940..e2044404ea 100644 --- a/src/Symfony/Component/Serializer/Encoder/EncoderInterface.php +++ b/src/Symfony/Component/Serializer/Encoder/EncoderInterface.php @@ -26,29 +26,7 @@ interface EncoderInterface * @param mixed $data data to encode * @param string $format format to encode to * @return string + * @api */ function encode($data, $format); - - /** - * Decodes a string into PHP data - * - * @param string $data data to decode - * @param string $format format to decode from - * @return mixed - */ - function decode($data, $format); - - /** - * Sets the owning Serializer object - * - * @param SerializerInterface $serializer - */ - function setSerializer(SerializerInterface $serializer); - - /** - * Gets the owning Serializer object - * - * @return SerializerInterface - */ - function getSerializer(); } diff --git a/src/Symfony/Component/Serializer/Encoder/JsonEncoder.php b/src/Symfony/Component/Serializer/Encoder/JsonEncoder.php index 31e4b001c0..5ab6876430 100644 --- a/src/Symfony/Component/Serializer/Encoder/JsonEncoder.php +++ b/src/Symfony/Component/Serializer/Encoder/JsonEncoder.php @@ -18,7 +18,7 @@ use Symfony\Component\Serializer\SerializerInterface; * * @author Jordi Boggiano */ -class JsonEncoder extends AbstractEncoder +class JsonEncoder extends AbstractEncoder implements DecoderInterface { /** * {@inheritdoc} diff --git a/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php b/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php index c09d89b62c..19ff4b476c 100644 --- a/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php +++ b/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php @@ -20,11 +20,11 @@ use Symfony\Component\Serializer\SerializerInterface; * @author John Wards * @author Fabian Vogler */ -class XmlEncoder extends AbstractEncoder +class XmlEncoder extends AbstractEncoder implements DecoderInterface { - protected $dom; - protected $format; - protected $rootNodeName = 'response'; + private $dom; + private $format; + private $rootNodeName = 'response'; /** * {@inheritdoc} @@ -78,13 +78,83 @@ class XmlEncoder extends AbstractEncoder return $this->rootNodeName; } + /** + * @param DOMNode $node + * @param string $val + * @return Boolean + */ + final protected function appendXMLString($node, $val) + { + if (strlen($val) > 0) { + $frag = $this->dom->createDocumentFragment(); + $frag->appendXML($val); + $node->appendChild($frag); + return true; + } + + return false; + } + + /** + * @param DOMNode $node + * @param string $val + * @return Boolean + */ + final protected function appendText($node, $val) + { + $nodeText = $this->dom->createTextNode($val); + $node->appendChild($nodeText); + + return true; + } + + /** + * @param DOMNode $node + * @param string $val + * @return Boolean + */ + final protected function appendCData($node, $val) + { + $nodeText = $this->dom->createCDATASection($val); + $node->appendChild($nodeText); + + return true; + } + + /** + * @param DOMNode $node + * @param DOMDocumentFragment $fragment + * @return Boolean + */ + final protected function appendDocumentFragment($node, $fragment) + { + if ($fragment instanceof \DOMDocumentFragment) { + $node->appendChild($fragment); + return true; + } + + return false; + } + + /** + * Checks the name is avalid xml element name + * @param string $name + * @return Boolean + */ + final protected function isElementNameValid($name) + { + return $name && + false === strpos($name, ' ') && + preg_match('#^[\pL_][\pL0-9._-]*$#ui', $name); + } + /** * Parse the input SimpleXmlElement into an array * * @param SimpleXmlElement $node xml to parse * @return array */ - protected function parseXml($node) + private function parseXml($node) { $data = array(); foreach ($node->children() as $key => $subnode) { @@ -95,12 +165,19 @@ class XmlEncoder extends AbstractEncoder $value['@'.$attrkey] = (string) $attr; } } + } elseif ($subnode->attributes()) { + $value = array(); + foreach ($subnode->attributes() as $attrkey => $attr) { + $value['@'.$attrkey] = (string) $attr; + } + $value['#'] = (string) $subnode; } else { $value = (string) $subnode; } + if ($key === 'item') { - if (isset($subnode['key'])) { - $data[(string)$subnode['key']] = $value; + if (isset($value['@key'])) { + $data[(string)$value['@key']] = $value['#']; } elseif (isset($data['item'])) { $tmp = $data['item']; unset($data['item']); @@ -108,7 +185,7 @@ class XmlEncoder extends AbstractEncoder $data[] = $value; } } elseif (key_exists($key, $data)) { - if (false === is_array($data[$key])) { + if ((false === is_array($data[$key])) || (false === isset($data[$key][0]))) { $data[$key] = array($data[$key]); } $data[$key][] = $value; @@ -126,7 +203,7 @@ class XmlEncoder extends AbstractEncoder * @param array|object $data data * @return bool */ - protected function buildXml($parentNode, $data) + private function buildXml($parentNode, $data) { $append = true; @@ -135,6 +212,8 @@ class XmlEncoder extends AbstractEncoder //Ah this is the magic @ attribute types. if (0 === strpos($key, "@") && is_scalar($data) && $this->isElementNameValid($attributeName = substr($key,1))) { $parentNode->setAttribute($attributeName, $data); + } elseif ($key === '#') { + $append = $this->selectNodeType($parentNode, $data); } elseif (is_array($data) && false === is_numeric($key)) { /** * Is this array fully numeric keys? @@ -183,7 +262,7 @@ class XmlEncoder extends AbstractEncoder * @param $nodename * @return void */ - protected function appendNode($parentNode, $data, $nodeName, $key = null) + private function appendNode($parentNode, $data, $nodeName, $key = null) { $node = $this->dom->createElement($nodeName); if (null !== $key) { @@ -204,7 +283,7 @@ class XmlEncoder extends AbstractEncoder * @param mixed $val * @return Boolean */ - protected function selectNodeType($node, $val) + private function selectNodeType($node, $val) { if (is_array($val)) { return $this->buildXml($node, $val); @@ -228,74 +307,4 @@ class XmlEncoder extends AbstractEncoder return true; } - - /** - * @param DOMNode $node - * @param string $val - * @return Boolean - */ - protected function appendXMLString($node, $val) - { - if (strlen($val) > 0) { - $frag = $this->dom->createDocumentFragment(); - $frag->appendXML($val); - $node->appendChild($frag); - return true; - } - - return false; - } - - /** - * @param DOMNode $node - * @param string $val - * @return Boolean - */ - protected function appendText($node, $val) - { - $nodeText = $this->dom->createTextNode($val); - $node->appendChild($nodeText); - - return true; - } - - /** - * @param DOMNode $node - * @param string $val - * @return Boolean - */ - protected function appendCData($node, $val) - { - $nodeText = $this->dom->createCDATASection($val); - $node->appendChild($nodeText); - - return true; - } - - /** - * @param DOMNode $node - * @param DOMDocumentFragment $fragment - * @return Boolean - */ - protected function appendDocumentFragment($node, $fragment) - { - if ($fragment instanceof \DOMDocumentFragment) { - $node->appendChild($fragment); - return true; - } - - return false; - } - - /** - * Checks the name is avalid xml element name - * @param string $name - * @return Boolean - */ - protected function isElementNameValid($name) - { - return $name && - false === strpos($name, ' ') && - preg_match('#^[\pL_][\pL0-9._-]*$#ui', $name); - } } diff --git a/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php index 3c34522b65..da41892bcf 100644 --- a/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php @@ -133,7 +133,7 @@ class GetSetMethodNormalizer extends AbstractNormalizer * @param ReflectionMethod $method the method to check * @return Boolean whether the method is a getter. */ - protected function isGetMethod(\ReflectionMethod $method) + private function isGetMethod(\ReflectionMethod $method) { return ( 0 === strpos($method->getName(), 'get') && diff --git a/src/Symfony/Component/Serializer/Normalizer/NormalizableInterface.php b/src/Symfony/Component/Serializer/Normalizer/NormalizableInterface.php index f3120e64d1..7e5ef795ae 100644 --- a/src/Symfony/Component/Serializer/Normalizer/NormalizableInterface.php +++ b/src/Symfony/Component/Serializer/Normalizer/NormalizableInterface.php @@ -21,6 +21,35 @@ namespace Symfony\Component\Serializer\Normalizer; */ interface NormalizableInterface { + /** + * Normalizes the object into an array of scalars|arrays. + * + * It is important to understand that the normalize() call should normalize + * recursively all child objects of the implementor. + * + * @param NormalizerInterface $normalizer The normalizer is given so that you + * can use it to normalize objects contained within this object, eventually + * grabbing the serializer from it to access other normalizers. + * @param string|null $format The format is optionally given to be able to normalize differently + * based on different output formats. + * @param array|null $properties If provided, this is a (subset) list of + * properties that should be exported from the object. + * @return array|scalar + */ function normalize(NormalizerInterface $normalizer, $format, $properties = null); + + /** + * Denormalizes the object back from an array of scalars|arrays. + * + * It is important to understand that the normalize() call should denormalize + * recursively all child objects of the implementor. + * + * @param NormalizerInterface $normalizer The normalizer is given so that you + * can use it to denormalize objects contained within this object, eventually + * grabbing the serializer from it to access other normalizers. + * @param array|scalar $data The data from which to re-create the object. + * @param string|null $format The format is optionally given to be able to denormalize differently + * based on different input formats. + */ function denormalize(NormalizerInterface $normalizer, $data, $format = null); } diff --git a/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php b/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php index e616f5d4af..2cbae9ccaa 100644 --- a/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php +++ b/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php @@ -27,6 +27,7 @@ interface NormalizerInterface * @param string $format format the normalization result will be encoded as * @param array $properties a list of properties to extract, if null all properties are returned * @return array|scalar + * @api */ function normalize($object, $format, $properties = null); @@ -37,6 +38,7 @@ interface NormalizerInterface * @param string $class the expected class to instantiate * @param string $format format the given data was extracted from * @return object + * @api */ function denormalize($data, $class, $format = null); @@ -46,6 +48,7 @@ interface NormalizerInterface * @param ReflectionClass $class * @param string $format format the given data was extracted from * @return Boolean + * @api */ function supports(\ReflectionClass $class, $format = null); @@ -53,6 +56,7 @@ interface NormalizerInterface * Sets the owning Serializer object * * @param SerializerInterface $serializer + * @api */ function setSerializer(SerializerInterface $serializer); @@ -60,6 +64,7 @@ interface NormalizerInterface * Gets the owning Serializer object * * @return SerializerInterface + * @api */ function getSerializer(); } diff --git a/src/Symfony/Component/Serializer/Serializer.php b/src/Symfony/Component/Serializer/Serializer.php index 0d5f058470..d46c1ee36e 100644 --- a/src/Symfony/Component/Serializer/Serializer.php +++ b/src/Symfony/Component/Serializer/Serializer.php @@ -28,13 +28,17 @@ use Symfony\Component\Serializer\Encoder\EncoderInterface; */ class Serializer implements SerializerInterface { - protected $normalizers = array(); - protected $encoders = array(); - protected $normalizerCache = array(); + private $normalizers = array(); + private $encoders = array(); + private $normalizerCache = array(); - public function isStructuredType($val) + /** + * @param mixed $value value to test + * @return Boolean whether the type is a structured type (array + objects) + */ + public function isStructuredType($value) { - return null !== $val && !is_scalar($val); + return null !== $value && !is_scalar($value); } /** @@ -127,17 +131,26 @@ class Serializer implements SerializerInterface return $this->encoders[$format]->decode($data, $format); } + /** + * {@inheritdoc} + */ public function addNormalizer(NormalizerInterface $normalizer) { $this->normalizers[] = $normalizer; $normalizer->setSerializer($this); } + /** + * {@inheritdoc} + */ public function getNormalizers() { return $this->normalizers; } + /** + * {@inheritdoc} + */ public function removeNormalizer(NormalizerInterface $normalizer) { unset($this->normalizers[array_search($normalizer, $this->normalizers, true)]); diff --git a/src/Symfony/Component/Serializer/SerializerAwareInterface.php b/src/Symfony/Component/Serializer/SerializerAwareInterface.php new file mode 100644 index 0000000000..625601e701 --- /dev/null +++ b/src/Symfony/Component/Serializer/SerializerAwareInterface.php @@ -0,0 +1,38 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * Defines the interface of encoders + * + * @author Jordi Boggiano + */ +interface SerializerAwareInterface +{ + /** + * Sets the owning Serializer object + * + * @param SerializerInterface $serializer + * @api + */ + function setSerializer(SerializerInterface $serializer); + + /** + * Gets the owning Serializer object + * + * @return SerializerInterface + * @api + */ + function getSerializer(); +} diff --git a/src/Symfony/Component/Serializer/SerializerInterface.php b/src/Symfony/Component/Serializer/SerializerInterface.php index 623799d5b5..a3488894cf 100644 --- a/src/Symfony/Component/Serializer/SerializerInterface.php +++ b/src/Symfony/Component/Serializer/SerializerInterface.php @@ -3,6 +3,7 @@ namespace Symfony\Component\Serializer; use Symfony\Component\Serializer\Encoder\EncoderInterface; +use Symfony\Component\Serializer\Normalizer\NormalizerInterface; /* * This file is part of the Symfony framework. @@ -26,6 +27,7 @@ interface SerializerInterface * @param mixed $data any data * @param string $format format name * @return string + * @api */ function serialize($data, $format); @@ -35,6 +37,7 @@ interface SerializerInterface * @param mixed $data data to normalize * @param string $format format name, present to give the option to normalizers to act differently based on formats * @return array|scalar + * @api */ function normalize($data, $format); @@ -64,6 +67,7 @@ interface SerializerInterface * @param mixed $data data to encode * @param string $format format name * @return array|scalar + * @api */ function encode($data, $format); @@ -73,9 +77,25 @@ interface SerializerInterface * @param string $data data to decode * @param string $format format name * @return mixed + * @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 diff --git a/src/Symfony/Component/Templating/DelegatingEngine.php b/src/Symfony/Component/Templating/DelegatingEngine.php index 78a6cfcd80..8aaff3edc2 100644 --- a/src/Symfony/Component/Templating/DelegatingEngine.php +++ b/src/Symfony/Component/Templating/DelegatingEngine.php @@ -106,6 +106,6 @@ class DelegatingEngine implements EngineInterface } } - throw new \RuntimeException(sprintf('No engine is able to work with the "%s" template.', $name)); + throw new \RuntimeException(sprintf('No engine is able to work with the template "%s".', $name)); } } diff --git a/src/Symfony/Component/Templating/EngineInterface.php b/src/Symfony/Component/Templating/EngineInterface.php index 7b26da0320..1a9a342672 100644 --- a/src/Symfony/Component/Templating/EngineInterface.php +++ b/src/Symfony/Component/Templating/EngineInterface.php @@ -19,7 +19,7 @@ namespace Symfony\Component\Templating; * a path on the filesystem (in fact, the template can be stored * anywhere, like in a database). * - * The methods should accept any name. If the name is not an instance of + * The methods should accept any name. If the name is not an instance of * TemplateReferenceInterface, a TemplateNameParserInterface should be used to * convert the name to a TemplateReferenceInterface instance. * diff --git a/src/Symfony/Component/Templating/Loader/CacheLoader.php b/src/Symfony/Component/Templating/Loader/CacheLoader.php index 47c60a3af3..ba694b647c 100644 --- a/src/Symfony/Component/Templating/Loader/CacheLoader.php +++ b/src/Symfony/Component/Templating/Loader/CacheLoader.php @@ -32,10 +32,10 @@ class CacheLoader extends Loader /** * Constructor. * - * @param Loader $loader A Loader instance - * @param string $dir The directory where to store the cache files + * @param LoaderInterface $loader A Loader instance + * @param string $dir The directory where to store the cache files */ - public function __construct(Loader $loader, $dir) + public function __construct(LoaderInterface $loader, $dir) { $this->loader = $loader; $this->dir = $dir; diff --git a/src/Symfony/Component/Templating/Loader/FilesystemLoader.php b/src/Symfony/Component/Templating/Loader/FilesystemLoader.php index f5d35d196b..3007a0e4f0 100644 --- a/src/Symfony/Component/Templating/Loader/FilesystemLoader.php +++ b/src/Symfony/Component/Templating/Loader/FilesystemLoader.php @@ -106,9 +106,9 @@ class FilesystemLoader extends Loader */ static protected function isAbsolutePath($file) { - if ($file[0] == '/' || $file[0] == '\\' - || (strlen($file) > 3 && ctype_alpha($file[0]) - && $file[1] == ':' + if ($file[0] == '/' || $file[0] == '\\' + || (strlen($file) > 3 && ctype_alpha($file[0]) + && $file[1] == ':' && ($file[2] == '\\' || $file[2] == '/') ) ) { diff --git a/src/Symfony/Component/Templating/PhpEngine.php b/src/Symfony/Component/Templating/PhpEngine.php index a05507e5d7..c5b2d47305 100644 --- a/src/Symfony/Component/Templating/PhpEngine.php +++ b/src/Symfony/Component/Templating/PhpEngine.php @@ -82,7 +82,7 @@ class PhpEngine implements EngineInterface, \ArrayAccess $parameters = array_replace($this->getGlobals(), $parameters); // render if (false === $content = $this->evaluate($storage, $parameters)) { - throw new \RuntimeException(sprintf('The template "%s" cannot be rendered.', json_encode($name))); + throw new \RuntimeException(sprintf('The template "%s" cannot be rendered.', $this->parser->parse($name))); } // decorator @@ -172,7 +172,7 @@ class PhpEngine implements EngineInterface, \ArrayAccess */ public function offsetGet($name) { - return $this->$name = $this->get($name); + return $this->get($name); } /** @@ -211,7 +211,7 @@ class PhpEngine implements EngineInterface, \ArrayAccess /** * @param Helper[] $helpers An array of helper */ - public function addHelpers(array $helpers = array()) + public function addHelpers(array $helpers) { foreach ($helpers as $alias => $helper) { $this->set($helper, is_int($alias) ? null : $alias); @@ -496,7 +496,7 @@ class PhpEngine implements EngineInterface, \ArrayAccess $storage = $this->loader->load($template); if (false === $storage) { - throw new \InvalidArgumentException(sprintf('The template "%s" does not exist.', is_string($name) ? $name : json_encode($name))); + throw new \InvalidArgumentException(sprintf('The template "%s" does not exist.', $template)); } return $this->cache[$key] = $storage; diff --git a/src/Symfony/Component/Templating/TemplateReference.php b/src/Symfony/Component/Templating/TemplateReference.php index 34a1ed6035..07817b8f3f 100644 --- a/src/Symfony/Component/Templating/TemplateReference.php +++ b/src/Symfony/Component/Templating/TemplateReference.php @@ -30,11 +30,13 @@ class TemplateReference implements TemplateReferenceInterface public function __toString() { - return json_encode($this->parameters); + return $this->getLogicalName(); } /** - * {@inheritDoc} + * Returns the template signature + * + * @return string A UID for the template */ public function getSignature() { @@ -42,7 +44,14 @@ class TemplateReference implements TemplateReferenceInterface } /** - * {@inheritDoc} + * Sets a template parameter. + * + * @param string $name The parameter name + * @param string $value The parameter value + * + * @return TemplateReferenceInterface The TemplateReferenceInterface instance + * + * @throws \InvalidArgumentException if the parameter is not defined */ public function set($name, $value) { @@ -56,7 +65,13 @@ class TemplateReference implements TemplateReferenceInterface } /** - * {@inheritDoc} + * Gets a template parameter. + * + * @param string $name The parameter name + * + * @return string The parameter value + * + * @throws \InvalidArgumentException if the parameter is not defined */ public function get($name) { @@ -68,7 +83,9 @@ class TemplateReference implements TemplateReferenceInterface } /** - * {@inheritDoc} + * Gets the template parameters. + * + * @return array An array of parameters */ public function all() { @@ -76,10 +93,24 @@ class TemplateReference implements TemplateReferenceInterface } /** - * {@inheritDoc} + * Returns the path to the template. + * + * By default, it just returns the template name. + * + * @return string A path to the template or a resource */ public function getPath() { return $this->parameters['name']; } + + /** + * Returns the template name + * + * @return string The template name + */ + public function getLogicalName() + { + return $this->parameters['name']; + } } diff --git a/src/Symfony/Component/Templating/TemplateReferenceInterface.php b/src/Symfony/Component/Templating/TemplateReferenceInterface.php index aafa7ee8a6..8de8f95977 100644 --- a/src/Symfony/Component/Templating/TemplateReferenceInterface.php +++ b/src/Symfony/Component/Templating/TemplateReferenceInterface.php @@ -63,4 +63,11 @@ interface TemplateReferenceInterface * @return string A path to the template or a resource */ function getPath(); + + /** + * Returns the template name + * + * @return string The template name + */ + function getLogicalName(); } diff --git a/src/Symfony/Component/Translation/Interval.php b/src/Symfony/Component/Translation/Interval.php index 63c89c5605..8e0d22f788 100644 --- a/src/Symfony/Component/Translation/Interval.php +++ b/src/Symfony/Component/Translation/Interval.php @@ -57,7 +57,7 @@ class Interval $leftNumber = self::convertNumber($matches['left']); $rightNumber = self::convertNumber($matches['right']); - return + return ('[' === $matches['left_delimiter'] ? $number >= $leftNumber : $number > $leftNumber) && (']' === $matches['right_delimiter'] ? $number <= $rightNumber : $number < $rightNumber) ; diff --git a/src/Symfony/Component/Translation/Loader/CsvFileLoader.php b/src/Symfony/Component/Translation/Loader/CsvFileLoader.php index daf95189c1..95ac3823c1 100644 --- a/src/Symfony/Component/Translation/Loader/CsvFileLoader.php +++ b/src/Symfony/Component/Translation/Loader/CsvFileLoader.php @@ -30,13 +30,13 @@ class CsvFileLoader extends ArrayLoader implements LoaderInterface public function load($resource, $locale, $domain = 'messages') { $messages = array(); - + try { $file = new \SplFileObject($resource, 'rb'); } catch(\RuntimeException $e) { throw new \InvalidArgumentException(sprintf('Error opening file "%s".', $resource)); } - + $file->setFlags(\SplFileObject::READ_CSV | \SplFileObject::SKIP_EMPTY); $file->setCsvControl(';'); diff --git a/src/Symfony/Component/Validator/Mapping/Cache/ApcCache.php b/src/Symfony/Component/Validator/Mapping/Cache/ApcCache.php index 83495db7c0..e8f1c355d3 100644 --- a/src/Symfony/Component/Validator/Mapping/Cache/ApcCache.php +++ b/src/Symfony/Component/Validator/Mapping/Cache/ApcCache.php @@ -6,30 +6,25 @@ use Symfony\Component\Validator\Mapping\ClassMetadata; class ApcCache implements CacheInterface { + private $prefix; + + public function __construct($prefix) + { + $this->prefix = $prefix; + } + public function has($class) { - apc_delete($this->computeCacheKey($class)); - apc_fetch($this->computeCacheKey($class), $exists); - - return $exists; + return apc_exists($this->prefix.$class); } public function read($class) { - if (!$this->has($class)) { - // TODO exception - } - - return apc_fetch($this->computeCacheKey($class)); + return apc_fetch($this->prefix.$class); } public function write(ClassMetadata $metadata) { - apc_store($this->computeCacheKey($metadata->getClassName()), $metadata); - } - - protected function computeCacheKey($class) - { - return 'Symfony\Components\Validator:'.$class; + apc_store($this->prefix.$metadata->getClassName(), $metadata); } } diff --git a/src/Symfony/Component/Yaml/Escaper.php b/src/Symfony/Component/Yaml/Escaper.php index 9ff9272ff8..81a7d5fe1b 100644 --- a/src/Symfony/Component/Yaml/Escaper.php +++ b/src/Symfony/Component/Yaml/Escaper.php @@ -49,7 +49,7 @@ class Escaper { return preg_match('/'.self::REGEX_CHARACTER_TO_ESCAPE.'/u', $value); } - + /** * Escapes and surrounds a PHP value with double quotes. * diff --git a/tests/Symfony/Tests/Bridge/Twig/Extension/TranslationExtensionTest.php b/tests/Symfony/Tests/Bridge/Twig/Extension/TranslationExtensionTest.php index db20de86e0..c141336bff 100644 --- a/tests/Symfony/Tests/Bridge/Twig/Extension/TranslationExtensionTest.php +++ b/tests/Symfony/Tests/Bridge/Twig/Extension/TranslationExtensionTest.php @@ -47,16 +47,9 @@ class TranslationExtensionTest extends TestCase { return array( // trans tag - array('{% trans "Hello" %}', 'Hello'), - array('{% trans "Hello %name%" %}', 'Hello Symfony2', array('name' => 'Symfony2')), - array('{% trans name %}', 'Symfony2', array('name' => 'Symfony2')), - array('{% trans hello with { \'%name%\': \'Symfony2\' } %}', 'Hello Symfony2', array('hello' => 'Hello %name%')), - array('{% set vars = { \'%name%\': \'Symfony2\' } %}{% trans hello with vars %}', 'Hello Symfony2', array('hello' => 'Hello %name%')), - array('{% trans %}Hello{% endtrans %}', 'Hello'), array('{% trans %}%name%{% endtrans %}', 'Symfony2', array('name' => 'Symfony2')), - array('{% trans "Hello" from elsewhere %}', 'Hello'), array('{% trans from elsewhere %}Hello{% endtrans %}', 'Hello'), array('{% trans %}Hello %name%{% endtrans %}', 'Hello Symfony2', array('name' => 'Symfony2')), @@ -72,12 +65,20 @@ class TranslationExtensionTest extends TestCase 'There is 5 apples (Symfony2)', array('count' => 5, 'name' => 'Symfony2')), array('{% transchoice count with { \'%name%\': \'Symfony2\' } %}{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples (%name%){% endtranschoice %}', 'There is 5 apples (Symfony2)', array('count' => 5)), + array('{% transchoice count for "{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples" from "messages" %}', + 'There is one apple', array('count' => 1)), + array('{% set text = "{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples (%name%)" %}{% transchoice count for text with { \'%name%\': \'Symfony2\', \'%count%\': count } %}', + 'There is 5 apples (Symfony2)', array('count' => 5)), // trans filter array('{{ "Hello"|trans }}', 'Hello'), array('{{ name|trans }}', 'Symfony2', array('name' => 'Symfony2')), array('{{ hello|trans({ \'%name%\': \'Symfony2\' }) }}', 'Hello Symfony2', array('hello' => 'Hello %name%')), array('{% set vars = { \'%name%\': \'Symfony2\' } %}{{ hello|trans(vars) }}', 'Hello Symfony2', array('hello' => 'Hello %name%')), + + // transchoice filter + array('{{ "{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples"|transchoice(count) }}', 'There is 5 apples', array('count' => 5)), + array('{{ text|transchoice(5, {\'%name%\': \'Symfony2\'}) }}', 'There is 5 apples (Symfony2)', array('text' => '{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples (%name%)')), ); } diff --git a/tests/Symfony/Tests/Component/BrowserKit/ClientTest.php b/tests/Symfony/Tests/Component/BrowserKit/ClientTest.php index f64c9ff94e..7a9de55dd2 100644 --- a/tests/Symfony/Tests/Component/BrowserKit/ClientTest.php +++ b/tests/Symfony/Tests/Component/BrowserKit/ClientTest.php @@ -308,4 +308,27 @@ class ClientTest extends \PHPUnit_Framework_TestCase $this->assertInstanceof('RuntimeException', $e, '->request() throws a \RuntimeException if the script has an error'); } } + + public function testGetServerParameter() + { + $client = new TestClient(); + $this->assertEquals('localhost', $client->getServerParameter('HTTP_HOST')); + $this->assertEquals('Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3', $client->getServerParameter('HTTP_USER_AGENT')); + + $this->assertEquals('testvalue', $client->getServerParameter('testkey', 'testvalue')); + } + + public function testSetServerParameter() + { + $client = new TestClient(); + + $this->assertEquals('localhost', $client->getServerParameter('HTTP_HOST')); + $this->assertEquals('Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3', $client->getServerParameter('HTTP_USER_AGENT')); + + $client->setServerParameter('HTTP_HOST', 'testhost'); + $this->assertEquals('testhost', $client->getServerParameter('HTTP_HOST')); + + $client->setServerParameter('HTTP_USER_AGENT', 'testua'); + $this->assertEquals('testua', $client->getServerParameter('HTTP_USER_AGENT')); + } } diff --git a/tests/Symfony/Tests/Component/BrowserKit/ResponseTest.php b/tests/Symfony/Tests/Component/BrowserKit/ResponseTest.php index 347a8fe21f..6e0f52b909 100644 --- a/tests/Symfony/Tests/Component/BrowserKit/ResponseTest.php +++ b/tests/Symfony/Tests/Component/BrowserKit/ResponseTest.php @@ -61,14 +61,14 @@ class ResponseTest extends \PHPUnit_Framework_TestCase { $headers = array( 'content-type' => 'text/html; charset=utf-8', - 'set-cookie' => array('foo=bar', 'bar=foo') + 'set-cookie' => array('foo=bar', 'bar=foo') ); - + $expected = 'content-type: text/html; charset=utf-8'."\n"; $expected.= 'set-cookie: foo=bar'."\n"; $expected.= 'set-cookie: bar=foo'."\n\n"; $expected.= 'foo'; - + $response = new Response('foo', 304, $headers); $this->assertEquals($expected, $response->__toString(), '->__toString() returns the headers and the content as a string'); diff --git a/tests/Symfony/Tests/Component/Config/Definition/Builder/NodeBuilderTest.php b/tests/Symfony/Tests/Component/Config/Definition/Builder/NodeBuilderTest.php index 8fc6bc248b..34ddb51f9a 100644 --- a/tests/Symfony/Tests/Component/Config/Definition/Builder/NodeBuilderTest.php +++ b/tests/Symfony/Tests/Component/Config/Definition/Builder/NodeBuilderTest.php @@ -30,7 +30,7 @@ class NodeBuilderTest extends \PHPUnit_Framework_TestCase public function testAddingANewNodeType() { $class = __NAMESPACE__.'\\SomeNodeDefinition'; - + $builder = new BaseNodeBuilder(); $node = $builder ->setNodeClass('newtype', $class) @@ -66,7 +66,7 @@ class NodeBuilderTest extends \PHPUnit_Framework_TestCase $node2 = $builder->node('', 'custom'); $this->assertEquals(get_class($node1), get_class($node2)); - } + } } class SomeNodeDefinition extends BaseVariableNodeDefinition diff --git a/tests/Symfony/Tests/Component/Config/Definition/PrototypedArrayNodeTest.php b/tests/Symfony/Tests/Component/Config/Definition/PrototypedArrayNodeTest.php index 3ce18790c1..697969f257 100644 --- a/tests/Symfony/Tests/Component/Config/Definition/PrototypedArrayNodeTest.php +++ b/tests/Symfony/Tests/Component/Config/Definition/PrototypedArrayNodeTest.php @@ -8,7 +8,7 @@ use Symfony\Component\Config\Definition\ScalarNode; class PrototypedArrayNodeTest extends \PHPUnit_Framework_TestCase { - + public function testGetDefaultValueReturnsAnEmptyArrayForPrototypes() { $node = new PrototypedArrayNode('root'); diff --git a/tests/Symfony/Tests/Component/Config/Fixtures/Builder/NodeBuilder.php b/tests/Symfony/Tests/Component/Config/Fixtures/Builder/NodeBuilder.php index a3ae249d4f..fb582d6c46 100644 --- a/tests/Symfony/Tests/Component/Config/Fixtures/Builder/NodeBuilder.php +++ b/tests/Symfony/Tests/Component/Config/Fixtures/Builder/NodeBuilder.php @@ -20,6 +20,6 @@ class NodeBuilder extends BaseNodeBuilder return __NAMESPACE__.'\\'.ucfirst($type).'NodeDefinition'; default: return parent::getNodeClass($type); - } + } } } \ No newline at end of file diff --git a/tests/Symfony/Tests/Component/DependencyInjection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPassTest.php b/tests/Symfony/Tests/Component/DependencyInjection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPassTest.php new file mode 100644 index 0000000000..4db6b8a990 --- /dev/null +++ b/tests/Symfony/Tests/Component/DependencyInjection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPassTest.php @@ -0,0 +1,62 @@ +register('a', '\stdClass') + ->addArgument(new Reference('b')) + ; + $container->register('b', '\stdClass'); + } + + /** + * @expectedException Symfony\Component\DependencyInjection\Exception\NonExistentServiceException + */ + public function testProcessThrowsExceptionOnInvalidReference() + { + $container = new ContainerBuilder(); + + $container + ->register('a', '\stdClass') + ->addArgument(new Reference('b')) + ; + + $this->process($container); + } + + /** + * @expectedException Symfony\Component\DependencyInjection\Exception\NonExistentServiceException + */ + public function testProcessThrowsExceptionOnInvalidReferenceFromInlinedDefinition() + { + $container = new ContainerBuilder(); + + $def = new Definition(); + $def->addArgument(new Reference('b')); + + $container + ->register('a', '\stdClass') + ->addArgument($def) + ; + + $this->process($container); + } + + private function process(ContainerBuilder $container) + { + $pass = new CheckExceptionOnInvalidReferenceBehaviorPass(); + $pass->process($container); + } +} \ No newline at end of file diff --git a/tests/Symfony/Tests/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPassTest.php b/tests/Symfony/Tests/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPassTest.php index 4e29373e22..3ae83af9d5 100644 --- a/tests/Symfony/Tests/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPassTest.php +++ b/tests/Symfony/Tests/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPassTest.php @@ -14,7 +14,7 @@ class ResolveDefinitionTemplatesPassTest extends \PHPUnit_Framework_TestCase $container = new ContainerBuilder(); $container->register('parent', 'foo')->setArguments(array('moo', 'b'))->setProperty('foo', 'moo'); $container->setDefinition('child', new DefinitionDecorator('parent')) - ->setArgument(0, 'a') + ->replaceArgument(0, 'a') ->setProperty('foo', 'bar') ->setClass('bar') ; @@ -119,12 +119,12 @@ class ResolveDefinitionTemplatesPassTest extends \PHPUnit_Framework_TestCase $container ->setDefinition('child2', new DefinitionDecorator('child1')) - ->setArgument(1, 'b') + ->replaceArgument(1, 'b') ; $container ->setDefinition('child1', new DefinitionDecorator('parent')) - ->setArgument(0, 'a') + ->replaceArgument(0, 'a') ; $this->process($container); diff --git a/tests/Symfony/Tests/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPassTest.php b/tests/Symfony/Tests/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPassTest.php index 82634e3ba1..6c8f312495 100644 --- a/tests/Symfony/Tests/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPassTest.php +++ b/tests/Symfony/Tests/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPassTest.php @@ -48,20 +48,6 @@ class ResolveInvalidReferencesPassTest extends \PHPUnit_Framework_TestCase $this->assertEquals('bar', (string) $arguments[0]); } - public function testProcessIgnoresExceptions() - { - $container = new ContainerBuilder(); - $def = $container - ->register('foo') - ->setArguments(array(new Reference('bar', ContainerInterface::NULL_ON_INVALID_REFERENCE))) - ; - - $this->process($container, array('bar')); - - $arguments = $def->getArguments(); - $this->assertEquals('bar', (string) $arguments[0]); - } - public function testProcessRemovesPropertiesOnInvalid() { $container = new ContainerBuilder(); @@ -75,9 +61,9 @@ class ResolveInvalidReferencesPassTest extends \PHPUnit_Framework_TestCase $this->assertEquals(array(), $def->getProperties()); } - protected function process(ContainerBuilder $container, array $exceptions = array()) + protected function process(ContainerBuilder $container) { - $pass = new ResolveInvalidReferencesPass($exceptions); + $pass = new ResolveInvalidReferencesPass(); $pass->process($container); } -} \ No newline at end of file +} diff --git a/tests/Symfony/Tests/Component/DependencyInjection/ContainerTest.php b/tests/Symfony/Tests/Component/DependencyInjection/ContainerTest.php index 5dc890b433..fc307babbb 100644 --- a/tests/Symfony/Tests/Component/DependencyInjection/ContainerTest.php +++ b/tests/Symfony/Tests/Component/DependencyInjection/ContainerTest.php @@ -161,8 +161,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase $sc->get(''); $this->fail('->get() throws a \InvalidArgumentException exception if the service is empty'); } catch (\Exception $e) { - $this->assertInstanceOf('\InvalidArgumentException', $e, '->get() throws a \InvalidArgumentException exception if the service is empty'); - $this->assertEquals('The service "" does not exist.', $e->getMessage(), '->get() throws a \InvalidArgumentException exception if the service is empty'); + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\NonExistentServiceException', $e, '->get() throws a NonExistentServiceException exception if the service is empty'); } $this->assertNull($sc->get('', ContainerInterface::NULL_ON_INVALID_REFERENCE)); } diff --git a/tests/Symfony/Tests/Component/DependencyInjection/DefinitionDecoratorTest.php b/tests/Symfony/Tests/Component/DependencyInjection/DefinitionDecoratorTest.php index 6c74adfe4a..165d26df63 100644 --- a/tests/Symfony/Tests/Component/DependencyInjection/DefinitionDecoratorTest.php +++ b/tests/Symfony/Tests/Component/DependencyInjection/DefinitionDecoratorTest.php @@ -57,7 +57,7 @@ class DefinitionDecoratorTest extends \PHPUnit_Framework_TestCase $def = new DefinitionDecorator('foo'); $this->assertEquals(array(), $def->getArguments()); - $this->assertSame($def, $def->setArgument(0, 'foo')); + $this->assertSame($def, $def->replaceArgument(0, 'foo')); $this->assertEquals(array('index_0' => 'foo'), $def->getArguments()); } } \ No newline at end of file diff --git a/tests/Symfony/Tests/Component/DependencyInjection/DefinitionTest.php b/tests/Symfony/Tests/Component/DependencyInjection/DefinitionTest.php index d1880d706b..9ff87e09b7 100644 --- a/tests/Symfony/Tests/Component/DependencyInjection/DefinitionTest.php +++ b/tests/Symfony/Tests/Component/DependencyInjection/DefinitionTest.php @@ -201,7 +201,7 @@ class DefinitionTest extends \PHPUnit_Framework_TestCase } /** - * @covers Symfony\Component\DependencyInjection\Definition::setArgument + * @covers Symfony\Component\DependencyInjection\Definition::replaceArgument */ public function testSetArgument() { @@ -210,13 +210,13 @@ class DefinitionTest extends \PHPUnit_Framework_TestCase $def->addArgument('foo'); $this->assertSame(array('foo'), $def->getArguments()); - $this->assertSame($def, $def->setArgument(0, 'moo')); + $this->assertSame($def, $def->replaceArgument(0, 'moo')); $this->assertSame(array('moo'), $def->getArguments()); $def->addArgument('moo'); $def - ->setArgument(0, 'foo') - ->setArgument(1, 'bar') + ->replaceArgument(0, 'foo') + ->replaceArgument(1, 'bar') ; $this->assertSame(array('foo', 'bar'), $def->getArguments()); } diff --git a/tests/Symfony/Tests/Component/DomCrawler/FormTest.php b/tests/Symfony/Tests/Component/DomCrawler/FormTest.php index 71aad4c9e7..53a9b72087 100644 --- a/tests/Symfony/Tests/Component/DomCrawler/FormTest.php +++ b/tests/Symfony/Tests/Component/DomCrawler/FormTest.php @@ -343,7 +343,7 @@ class FormTest extends \PHPUnit_Framework_TestCase 'chooses the path if the action attribute value is a sharp (#)', '
', array(), - '/', + '/#', ), ); } @@ -389,20 +389,27 @@ class FormTest extends \PHPUnit_Framework_TestCase public function testBase() { $dom = new \DOMDocument(); - $dom->loadHTML('
'); + $dom->loadHTML('
'); $nodes = $dom->getElementsByTagName('input'); $form = new Form($nodes->item($nodes->length - 1), null, 'http://www.bar.com/foobar/', '/', 'http://www.foo.com/'); $this->assertEquals('http://www.foo.com/foo.php', $form->getUri()); } - protected function createForm($form, $method = null, $host = null, $path = '/') + public function testUriWithAnchor() + { + $form = $this->createForm('
', null, 'http://example.com', '/id/123'); + + $this->assertEquals('http://example.com/id/123#foo', $form->getUri()); + } + + protected function createForm($form, $method = null, $host = null, $path = '/', $base = null) { $dom = new \DOMDocument(); $dom->loadHTML(''.$form.''); $nodes = $dom->getElementsByTagName('input'); - return new Form($nodes->item($nodes->length - 1), $method, $host, $path); + return new Form($nodes->item($nodes->length - 1), $method, $host, $path, $base); } } diff --git a/tests/Symfony/Tests/Component/HttpFoundation/CookieTest.php b/tests/Symfony/Tests/Component/HttpFoundation/CookieTest.php index 60e873bfcf..b2e869c589 100644 --- a/tests/Symfony/Tests/Component/HttpFoundation/CookieTest.php +++ b/tests/Symfony/Tests/Component/HttpFoundation/CookieTest.php @@ -69,13 +69,13 @@ class CookieTest extends \PHPUnit_Framework_TestCase { new Cookie('MyCookie', $value); } - + /** * @expectedException InvalidArgumentException */ public function testInvalidExpiration() { - $cookie = new Cookie('MyCookie', 'foo','bar'); + $cookie = new Cookie('MyCookie', 'foo','bar'); } /** @@ -96,11 +96,11 @@ class CookieTest extends \PHPUnit_Framework_TestCase $this->assertSame('/', $cookie->getPath(), '->getPath() returns / as the default path'); } - public function testGetExpires() + public function testGetExpiresTime() { $cookie = new Cookie('foo', 'bar', 3600); - $this->assertEquals(3600, $cookie->getExpire(), '->getExpire() returns the expire date'); + $this->assertEquals(3600, $cookie->getExpiresTime(), '->getExpiresTime() returns the expire date'); } public function testGetDomain() diff --git a/tests/Symfony/Tests/Component/HttpFoundation/ParameterBagTest.php b/tests/Symfony/Tests/Component/HttpFoundation/ParameterBagTest.php index c4bc6d6564..e5e8ef3e89 100644 --- a/tests/Symfony/Tests/Component/HttpFoundation/ParameterBagTest.php +++ b/tests/Symfony/Tests/Component/HttpFoundation/ParameterBagTest.php @@ -56,6 +56,41 @@ class ParameterBagTest extends \PHPUnit_Framework_TestCase $this->assertNull($bag->get('null', 'default'), '->get() returns null if null is set'); } + /** + * @dataProvider getInvalidPaths + * @expectedException \InvalidArgumentException + * @covers Symfony\Component\HttpFoundation\ParameterBag::getDeep + */ + public function testGetDeepWithInvalidPaths($path) + { + $bag = new ParameterBag(array('foo' => array('bar' => 'moo'))); + + $bag->getDeep($path); + } + + public function getInvalidPaths() + { + return array( + array('foo[['), + array('foo[d'), + array('foo[bar]]'), + array('foo[bar]d'), + ); + } + + /** + * @covers Symfony\Component\HttpFoundation\ParameterBag::getDeep + */ + public function testGetDeep() + { + $bag = new ParameterBag(array('foo' => array('bar' => array('moo' => 'boo')))); + + $this->assertEquals(array('moo' => 'boo'), $bag->getDeep('foo[bar]')); + $this->assertEquals('boo', $bag->getDeep('foo[bar][moo]')); + $this->assertEquals('default', $bag->getDeep('foo[bar][foo]', 'default')); + $this->assertEquals('default', $bag->getDeep('bar[moo][foo]', 'default')); + } + /** * @covers Symfony\Component\HttpFoundation\ParameterBag::set */ diff --git a/tests/Symfony/Tests/Component/HttpFoundation/RequestTest.php b/tests/Symfony/Tests/Component/HttpFoundation/RequestTest.php index e975fd9692..019fa215f0 100644 --- a/tests/Symfony/Tests/Component/HttpFoundation/RequestTest.php +++ b/tests/Symfony/Tests/Component/HttpFoundation/RequestTest.php @@ -116,7 +116,7 @@ class RequestTest extends \PHPUnit_Framework_TestCase public function testGetFormatFromMimeType($format, $mimeTypes) { $request = new Request(); - foreach ($mimeTypes as $mime) { + foreach ($mimeTypes as $mime) { $this->assertEquals($format, $request->getFormat($mime)); } $request->setFormat($format, $mimeTypes); @@ -131,7 +131,7 @@ class RequestTest extends \PHPUnit_Framework_TestCase */ public function testGetMimeTypeFromFormat($format, $mimeTypes) { - if (!is_null($format)) { + if (null !== $format) { $request = new Request(); $this->assertEquals($mimeTypes[0], $request->getMimeType($format)); } @@ -634,7 +634,7 @@ class RequestTest extends \PHPUnit_Framework_TestCase $request = new Request(); $request->headers->set('Accept-Charset', 'ISO-8859-1, US-ASCII, UTF-8; q=0.8, ISO-10646-UCS-2; q=0.6'); $this->assertEquals(array('ISO-8859-1', 'US-ASCII', 'UTF-8', 'ISO-10646-UCS-2'), $request->getCharsets()); - + $request = new Request(); $request->headers->set('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.7'); $this->assertEquals(array('ISO-8859-1', '*', 'utf-8'), $request->getCharsets()); diff --git a/tests/Symfony/Tests/Component/HttpFoundation/ResponseTest.php b/tests/Symfony/Tests/Component/HttpFoundation/ResponseTest.php index 1105d48193..11429f4bcc 100644 --- a/tests/Symfony/Tests/Component/HttpFoundation/ResponseTest.php +++ b/tests/Symfony/Tests/Component/HttpFoundation/ResponseTest.php @@ -61,6 +61,15 @@ class ResponseTest extends \PHPUnit_Framework_TestCase $this->assertNull($response->getMaxAge(), '->getMaxAge() returns null if no freshness information available'); } + public function testSetSharedMaxAge() + { + $response = new Response(); + $response->setSharedMaxAge(20); + + $cacheControl = $response->headers->get('Cache-Control'); + $this->assertEquals('public, s-maxage=20', $cacheControl); + } + public function testIsPrivate() { $response = new Response(); @@ -207,7 +216,7 @@ class ResponseTest extends \PHPUnit_Framework_TestCase $response->setCache($options); $this->assertEquals($response->getMaxAge(), 200); - $this->assertFalse($response->headers->hasCacheControlDirective('public')); + $this->assertTrue($response->headers->hasCacheControlDirective('public')); $this->assertFalse($response->headers->hasCacheControlDirective('private')); $response->setCache(array('public' => true)); diff --git a/tests/Symfony/Tests/Component/HttpFoundation/SessionStorage/FilesystemSessionStorageTest.php b/tests/Symfony/Tests/Component/HttpFoundation/SessionStorage/FilesystemSessionStorageTest.php new file mode 100644 index 0000000000..7f4503b405 --- /dev/null +++ b/tests/Symfony/Tests/Component/HttpFoundation/SessionStorage/FilesystemSessionStorageTest.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Tests\Component\HttpFoundation\SessionStorage; + +use Symfony\Component\HttpFoundation\SessionStorage\FilesystemSessionStorage; + +class FilesystemSessionStorageTest extends \PHPUnit_Framework_TestCase +{ + private $path; + + protected function setUp() + { + $this->path = sys_get_temp_dir().'/sf2/session_test'; + if (!file_exists($this->path)) { + mkdir($this->path, 0777, true); + } + } + + protected function tearDown() + { + array_map('unlink', glob($this->path.'/*.session')); + rmdir($this->path); + } + + public function testMultipleInstances() + { + $storage = new FilesystemSessionStorage($this->path); + $storage->start(); + $storage->write('foo', 'bar'); + + $storage = new FilesystemSessionStorage($this->path); + $storage->start(); + $this->assertEquals('bar', $storage->read('foo'), 'values persist between instances'); + } + + public function testGetIdThrowsErrorBeforeStart() + { + $this->setExpectedException('RuntimeException'); + + $storage = new FilesystemSessionStorage($this->path); + $storage->getId(); + } + + public function testGetIdWorksAfterStart() + { + $storage = new FilesystemSessionStorage($this->path); + $storage->start(); + $storage->getId(); + } +} diff --git a/tests/Symfony/Tests/Component/HttpKernel/Bundle/BundleTest.php b/tests/Symfony/Tests/Component/HttpKernel/Bundle/BundleTest.php index 547585c78a..8028edc7ab 100644 --- a/tests/Symfony/Tests/Component/HttpKernel/Bundle/BundleTest.php +++ b/tests/Symfony/Tests/Component/HttpKernel/Bundle/BundleTest.php @@ -31,18 +31,6 @@ class BundleTest extends \PHPUnit_Framework_TestCase $bundle2 = new ExtensionAbsentBundle(); $this->assertNull($bundle2->registerCommands($app)); - } - public function testGetName() - { - $bundle = new ExtensionPresentBundle(); - $this->assertEquals('ExtensionPresent', $bundle->getName(), '->getName() rtrims "Bundle"'); } - - public function testInvalidBundleName() - { - $this->setExpectedException('RuntimeException'); - $bundle = $this->getMockForAbstractClass('Symfony\\Component\\HttpKernel\\Bundle\\Bundle'); - $bundle->getName(); - } -} +} \ No newline at end of file diff --git a/tests/Symfony/Tests/Component/HttpKernel/ClientTest.php b/tests/Symfony/Tests/Component/HttpKernel/ClientTest.php index 07a94d3c39..2143891533 100644 --- a/tests/Symfony/Tests/Component/HttpKernel/ClientTest.php +++ b/tests/Symfony/Tests/Component/HttpKernel/ClientTest.php @@ -15,6 +15,7 @@ use Symfony\Component\HttpKernel\Client; use Symfony\Component\HttpKernel\HttpKernel; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\Cookie; require_once __DIR__.'/TestHttpKernel.php'; @@ -55,4 +56,24 @@ class ClientTest extends \PHPUnit_Framework_TestCase $this->assertEquals('Request: /', $client->getResponse()->getContent(), '->getScript() returns a script that uses the request handler to make the request'); } + + public function testFilterResponseConvertsCookies() + { + $client = new Client(new TestHttpKernel()); + + $r = new \ReflectionObject($client); + $m = $r->getMethod('filterResponse'); + $m->setAccessible(true); + + $response = new Response(); + $response->headers->setCookie(new Cookie('foo', 'bar', \DateTime::createFromFormat('j-M-Y H:i:s T', '15-Feb-2009 20:00:00 GMT')->format('U'), '/foo', 'http://example.com', true, true)); + $domResponse = $m->invoke($client, $response); + $this->assertEquals('foo=bar; expires=Sun, 15-Feb-2009 20:00:00 GMT; domain=http://example.com; path=/foo; secure; httponly', $domResponse->getHeader('Set-Cookie')); + + $response = new Response(); + $response->headers->setCookie(new Cookie('foo', 'bar', \DateTime::createFromFormat('j-M-Y H:i:s T', '15-Feb-2009 20:00:00 GMT')->format('U'), '/foo', 'http://example.com', true, true)); + $response->headers->setCookie(new Cookie('foo1', 'bar1', \DateTime::createFromFormat('j-M-Y H:i:s T', '15-Feb-2009 20:00:00 GMT')->format('U'), '/foo', 'http://example.com', true, true)); + $domResponse = $m->invoke($client, $response); + $this->assertEquals('foo=bar; expires=Sun, 15-Feb-2009 20:00:00 GMT; domain=http://example.com; path=/foo; secure; httponly, foo1=bar1; expires=Sun, 15-Feb-2009 20:00:00 GMT; domain=http://example.com; path=/foo; secure; httponly', $domResponse->getHeader('Set-Cookie')); + } } diff --git a/tests/Symfony/Tests/Component/HttpKernel/Controller/ControllerResolverTest.php b/tests/Symfony/Tests/Component/HttpKernel/Controller/ControllerResolverTest.php index d2e4940702..334fcb2af9 100644 --- a/tests/Symfony/Tests/Component/HttpKernel/Controller/ControllerResolverTest.php +++ b/tests/Symfony/Tests/Component/HttpKernel/Controller/ControllerResolverTest.php @@ -36,6 +36,18 @@ class ControllerResolverTest extends \PHPUnit_Framework_TestCase $controller = $resolver->getController($request); $this->assertSame($lambda, $controller); + $request->attributes->set('_controller', $this); + $controller = $resolver->getController($request); + $this->assertSame($this, $controller); + + $request->attributes->set('_controller', array($this, 'controllerMethod1')); + $controller = $resolver->getController($request); + $this->assertSame(array($this, 'controllerMethod1'), $controller); + + $request->attributes->set('_controller', array('Symfony\Tests\Component\HttpKernel\ControllerResolverTest', 'controllerMethod4')); + $controller = $resolver->getController($request); + $this->assertSame(array('Symfony\Tests\Component\HttpKernel\ControllerResolverTest', 'controllerMethod4'), $controller); + $request->attributes->set('_controller', 'foo'); try { $resolver->getController($request); @@ -98,6 +110,14 @@ class ControllerResolverTest extends \PHPUnit_Framework_TestCase } catch (\Exception $e) { $this->assertInstanceOf('\RuntimeException', $e, '->getArguments() throws a \RuntimeException exception if it cannot determine the argument value'); } + + $request = Request::create('/'); + $controller = array(new self(), 'controllerMethod5'); + $this->assertEquals(array($request), $resolver->getArguments($request, $controller), '->getArguments() injects the request'); + } + + public function __invoke() + { } protected function controllerMethod1($foo) @@ -111,4 +131,12 @@ class ControllerResolverTest extends \PHPUnit_Framework_TestCase protected function controllerMethod3($foo, $bar = null, $foobar) { } + + static protected function controllerMethod4() + { + } + + protected function controllerMethod5(Request $request) + { + } } diff --git a/tests/Symfony/Tests/Component/HttpKernel/DataCollector/ExceptionDataCollectorTest.php b/tests/Symfony/Tests/Component/HttpKernel/DataCollector/ExceptionDataCollectorTest.php index 4e105d6694..88360c6f0f 100644 --- a/tests/Symfony/Tests/Component/HttpKernel/DataCollector/ExceptionDataCollectorTest.php +++ b/tests/Symfony/Tests/Component/HttpKernel/DataCollector/ExceptionDataCollectorTest.php @@ -24,11 +24,11 @@ class ExceptionDataCollectorTest extends \PHPUnit_Framework_TestCase $c = new ExceptionDataCollector(); $flattened = FlattenException::create($e); $trace = $flattened->getTrace(); - + $this->assertFalse($c->hasException()); - + $c->collect(new Request(), new Response(),$e); - + $this->assertTrue($c->hasException()); $this->assertEquals($flattened,$c->getException()); $this->assertSame('foo',$c->getMessage()); @@ -36,5 +36,5 @@ class ExceptionDataCollectorTest extends \PHPUnit_Framework_TestCase $this->assertSame('exception',$c->getName()); $this->assertSame($trace,$c->getTrace()); } - + } diff --git a/tests/Symfony/Tests/Component/HttpKernel/DataCollector/LoggerDataCollectorTest.php b/tests/Symfony/Tests/Component/HttpKernel/DataCollector/LoggerDataCollectorTest.php index 84033306e7..529211e89f 100644 --- a/tests/Symfony/Tests/Component/HttpKernel/DataCollector/LoggerDataCollectorTest.php +++ b/tests/Symfony/Tests/Component/HttpKernel/DataCollector/LoggerDataCollectorTest.php @@ -22,14 +22,14 @@ class LoggerDataCollectorTest extends \PHPUnit_Framework_TestCase public function testCollect() { $c = new LoggerDataCollector(new TestLogger()); - + $c->collect(new Request(), new Response()); - + $this->assertSame('logger',$c->getName()); $this->assertSame(1337,$c->countErrors()); $this->assertSame(array('foo'),$c->getLogs()); } - + } class TestLogger extends Logger implements DebugLoggerInterface @@ -38,12 +38,12 @@ class TestLogger extends Logger implements DebugLoggerInterface { return 1337; } - + public function getDebugLogger() { return new static(); } - + public function getLogs($priority = false) { return array('foo'); diff --git a/tests/Symfony/Tests/Component/HttpKernel/DataCollector/MemoryDataCollectorTest.php b/tests/Symfony/Tests/Component/HttpKernel/DataCollector/MemoryDataCollectorTest.php index 2d0c4ff503..d52f5a9b2b 100644 --- a/tests/Symfony/Tests/Component/HttpKernel/DataCollector/MemoryDataCollectorTest.php +++ b/tests/Symfony/Tests/Component/HttpKernel/DataCollector/MemoryDataCollectorTest.php @@ -20,11 +20,11 @@ class MemoryDataCollectorTest extends \PHPUnit_Framework_TestCase public function testCollect() { $c = new MemoryDataCollector(); - + $c->collect(new Request(), new Response()); - + $this->assertInternalType('integer',$c->getMemory()); $this->assertSame('memory',$c->getName()); } - + } diff --git a/tests/Symfony/Tests/Component/HttpKernel/DataCollector/RequestDataCollectorTest.php b/tests/Symfony/Tests/Component/HttpKernel/DataCollector/RequestDataCollectorTest.php index 09736efbb1..e8e4ce4d60 100644 --- a/tests/Symfony/Tests/Component/HttpKernel/DataCollector/RequestDataCollectorTest.php +++ b/tests/Symfony/Tests/Component/HttpKernel/DataCollector/RequestDataCollectorTest.php @@ -24,9 +24,9 @@ class RequestDataCollectorTest extends \PHPUnit_Framework_TestCase public function testCollect(Request $request, Response $response) { $c = new RequestDataCollector(); - + $c->collect($request, $response); - + $this->assertSame('request',$c->getName()); $this->assertInstanceOf('Symfony\Component\HttpFoundation\HeaderBag',$c->getRequestHeaders()); $this->assertInstanceOf('Symfony\Component\HttpFoundation\ParameterBag',$c->getRequestServer()); @@ -36,27 +36,27 @@ class RequestDataCollectorTest extends \PHPUnit_Framework_TestCase $this->assertInstanceOf('Symfony\Component\HttpFoundation\ParameterBag',$c->getRequestQuery()); $this->assertEquals('html',$c->getFormat()); $this->assertEquals(array(),$c->getSessionAttributes()); - + $this->assertInstanceOf('Symfony\Component\HttpFoundation\HeaderBag',$c->getResponseHeaders()); $this->assertEquals(200,$c->getStatusCode()); $this->assertEquals('application/json',$c->getContentType()); } - + public function provider() { $request = Request::create('http://test.com/foo?bar=baz'); $request->attributes->set('foo', 'bar'); - + $response = new Response(); $response->setStatusCode(200); $response->headers->set('Content-Type', 'application/json'); $response->headers->setCookie(new Cookie('foo','bar',1,'/foo','localhost',true,true)); $response->headers->setCookie(new Cookie('bar','foo',new \DateTime('@946684800'))); $response->headers->setCookie(new Cookie('bazz','foo','2000-12-12')); - + return array( array($request,$response) ); } - + } diff --git a/tests/Symfony/Tests/Component/HttpKernel/Debug/ErrorHandlerTest.php b/tests/Symfony/Tests/Component/HttpKernel/Debug/ErrorHandlerTest.php index 6e7607e1db..6c96cf3c9e 100644 --- a/tests/Symfony/Tests/Component/HttpKernel/Debug/ErrorHandlerTest.php +++ b/tests/Symfony/Tests/Component/HttpKernel/Debug/ErrorHandlerTest.php @@ -21,27 +21,27 @@ use Symfony\Component\HttpKernel\Debug\ErrorException; */ class ErrorHandlerTest extends \PHPUnit_Framework_TestCase { - + public function testConstruct() { $e = new ErrorHandler(3); - + $this->assertInstanceOf('Symfony\Component\HttpKernel\Debug\ErrorHandler',$e); - + $level = new \ReflectionProperty(get_class($e),'level'); $level->setAccessible(true); - + $this->assertEquals(3,$level->getValue($e)); } - + public function testRegister() { $e = new ErrorHandler(3); $e = $this->getMock(get_class($e), array('handle')); $e->expects($this->once())->method('handle'); - + $e->register(); - + try{ trigger_error('foo'); }catch(\Exception $e){ @@ -52,10 +52,10 @@ class ErrorHandlerTest extends \PHPUnit_Framework_TestCase { $e = new ErrorHandler(0); $this->assertFalse($e->handle(0,'foo','foo.php',12,'foo')); - + $e = new ErrorHandler(3); $this->assertFalse($e->handle(4,'foo','foo.php',12,'foo')); - + $e = new ErrorHandler(3); try{ $e->handle(1, 'foo', 'foo.php', 12,'foo'); diff --git a/tests/Symfony/Tests/Component/HttpKernel/DependencyInjection/MergeExtensionConfigurationPassTest.php b/tests/Symfony/Tests/Component/HttpKernel/DependencyInjection/MergeExtensionConfigurationPassTest.php index e4c0bc90d1..78720eedd8 100644 --- a/tests/Symfony/Tests/Component/HttpKernel/DependencyInjection/MergeExtensionConfigurationPassTest.php +++ b/tests/Symfony/Tests/Component/HttpKernel/DependencyInjection/MergeExtensionConfigurationPassTest.php @@ -18,9 +18,9 @@ class MergeExtensionConfigurationPassTest extends \PHPUnit_Framework_TestCase public function testAutoloadMainExtension() { $bundles = array( - 'ExtensionAbsent' => 'Symfony\\Tests\\Component\\HttpKernel\\Fixtures\\ExtensionAbsentBundle\\ExtensionAbsentBundle', - 'ExtensionLoaded' => 'Symfony\\Tests\\Component\\HttpKernel\\Fixtures\\ExtensionLoadedBundle\\ExtensionLoadedBundle', - 'ExtensionPresent' => 'Symfony\\Tests\\Component\\HttpKernel\\Fixtures\\ExtensionPresentBundle\\ExtensionPresentBundle', + 'ExtensionAbsentBundle' => 'Symfony\\Tests\\Component\\HttpKernel\\Fixtures\\ExtensionAbsentBundle\\ExtensionAbsentBundle', + 'ExtensionLoadedBundle' => 'Symfony\\Tests\\Component\\HttpKernel\\Fixtures\\ExtensionLoadedBundle\\ExtensionLoadedBundle', + 'ExtensionPresentBundle' => 'Symfony\\Tests\\Component\\HttpKernel\\Fixtures\\ExtensionPresentBundle\\ExtensionPresentBundle', ); $container = $this->getMock('Symfony\\Component\\DependencyInjection\\ContainerBuilder'); diff --git a/tests/Symfony/Tests/Component/HttpKernel/Exception/FlattenExceptionTest.php b/tests/Symfony/Tests/Component/HttpKernel/Exception/FlattenExceptionTest.php index 3a4f577be3..48dcd77886 100644 --- a/tests/Symfony/Tests/Component/HttpKernel/Exception/FlattenExceptionTest.php +++ b/tests/Symfony/Tests/Component/HttpKernel/Exception/FlattenExceptionTest.php @@ -21,7 +21,7 @@ class FlattenExceptionTest extends \PHPUnit_Framework_TestCase { $flattened = FlattenException::create($exception); $flattened2 = FlattenException::create($exception); - + $flattened->setPrevious($flattened2); $this->assertEquals($exception->getMessage(), $flattened->getMessage(), 'The message is copied from the original exception.'); @@ -29,7 +29,7 @@ class FlattenExceptionTest extends \PHPUnit_Framework_TestCase $this->assertEquals(get_class($exception), $flattened->getClass(), 'The class is set to the class of the original exception'); } - + /** * @dataProvider flattenDataProvider */ @@ -37,14 +37,14 @@ class FlattenExceptionTest extends \PHPUnit_Framework_TestCase { $flattened = FlattenException::create($exception); $flattened2 = FlattenException::create($exception); - + $flattened->setPrevious($flattened2); - + $this->assertSame($flattened2,$flattened->getPrevious()); - + $this->assertSame(array($flattened2),$flattened->getPreviouses()); } - + /** * @dataProvider flattenDataProvider */ @@ -52,7 +52,7 @@ class FlattenExceptionTest extends \PHPUnit_Framework_TestCase { $flattened = FlattenException::create($exception); $flattened->setTrace(array(),'foo.php',123); - + $this->assertEquals(array( array( 'message'=> 'test', @@ -64,7 +64,7 @@ class FlattenExceptionTest extends \PHPUnit_Framework_TestCase ) ),$flattened->toArray()); } - + public function flattenDataProvider() { return array( diff --git a/tests/Symfony/Tests/Component/HttpKernel/Fixtures/Bundle1/Resources/foo.txt b/tests/Symfony/Tests/Component/HttpKernel/Fixtures/BaseBundle/Resources/foo.txt similarity index 100% rename from tests/Symfony/Tests/Component/HttpKernel/Fixtures/Bundle1/Resources/foo.txt rename to tests/Symfony/Tests/Component/HttpKernel/Fixtures/BaseBundle/Resources/foo.txt diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/skeleton/bundle/generic/Controller/.gitkeep b/tests/Symfony/Tests/Component/HttpKernel/Fixtures/BaseBundle/Resources/hide.txt similarity index 100% rename from src/Symfony/Bundle/FrameworkBundle/Resources/skeleton/bundle/generic/Controller/.gitkeep rename to tests/Symfony/Tests/Component/HttpKernel/Fixtures/BaseBundle/Resources/hide.txt diff --git a/tests/Symfony/Tests/Component/HttpKernel/Fixtures/Bundle1/foo.txt b/tests/Symfony/Tests/Component/HttpKernel/Fixtures/Bundle1Bundle/Resources/foo.txt similarity index 100% rename from tests/Symfony/Tests/Component/HttpKernel/Fixtures/Bundle1/foo.txt rename to tests/Symfony/Tests/Component/HttpKernel/Fixtures/Bundle1Bundle/Resources/foo.txt diff --git a/tests/Symfony/Tests/Component/HttpKernel/Fixtures/Bundle1/bar.txt b/tests/Symfony/Tests/Component/HttpKernel/Fixtures/Bundle1Bundle/bar.txt similarity index 100% rename from tests/Symfony/Tests/Component/HttpKernel/Fixtures/Bundle1/bar.txt rename to tests/Symfony/Tests/Component/HttpKernel/Fixtures/Bundle1Bundle/bar.txt diff --git a/tests/Symfony/Tests/Component/HttpKernel/Fixtures/Bundle2/Resources/foo.txt b/tests/Symfony/Tests/Component/HttpKernel/Fixtures/Bundle1Bundle/foo.txt similarity index 100% rename from tests/Symfony/Tests/Component/HttpKernel/Fixtures/Bundle2/Resources/foo.txt rename to tests/Symfony/Tests/Component/HttpKernel/Fixtures/Bundle1Bundle/foo.txt diff --git a/tests/Symfony/Tests/Component/HttpKernel/Fixtures/Bundle2/foo.txt b/tests/Symfony/Tests/Component/HttpKernel/Fixtures/Bundle2Bundle/foo.txt similarity index 100% rename from tests/Symfony/Tests/Component/HttpKernel/Fixtures/Bundle2/foo.txt rename to tests/Symfony/Tests/Component/HttpKernel/Fixtures/Bundle2Bundle/foo.txt diff --git a/tests/Symfony/Tests/Component/HttpKernel/Fixtures/foo/foo.txt b/tests/Symfony/Tests/Component/HttpKernel/Fixtures/ChildBundle/Resources/foo.txt similarity index 100% rename from tests/Symfony/Tests/Component/HttpKernel/Fixtures/foo/foo.txt rename to tests/Symfony/Tests/Component/HttpKernel/Fixtures/ChildBundle/Resources/foo.txt diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/skeleton/bundle/generic/Resources/views/.gitkeep b/tests/Symfony/Tests/Component/HttpKernel/Fixtures/ChildBundle/Resources/hide.txt similarity index 100% rename from src/Symfony/Bundle/FrameworkBundle/Resources/skeleton/bundle/generic/Resources/views/.gitkeep rename to tests/Symfony/Tests/Component/HttpKernel/Fixtures/ChildBundle/Resources/hide.txt diff --git a/tests/Symfony/Tests/Component/HttpKernel/Fixtures/ExtensionPresentBundle/Command/FooCommand.php b/tests/Symfony/Tests/Component/HttpKernel/Fixtures/ExtensionPresentBundle/Command/FooCommand.php index 1914ad70a0..398cb817fc 100644 --- a/tests/Symfony/Tests/Component/HttpKernel/Fixtures/ExtensionPresentBundle/Command/FooCommand.php +++ b/tests/Symfony/Tests/Component/HttpKernel/Fixtures/ExtensionPresentBundle/Command/FooCommand.php @@ -19,5 +19,5 @@ class FooCommand extends Command { $this->setName('foo'); } - + } diff --git a/tests/Symfony/Tests/Component/HttpKernel/Fixtures/Resources/BaseBundle/hide.txt b/tests/Symfony/Tests/Component/HttpKernel/Fixtures/Resources/BaseBundle/hide.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Symfony/Tests/Component/HttpKernel/Fixtures/Resources/Bundle1Bundle/foo.txt b/tests/Symfony/Tests/Component/HttpKernel/Fixtures/Resources/Bundle1Bundle/foo.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Symfony/Tests/Component/HttpKernel/Fixtures/Resources/ChildBundle/foo.txt b/tests/Symfony/Tests/Component/HttpKernel/Fixtures/Resources/ChildBundle/foo.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Symfony/Tests/Component/HttpKernel/Fixtures/Resources/FooBundle/foo.txt b/tests/Symfony/Tests/Component/HttpKernel/Fixtures/Resources/FooBundle/foo.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Symfony/Tests/Component/HttpKernel/HttpKernelTest.php b/tests/Symfony/Tests/Component/HttpKernel/HttpKernelTest.php index 2e86b88b83..852c9f2bcd 100644 --- a/tests/Symfony/Tests/Component/HttpKernel/HttpKernelTest.php +++ b/tests/Symfony/Tests/Component/HttpKernel/HttpKernelTest.php @@ -88,6 +88,47 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase $kernel->handle(new Request()); } + public function testHandleWhenNoControllerIsAClosure() + { + $response = new Response('foo'); + $dispatcher = new EventDispatcher(); + $kernel = new HttpKernel($dispatcher, $this->getResolver(function () use ($response) { return $response; })); + + $this->assertSame($response, $kernel->handle(new Request())); + } + + public function testHandleWhenNoControllerIsAnObjectWithInvoke() + { + $dispatcher = new EventDispatcher(); + $kernel = new HttpKernel($dispatcher, $this->getResolver(new Controller())); + + $this->assertEquals(new Response('foo'), $kernel->handle(new Request())); + } + + public function testHandleWhenNoControllerIsAFunction() + { + $dispatcher = new EventDispatcher(); + $kernel = new HttpKernel($dispatcher, $this->getResolver('Symfony\Tests\Component\HttpKernel\controller_func')); + + $this->assertEquals(new Response('foo'), $kernel->handle(new Request())); + } + + public function testHandleWhenNoControllerIsAnArray() + { + $dispatcher = new EventDispatcher(); + $kernel = new HttpKernel($dispatcher, $this->getResolver(array(new Controller(), 'controller'))); + + $this->assertEquals(new Response('foo'), $kernel->handle(new Request())); + } + + public function testHandleWhenNoControllerIsAStaticArray() + { + $dispatcher = new EventDispatcher(); + $kernel = new HttpKernel($dispatcher, $this->getResolver(array('Symfony\Tests\Component\HttpKernel\Controller', 'staticcontroller'))); + + $this->assertEquals(new Response('foo'), $kernel->handle(new Request())); + } + /** * @expectedException LogicException */ @@ -140,3 +181,26 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase return $resolver; } } + +class Controller +{ + public function __invoke() + { + return new Response('foo'); + } + + public function controller() + { + return new Response('foo'); + } + + static public function staticController() + { + return new Response('foo'); + } +} + +function controller_func() +{ + return new Response('foo'); +} diff --git a/tests/Symfony/Tests/Component/HttpKernel/KernelTest.php b/tests/Symfony/Tests/Component/HttpKernel/KernelTest.php index b87603dd71..aa5c1aba60 100644 --- a/tests/Symfony/Tests/Component/HttpKernel/KernelTest.php +++ b/tests/Symfony/Tests/Component/HttpKernel/KernelTest.php @@ -303,10 +303,232 @@ EOF; $this->assertEquals($expected, $kernel->serialize()); } + /** + * @expectedException \InvalidArgumentException + */ + public function testLocateResourceThrowsExceptionWhenNameIsNotValid() + { + $this->getKernelForInvalidLocateResource()->locateResource('Foo'); + } + + /** + * @expectedException \RuntimeException + */ + public function testLocateResourceThrowsExceptionWhenNameIsUnsafe() + { + $this->getKernelForInvalidLocateResource()->locateResource('@FooBundle/../bar'); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testLocateResourceThrowsExceptionWhenBundleDoesNotExist() + { + $this->getKernelForInvalidLocateResource()->locateResource('@FooBundle/config/routing.xml'); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testLocateResourceThrowsExceptionWhenResourceDoesNotExist() + { + $kernel = $this->getKernel(); + $kernel + ->expects($this->once()) + ->method('getBundle') + ->will($this->returnValue(array($this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle')))) + ; + + $kernel->locateResource('@Bundle1Bundle/config/routing.xml'); + } + + public function testLocateResourceReturnsTheFirstThatMatches() + { + $kernel = $this->getKernel(); + $kernel + ->expects($this->once()) + ->method('getBundle') + ->will($this->returnValue(array($this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle')))) + ; + + $this->assertEquals(__DIR__.'/Fixtures/Bundle1Bundle/foo.txt', $kernel->locateResource('@Bundle1Bundle/foo.txt')); + } + + public function testLocateResourceReturnsTheFirstThatMatchesWithParent() + { + $parent = $this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle'); + $child = $this->getBundle(__DIR__.'/Fixtures/Bundle2Bundle'); + + $kernel = $this->getKernel(); + $kernel + ->expects($this->exactly(2)) + ->method('getBundle') + ->will($this->returnValue(array($child, $parent))) + ; + + $this->assertEquals(__DIR__.'/Fixtures/Bundle2Bundle/foo.txt', $kernel->locateResource('@ParentAABundle/foo.txt')); + $this->assertEquals(__DIR__.'/Fixtures/Bundle1Bundle/bar.txt', $kernel->locateResource('@ParentAABundle/bar.txt')); + } + + public function testLocateResourceReturnsAllMatches() + { + $parent = $this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle'); + $child = $this->getBundle(__DIR__.'/Fixtures/Bundle2Bundle'); + + $kernel = $this->getKernel(); + $kernel + ->expects($this->once()) + ->method('getBundle') + ->will($this->returnValue(array($child, $parent))) + ; + + $this->assertEquals(array( + __DIR__.'/Fixtures/Bundle2Bundle/foo.txt', + __DIR__.'/Fixtures/Bundle1Bundle/foo.txt'), + $kernel->locateResource('@Bundle1Bundle/foo.txt', null, false)); + } + + public function testLocateResourceReturnsAllMatchesBis() + { + $kernel = $this->getKernel(); + $kernel + ->expects($this->once()) + ->method('getBundle') + ->will($this->returnValue(array( + $this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle'), + $this->getBundle(__DIR__.'/Foobar') + ))) + ; + + $this->assertEquals( + array(__DIR__.'/Fixtures/Bundle1Bundle/foo.txt'), + $kernel->locateResource('@Bundle1Bundle/foo.txt', null, false) + ); + } + + public function testLocateResourceIgnoresDirOnNonResource() + { + $kernel = $this->getKernel(); + $kernel + ->expects($this->once()) + ->method('getBundle') + ->will($this->returnValue(array($this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle')))) + ; + + $this->assertEquals( + __DIR__.'/Fixtures/Bundle1Bundle/foo.txt', + $kernel->locateResource('@Bundle1Bundle/foo.txt', __DIR__.'/Fixtures') + ); + } + + public function testLocateResourceReturnsTheDirOneForResources() + { + $kernel = $this->getKernel(); + $kernel + ->expects($this->once()) + ->method('getBundle') + ->will($this->returnValue(array($this->getBundle(__DIR__.'/Fixtures/FooBundle', null, null, 'FooBundle')))) + ; + + $this->assertEquals( + __DIR__.'/Fixtures/Resources/FooBundle/foo.txt', + $kernel->locateResource('@FooBundle/Resources/foo.txt', __DIR__.'/Fixtures/Resources') + ); + } + + public function testLocateResourceReturnsTheDirOneForResourcesAndBundleOnes() + { + $kernel = $this->getKernel(); + $kernel + ->expects($this->once()) + ->method('getBundle') + ->will($this->returnValue(array($this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle', null, null, 'Bundle1Bundle')))) + ; + + $this->assertEquals(array( + __DIR__.'/Fixtures/Resources/Bundle1Bundle/foo.txt', + __DIR__.'/Fixtures/Bundle1Bundle/Resources/foo.txt'), + $kernel->locateResource('@Bundle1Bundle/Resources/foo.txt', __DIR__.'/Fixtures/Resources', false) + ); + } + + public function testLocateResourceOverrideBundleAndResourcesFolders() + { + $parent = $this->getBundle(__DIR__.'/Fixtures/BaseBundle', null, 'BaseBundle', 'BaseBundle'); + $child = $this->getBundle(__DIR__.'/Fixtures/ChildBundle', 'ParentBundle', 'ChildBundle', 'ChildBundle'); + + $kernel = $this->getKernel(); + $kernel + ->expects($this->exactly(4)) + ->method('getBundle') + ->will($this->returnValue(array($child, $parent))) + ; + + $this->assertEquals(array( + __DIR__.'/Fixtures/Resources/ChildBundle/foo.txt', + __DIR__.'/Fixtures/ChildBundle/Resources/foo.txt', + __DIR__.'/Fixtures/BaseBundle/Resources/foo.txt', + ), + $kernel->locateResource('@BaseBundle/Resources/foo.txt', __DIR__.'/Fixtures/Resources', false) + ); + + $this->assertEquals( + __DIR__.'/Fixtures/Resources/ChildBundle/foo.txt', + $kernel->locateResource('@BaseBundle/Resources/foo.txt', __DIR__.'/Fixtures/Resources') + ); + + try { + $kernel->locateResource('@BaseBundle/Resources/hide.txt', __DIR__.'/Fixtures/Resources', false); + $this->fail('Hidden resources should raise an exception when returning an array of matching paths'); + } catch (\RuntimeException $e) { + } + + try { + $kernel->locateResource('@BaseBundle/Resources/hide.txt', __DIR__.'/Fixtures/Resources', true); + $this->fail('Hidden resources should raise an exception when returning the first matching path'); + } catch (\RuntimeException $e) { + } + } + + public function testLocateResourceOnDirectories() + { + $kernel = $this->getKernel(); + $kernel + ->expects($this->exactly(2)) + ->method('getBundle') + ->will($this->returnValue(array($this->getBundle(__DIR__.'/Fixtures/FooBundle', null, null, 'FooBundle')))) + ; + + $this->assertEquals( + __DIR__.'/Fixtures/Resources/FooBundle/', + $kernel->locateResource('@FooBundle/Resources/', __DIR__.'/Fixtures/Resources') + ); + $this->assertEquals( + __DIR__.'/Fixtures/Resources/FooBundle', + $kernel->locateResource('@FooBundle/Resources', __DIR__.'/Fixtures/Resources') + ); + + $kernel = $this->getKernel(); + $kernel + ->expects($this->exactly(2)) + ->method('getBundle') + ->will($this->returnValue(array($this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle', null, null, 'Bundle1Bundle')))) + ; + + $this->assertEquals( + __DIR__.'/Fixtures/Bundle1Bundle/Resources/', + $kernel->locateResource('@Bundle1Bundle/Resources/') + ); + $this->assertEquals( + __DIR__.'/Fixtures/Bundle1Bundle/Resources', + $kernel->locateResource('@Bundle1Bundle/Resources') + ); + } + public function testInitializeBundles() { $parent = $this->getBundle(null, null, 'ParentABundle'); - $child = $this->getBundle(null, 'ParentA', 'ChildABundle'); + $child = $this->getBundle(null, 'ParentABundle', 'ChildABundle'); $kernel = $this->getKernel(); $kernel @@ -317,14 +539,14 @@ EOF; $kernel->initializeBundles(); $map = $kernel->getBundleMap(); - $this->assertEquals(array($child, $parent), $map['ParentA']); + $this->assertEquals(array($child, $parent), $map['ParentABundle']); } public function testInitializeBundlesSupportInheritanceCascade() { $grandparent = $this->getBundle(null, null, 'GrandParentBBundle'); - $parent = $this->getBundle(null, 'GrandParentB', 'ParentBBundle'); - $child = $this->getBundle(null, 'ParentB', 'ChildBBundle'); + $parent = $this->getBundle(null, 'GrandParentBBundle', 'ParentBBundle'); + $child = $this->getBundle(null, 'ParentBBundle', 'ChildBBundle'); $kernel = $this->getKernel(); $kernel @@ -336,9 +558,9 @@ EOF; $kernel->initializeBundles(); $map = $kernel->getBundleMap(); - $this->assertEquals(array($child, $parent, $grandparent), $map['GrandParentB']); - $this->assertEquals(array($child, $parent), $map['ParentB']); - $this->assertEquals(array($child), $map['ChildB']); + $this->assertEquals(array($child, $parent, $grandparent), $map['GrandParentBBundle']); + $this->assertEquals(array($child, $parent), $map['ParentBBundle']); + $this->assertEquals(array($child), $map['ChildBBundle']); } /** @@ -359,9 +581,9 @@ EOF; public function testInitializeBundlesSupportsArbitraryBundleRegistrationOrder() { - $grandparent = $this->getBundle(null, null, 'GrandParentCBundle'); - $parent = $this->getBundle(null, 'GrandParentC', 'ParentCBundle'); - $child = $this->getBundle(null, 'ParentC', 'ChildC1Bundle'); + $grandparent = $this->getBundle(null, null, 'GrandParentCCundle'); + $parent = $this->getBundle(null, 'GrandParentCCundle', 'ParentCCundle'); + $child = $this->getBundle(null, 'ParentCCundle', 'ChildCCundle'); $kernel = $this->getKernel(); $kernel @@ -373,9 +595,9 @@ EOF; $kernel->initializeBundles(); $map = $kernel->getBundleMap(); - $this->assertEquals(array($child, $parent, $grandparent), $map['GrandParentC']); - $this->assertEquals(array($child, $parent), $map['ParentC']); - $this->assertEquals(array($child), $map['ChildC1']); + $this->assertEquals(array($child, $parent, $grandparent), $map['GrandParentCCundle']); + $this->assertEquals(array($child, $parent), $map['ParentCCundle']); + $this->assertEquals(array($child), $map['ChildCCundle']); } /** @@ -383,9 +605,9 @@ EOF; */ public function testInitializeBundlesThrowsExceptionWhenABundleIsDirectlyExtendedByTwoBundles() { - $parent = $this->getBundle(null, null, 'ParentC1Bundle'); - $child1 = $this->getBundle(null, 'ParentC1', 'ChildC2Bundle'); - $child2 = $this->getBundle(null, 'ParentC1', 'ChildC3Bundle'); + $parent = $this->getBundle(null, null, 'ParentCBundle'); + $child1 = $this->getBundle(null, 'ParentCBundle', 'ChildC1Bundle'); + $child2 = $this->getBundle(null, 'ParentCBundle', 'ChildC2Bundle'); $kernel = $this->getKernel(); $kernel @@ -413,33 +635,53 @@ EOF; $kernel->initializeBundles(); } + /** + * @expectedException \LogicException + */ + public function testInitializeBundleThrowsExceptionWhenABundleExtendsItself() + { + $circularRef = $this->getBundle(null, 'CircularRefBundle', 'CircularRefBundle'); + + $kernel = $this->getKernel(); + $kernel + ->expects($this->once()) + ->method('registerBundles') + ->will($this->returnValue(array($circularRef))) + ; + $kernel->initializeBundles(); + } + protected function getBundle($dir = null, $parent = null, $className = null, $bundleName = null) { - if (null === $className) { - $className = 'Test'.rand(11111, 99999).'Bundle'; - } - - if (null === $bundleName) { - $bundleName = substr($className, 0, -6); - } - - $bundle = $this->getMockBuilder('Symfony\Tests\Component\HttpKernel\BundleForTest') - ->disableOriginalConstructor() + $bundle = $this + ->getMockBuilder('Symfony\Tests\Component\HttpKernel\BundleForTest') ->setMethods(array('getPath', 'getParent', 'getName')) - ->setMockClassName($className) - ->getMockForAbstractClass(); + ->disableOriginalConstructor() + ; - $bundle->expects($this->any()) + if ($className) { + $bundle->setMockClassName($className); + } + + $bundle = $bundle->getMockForAbstractClass(); + + $bundle + ->expects($this->any()) ->method('getName') - ->will($this->returnValue($bundleName)); + ->will($this->returnValue(null === $bundleName ? get_class($bundle) : $bundleName)) + ; - $bundle->expects($this->any()) + $bundle + ->expects($this->any()) ->method('getPath') - ->will($this->returnValue(strtr($dir, '\\', '/'))); + ->will($this->returnValue($dir)) + ; - $bundle->expects($this->any()) + $bundle + ->expects($this->any()) ->method('getParent') - ->will($this->returnValue($parent)); + ->will($this->returnValue($parent)) + ; return $bundle; } @@ -453,6 +695,15 @@ EOF; ->getMock() ; } + + protected function getKernelForInvalidLocateResource() + { + return $this + ->getMockBuilder('Symfony\Component\HttpKernel\Kernel') + ->disableOriginalConstructor() + ->getMockForAbstractClass() + ; + } } class KernelForTest extends Kernel diff --git a/tests/Symfony/Tests/Component/Locale/Stub/StubIntlDateFormatterTest.php b/tests/Symfony/Tests/Component/Locale/Stub/StubIntlDateFormatterTest.php index b81c81b2b3..9c32446773 100644 --- a/tests/Symfony/Tests/Component/Locale/Stub/StubIntlDateFormatterTest.php +++ b/tests/Symfony/Tests/Component/Locale/Stub/StubIntlDateFormatterTest.php @@ -833,12 +833,9 @@ class StubIntlDateFormatterTest extends LocaleTestCase protected function createDateTime($timestamp = null, $timeZone = null) { - $timestamp = is_null($timestamp) ? time() : $timestamp; - $timeZone = is_null($timeZone) ? date_default_timezone_get() : $timeZone; - $dateTime = new \DateTime(); - $dateTime->setTimestamp($timestamp); - $dateTime->setTimeZone(new \DateTimeZone($timeZone)); + $dateTime->setTimestamp(null === $timestamp ? time() : $timestamp); + $dateTime->setTimeZone(new \DateTimeZone(null === $timeZone ? date_default_timezone_get() : $timeZone)); return $dateTime; } diff --git a/tests/Symfony/Tests/Component/Locale/Stub/StubNumberFormatterTest.php b/tests/Symfony/Tests/Component/Locale/Stub/StubNumberFormatterTest.php index f796680ce3..7ec762dce0 100644 --- a/tests/Symfony/Tests/Component/Locale/Stub/StubNumberFormatterTest.php +++ b/tests/Symfony/Tests/Component/Locale/Stub/StubNumberFormatterTest.php @@ -384,7 +384,7 @@ class StubNumberFormatterTest extends LocaleTestCase { $formatter = $this->getStubFormatterWithDecimalStyle(); - if (!is_null($fractionDigits)) { + if (null !== $fractionDigits) { $attributeRet = $formatter->setAttribute(StubNumberFormatter::FRACTION_DIGITS, $fractionDigits); } @@ -405,7 +405,7 @@ class StubNumberFormatterTest extends LocaleTestCase $this->skipIfIntlExtensionIsNotLoaded(); $formatter = $this->getIntlFormatterWithDecimalStyle(); - if (!is_null($fractionDigits)) { + if (null !== $fractionDigits) { $attributeRet = $formatter->setAttribute(\NumberFormatter::FRACTION_DIGITS, $fractionDigits); } @@ -437,7 +437,7 @@ class StubNumberFormatterTest extends LocaleTestCase { $formatter = $this->getStubFormatterWithDecimalStyle(); - if (!is_null($groupingUsed)) { + if (null !== $groupingUsed) { $attributeRet = $formatter->setAttribute(StubNumberFormatter::GROUPING_USED, $groupingUsed); } @@ -458,7 +458,7 @@ class StubNumberFormatterTest extends LocaleTestCase $this->skipIfIntlExtensionIsNotLoaded(); $formatter = $this->getIntlFormatterWithDecimalStyle(); - if (!is_null($groupingUsed)) { + if (null !== $groupingUsed) { $attributeRet = $formatter->setAttribute(\NumberFormatter::GROUPING_USED, $groupingUsed); } diff --git a/tests/Symfony/Tests/Component/Routing/Annotation/RouteTest.php b/tests/Symfony/Tests/Component/Routing/Annotation/RouteTest.php index 0b1ee6ec88..4ef8fbab50 100644 --- a/tests/Symfony/Tests/Component/Routing/Annotation/RouteTest.php +++ b/tests/Symfony/Tests/Component/Routing/Annotation/RouteTest.php @@ -39,7 +39,7 @@ class RouteTest extends \PHPUnit_Framework_TestCase array('requirements', array('_method' => 'GET'), 'getRequirements'), array('options', array('segment_separators' => array('/')), 'getOptions'), array('name', 'blog_index', 'getName'), - array('defaults', array('_controller' => 'MyBlog:Blog:index'), 'getDefaults') + array('defaults', array('_controller' => 'MyBlogBundle:Blog:index'), 'getDefaults') ); } } diff --git a/tests/Symfony/Tests/Component/Routing/Fixtures/RedirectableUrlMatcher.php b/tests/Symfony/Tests/Component/Routing/Fixtures/RedirectableUrlMatcher.php new file mode 100644 index 0000000000..81f021afee --- /dev/null +++ b/tests/Symfony/Tests/Component/Routing/Fixtures/RedirectableUrlMatcher.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Tests\Component\Routing\Fixtures; + +use Symfony\Component\Routing\Matcher\UrlMatcher; +use Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface; + +/** + * @author Fabien Potencier + */ +class RedirectableUrlMatcher extends UrlMatcher implements RedirectableUrlMatcherInterface +{ + public function redirect($path, $route, $scheme = null) + { + return array( + '_controller' => 'Some controller reference...', + 'path' => $path, + 'scheme' => $scheme, + ); + } +} diff --git a/tests/Symfony/Tests/Component/Routing/Fixtures/dumper/url_matcher1.php b/tests/Symfony/Tests/Component/Routing/Fixtures/dumper/url_matcher1.php index 564a6e0c9a..3250215125 100644 --- a/tests/Symfony/Tests/Component/Routing/Fixtures/dumper/url_matcher1.php +++ b/tests/Symfony/Tests/Component/Routing/Fixtures/dumper/url_matcher1.php @@ -2,6 +2,7 @@ use Symfony\Component\Routing\Matcher\Exception\MethodNotAllowedException; use Symfony\Component\Routing\Matcher\Exception\NotFoundException; +use Symfony\Component\Routing\RequestContext; /** * ProjectUrlMatcher @@ -14,10 +15,9 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher /** * Constructor. */ - public function __construct(array $context = array(), array $defaults = array()) + public function __construct(RequestContext $context) { $this->context = $context; - $this->defaults = $defaults; } public function match($pathinfo) @@ -31,66 +31,63 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher // bar if (0 === strpos($pathinfo, '/bar') && preg_match('#^/bar/(?P[^/\.]+?)$#x', $pathinfo, $matches)) { - if (isset($this->context['method']) && !in_array(strtolower($this->context['method']), array('get', 'head'))) { + if (!in_array($this->context->getMethod(), array('get', 'head'))) { $allow = array_merge($allow, array('get', 'head')); goto not_bar; } - return array_merge($this->mergeDefaults($matches, array ()), array('_route' => 'bar')); + $matches['_route'] = 'bar'; + return $matches; } not_bar: // baz if ($pathinfo === '/test/baz') { - return array_merge($this->mergeDefaults(array(), array ()), array('_route' => 'baz')); + return array('_route' => 'baz'); } // baz2 if ($pathinfo === '/test/baz.html') { - return array_merge($this->mergeDefaults(array(), array ()), array('_route' => 'baz2')); + return array('_route' => 'baz2'); } // baz3 - if (rtrim($pathinfo, '/') === '/test/baz3') { - if (substr($pathinfo, -1) !== '/') { - return array('_controller' => 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction', 'url' => $this->context['base_url'].$pathinfo.'/', 'permanent' => true, '_route' => 'baz3'); - } - return array_merge($this->mergeDefaults(array(), array ()), array('_route' => 'baz3')); + if ($pathinfo === '/test/baz3/') { + return array('_route' => 'baz3'); } // baz4 - if (0 === strpos($pathinfo, '/test') && preg_match('#^/test/(?P[^/\.]+?)/?$#x', $pathinfo, $matches)) { - if (substr($pathinfo, -1) !== '/') { - return array('_controller' => 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction', 'url' => $this->context['base_url'].$pathinfo.'/', 'permanent' => true, '_route' => 'baz4'); - } - return array_merge($this->mergeDefaults($matches, array ()), array('_route' => 'baz4')); + if (0 === strpos($pathinfo, '/test') && preg_match('#^/test/(?P[^/\.]+?)/$#x', $pathinfo, $matches)) { + $matches['_route'] = 'baz4'; + return $matches; } // baz5 - if (0 === strpos($pathinfo, '/test') && preg_match('#^/test/(?P[^/\.]+?)/?$#x', $pathinfo, $matches)) { - if (isset($this->context['method']) && !in_array(strtolower($this->context['method']), array('post'))) { - $allow = array_merge($allow, array('post')); + if (0 === strpos($pathinfo, '/test') && preg_match('#^/test/(?P[^/\.]+?)/$#x', $pathinfo, $matches)) { + if ($this->context->getMethod() != 'post') { + $allow[] = 'post'; goto not_baz5; } - if (substr($pathinfo, -1) !== '/') { - return array('_controller' => 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction', 'url' => $this->context['base_url'].$pathinfo.'/', 'permanent' => true, '_route' => 'baz5'); - } - return array_merge($this->mergeDefaults($matches, array ()), array('_route' => 'baz5')); + $matches['_route'] = 'baz5'; + return $matches; } not_baz5: // baz.baz6 - if (0 === strpos($pathinfo, '/test') && preg_match('#^/test/(?P[^/\.]+?)/?$#x', $pathinfo, $matches)) { - if (isset($this->context['method']) && !in_array(strtolower($this->context['method']), array('put'))) { - $allow = array_merge($allow, array('put')); + if (0 === strpos($pathinfo, '/test') && preg_match('#^/test/(?P[^/\.]+?)/$#x', $pathinfo, $matches)) { + if ($this->context->getMethod() != 'put') { + $allow[] = 'put'; goto not_bazbaz6; } - if (substr($pathinfo, -1) !== '/') { - return array('_controller' => 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction', 'url' => $this->context['base_url'].$pathinfo.'/', 'permanent' => true, '_route' => 'baz.baz6'); - } - return array_merge($this->mergeDefaults($matches, array ()), array('_route' => 'baz.baz6')); + $matches['_route'] = 'baz.baz6'; + return $matches; } not_bazbaz6: + // foofoo + if ($pathinfo === '/foofoo') { + return array ( 'def' => 'test', '_route' => 'foofoo',); + } + throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new NotFoundException(); } } diff --git a/tests/Symfony/Tests/Component/Routing/Fixtures/dumper/url_matcher2.php b/tests/Symfony/Tests/Component/Routing/Fixtures/dumper/url_matcher2.php new file mode 100644 index 0000000000..db003bb89d --- /dev/null +++ b/tests/Symfony/Tests/Component/Routing/Fixtures/dumper/url_matcher2.php @@ -0,0 +1,121 @@ +context = $context; + } + + public function match($pathinfo) + { + $allow = array(); + + // foo + if (0 === strpos($pathinfo, '/foo') && preg_match('#^/foo/(?Pbaz|symfony)$#x', $pathinfo, $matches)) { + return array_merge($this->mergeDefaults($matches, array ( 'def' => 'test',)), array('_route' => 'foo')); + } + + // bar + if (0 === strpos($pathinfo, '/bar') && preg_match('#^/bar/(?P[^/\.]+?)$#x', $pathinfo, $matches)) { + if (!in_array($this->context->getMethod(), array('get', 'head'))) { + $allow = array_merge($allow, array('get', 'head')); + goto not_bar; + } + $matches['_route'] = 'bar'; + return $matches; + } + not_bar: + + // baz + if ($pathinfo === '/test/baz') { + return array('_route' => 'baz'); + } + + // baz2 + if ($pathinfo === '/test/baz.html') { + return array('_route' => 'baz2'); + } + + // baz3 + if (rtrim($pathinfo, '/') === '/test/baz3') { + if (substr($pathinfo, -1) !== '/') { + return $this->redirect($pathinfo.'/', 'baz3'); + } + return array('_route' => 'baz3'); + } + + // baz4 + if (0 === strpos($pathinfo, '/test') && preg_match('#^/test/(?P[^/\.]+?)/?$#x', $pathinfo, $matches)) { + if (substr($pathinfo, -1) !== '/') { + return $this->redirect($pathinfo.'/', 'baz4'); + } + $matches['_route'] = 'baz4'; + return $matches; + } + + // baz5 + if (0 === strpos($pathinfo, '/test') && preg_match('#^/test/(?P[^/\.]+?)/?$#x', $pathinfo, $matches)) { + if ($this->context->getMethod() != 'post') { + $allow[] = 'post'; + goto not_baz5; + } + if (substr($pathinfo, -1) !== '/') { + return $this->redirect($pathinfo.'/', 'baz5'); + } + $matches['_route'] = 'baz5'; + return $matches; + } + not_baz5: + + // baz.baz6 + if (0 === strpos($pathinfo, '/test') && preg_match('#^/test/(?P[^/\.]+?)/?$#x', $pathinfo, $matches)) { + if ($this->context->getMethod() != 'put') { + $allow[] = 'put'; + goto not_bazbaz6; + } + if (substr($pathinfo, -1) !== '/') { + return $this->redirect($pathinfo.'/', 'baz.baz6'); + } + $matches['_route'] = 'baz.baz6'; + return $matches; + } + not_bazbaz6: + + // foofoo + if ($pathinfo === '/foofoo') { + return array ( 'def' => 'test', '_route' => 'foofoo',); + } + + // secure + if ($pathinfo === '/secure') { + if ($this->context->getScheme() !== 'https') { + return $this->redirect($pathinfo, 'secure', 'https'); + } + return array('_route' => 'secure'); + } + + // nonsecure + if ($pathinfo === '/nonsecure') { + if ($this->context->getScheme() !== 'http') { + return $this->redirect($pathinfo, 'nonsecure', 'http'); + } + return array('_route' => 'nonsecure'); + } + + throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new NotFoundException(); + } +} diff --git a/tests/Symfony/Tests/Component/Routing/Fixtures/incomplete.yml b/tests/Symfony/Tests/Component/Routing/Fixtures/incomplete.yml index 74db2f7a98..df64d324f9 100644 --- a/tests/Symfony/Tests/Component/Routing/Fixtures/incomplete.yml +++ b/tests/Symfony/Tests/Component/Routing/Fixtures/incomplete.yml @@ -1,2 +1,2 @@ blog_show: - defaults: { _controller: MyBlog:Blog:show } + defaults: { _controller: MyBlogBundle:Blog:show } diff --git a/tests/Symfony/Tests/Component/Routing/Fixtures/nonvalid.xml b/tests/Symfony/Tests/Component/Routing/Fixtures/nonvalid.xml index ddb00f46e4..1414e7e460 100644 --- a/tests/Symfony/Tests/Component/Routing/Fixtures/nonvalid.xml +++ b/tests/Symfony/Tests/Component/Routing/Fixtures/nonvalid.xml @@ -5,7 +5,7 @@ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd"> - My:Blog:show + MyBundle:Blog:show GET diff --git a/tests/Symfony/Tests/Component/Routing/Fixtures/nonvalidroute.xml b/tests/Symfony/Tests/Component/Routing/Fixtures/nonvalidroute.xml index 7ca439f5f9..a6ef587ac8 100644 --- a/tests/Symfony/Tests/Component/Routing/Fixtures/nonvalidroute.xml +++ b/tests/Symfony/Tests/Component/Routing/Fixtures/nonvalidroute.xml @@ -5,7 +5,7 @@ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd"> - My:Blog:show + MyBundle:Blog:show GET baz diff --git a/tests/Symfony/Tests/Component/Routing/Fixtures/validpattern.php b/tests/Symfony/Tests/Component/Routing/Fixtures/validpattern.php index d2db514428..d96436cb0f 100644 --- a/tests/Symfony/Tests/Component/Routing/Fixtures/validpattern.php +++ b/tests/Symfony/Tests/Component/Routing/Fixtures/validpattern.php @@ -4,7 +4,7 @@ use Symfony\Component\Routing\Route; $collection = new RouteCollection(); $collection->add('blog_show', new Route('/blog/{slug}', array( - '_controller' => 'MyBlog:Blog:show', + '_controller' => 'MyBlogBundle:Blog:show', ))); return $collection; diff --git a/tests/Symfony/Tests/Component/Routing/Fixtures/validpattern.xml b/tests/Symfony/Tests/Component/Routing/Fixtures/validpattern.xml index c4f5da2cfa..a1620415f8 100644 --- a/tests/Symfony/Tests/Component/Routing/Fixtures/validpattern.xml +++ b/tests/Symfony/Tests/Component/Routing/Fixtures/validpattern.xml @@ -5,7 +5,7 @@ xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd"> - My:Blog:show + MyBundle:Blog:show GET diff --git a/tests/Symfony/Tests/Component/Routing/Fixtures/validpattern.yml b/tests/Symfony/Tests/Component/Routing/Fixtures/validpattern.yml index ceb318843c..8d79b2b276 100644 --- a/tests/Symfony/Tests/Component/Routing/Fixtures/validpattern.yml +++ b/tests/Symfony/Tests/Component/Routing/Fixtures/validpattern.yml @@ -1,4 +1,4 @@ blog_show: pattern: /blog/{slug} - defaults: { _controller: MyBlog:Blog:show } + defaults: { _controller: MyBlogBundle:Blog:show } diff --git a/tests/Symfony/Tests/Component/Routing/Generator/Dumper/PhpGeneratorDumperTest.php b/tests/Symfony/Tests/Component/Routing/Generator/Dumper/PhpGeneratorDumperTest.php index 1374024521..5d5466de67 100644 --- a/tests/Symfony/Tests/Component/Routing/Generator/Dumper/PhpGeneratorDumperTest.php +++ b/tests/Symfony/Tests/Component/Routing/Generator/Dumper/PhpGeneratorDumperTest.php @@ -14,6 +14,7 @@ namespace Symfony\Tests\Component\Routing\Generator\Dumper\PhpGeneratorDumper; use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper; +use Symfony\Component\Routing\RequestContext; class PhpGeneratorDumperTest extends \PHPUnit_Framework_TestCase { @@ -21,12 +22,12 @@ class PhpGeneratorDumperTest extends \PHPUnit_Framework_TestCase * @var RouteCollection */ private $routeCollection; - + /** * @var PhpGeneratorDumper */ private $generatorDumper; - + /** * @var string */ @@ -37,7 +38,7 @@ class PhpGeneratorDumperTest extends \PHPUnit_Framework_TestCase parent::setUp(); $this->routeCollection = new RouteCollection(); - $this->generatorDumper = new PhpGeneratorDumper($this->routeCollection); + $this->generatorDumper = new PhpGeneratorDumper($this->routeCollection, new RequestContext()); $this->testTmpFilepath = sys_get_temp_dir().DIRECTORY_SEPARATOR.'php_generator.php'; @unlink($this->testTmpFilepath); } @@ -45,7 +46,7 @@ class PhpGeneratorDumperTest extends \PHPUnit_Framework_TestCase protected function tearDown() { parent::tearDown(); - + @unlink($this->testTmpFilepath); } @@ -53,18 +54,12 @@ class PhpGeneratorDumperTest extends \PHPUnit_Framework_TestCase { $this->routeCollection->add('Test', new Route('/testing/{foo}')); $this->routeCollection->add('Test2', new Route('/testing2')); - + file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump()); include ($this->testTmpFilepath); - $projectUrlGenerator = new \ProjectUrlGenerator(array( - 'base_url' => '/app.php', - 'method' => 'GET', - 'host' => 'localhost', - 'port' => 80, - 'is_secure' => false - )); - + $projectUrlGenerator = new \ProjectUrlGenerator(new RequestContext('/app.php')); + $absoluteUrlWithParameter = $projectUrlGenerator->generate('Test', array('foo' => 'bar'), true); $absoluteUrlWithoutParameter = $projectUrlGenerator->generate('Test2', array(), true); $relativeUrlWithParameter = $projectUrlGenerator->generate('Test', array('foo' => 'bar'), false); @@ -75,7 +70,7 @@ class PhpGeneratorDumperTest extends \PHPUnit_Framework_TestCase $this->assertEquals($relativeUrlWithParameter, '/app.php/testing/bar'); $this->assertEquals($relativeUrlWithoutParameter, '/app.php/testing2'); } - + /** * @expectedException \InvalidArgumentException */ @@ -84,25 +79,19 @@ class PhpGeneratorDumperTest extends \PHPUnit_Framework_TestCase file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump(array('class' => 'WithoutRoutesUrlGenerator'))); include ($this->testTmpFilepath); - $projectUrlGenerator = new \WithoutRoutesUrlGenerator(array( - 'base_url' => '/app.php', - 'method' => 'GET', - 'host' => 'localhost', - 'port' => 80, - 'is_secure' => false - )); - + $projectUrlGenerator = new \WithoutRoutesUrlGenerator(new RequestContext('/app.php')); + $projectUrlGenerator->generate('Test', array()); } - + public function testDumpForRouteWithDefaults() { $this->routeCollection->add('Test', new Route('/testing/{foo}', array('foo' => 'bar'))); - + file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump(array('class' => 'DefaultRoutesUrlGenerator'))); include ($this->testTmpFilepath); - - $projectUrlGenerator = new \DefaultRoutesUrlGenerator(array()); + + $projectUrlGenerator = new \DefaultRoutesUrlGenerator(new RequestContext()); $url = $projectUrlGenerator->generate('Test', array()); $this->assertEquals($url, '/testing'); diff --git a/tests/Symfony/Tests/Component/Routing/Generator/UrlGeneratorTest.php b/tests/Symfony/Tests/Component/Routing/Generator/UrlGeneratorTest.php index 5cdf04393a..03d9f997da 100644 --- a/tests/Symfony/Tests/Component/Routing/Generator/UrlGeneratorTest.php +++ b/tests/Symfony/Tests/Component/Routing/Generator/UrlGeneratorTest.php @@ -14,176 +14,177 @@ namespace Symfony\Tests\Component\Routing\Generator; use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\Generator\UrlGenerator; +use Symfony\Component\Routing\RequestContext; class UrlGeneratorTest extends \PHPUnit_Framework_TestCase { - /** @var RouteCollection */ - private $routeCollection; - /** @var UrlGenerator */ - private $generator; - - protected function setUp() - { - parent::setUp(); - - $this->routeCollection = new RouteCollection(); - $this->generator = new UrlGenerator($this->routeCollection); - } - public function testAbsoluteUrlWithPort80() { - $this->routeCollection->add('test', new Route('/testing')); - $this->generator->setContext(array( - 'base_url'=>'/app.php', - 'method'=>'GET', - 'host'=>'localhost', - 'port'=>80, - 'is_secure'=>false)); - - $url = $this->generator->generate('test', array(), true); + $routes = $this->getRoutes('test', new Route('/testing')); + $url = $this->getGenerator($routes)->generate('test', array(), true); $this->assertEquals('http://localhost/app.php/testing', $url); } public function testAbsoluteSecureUrlWithPort443() { - $this->routeCollection->add('test', new Route('/testing')); - $this->generator->setContext(array( - 'base_url'=>'/app.php', - 'method'=>'GET', - 'host'=>'localhost', - 'port'=>443, - 'is_secure'=>true)); - - $url = $this->generator->generate('test', array(), true); + $routes = $this->getRoutes('test', new Route('/testing')); + $url = $this->getGenerator($routes, array('scheme' => 'https'))->generate('test', array(), true); $this->assertEquals('https://localhost/app.php/testing', $url); } public function testAbsoluteUrlWithNonStandardPort() { - $this->routeCollection->add('test', new Route('/testing')); - $this->generator->setContext(array( - 'base_url'=>'/app.php', - 'method'=>'GET', - 'host'=>'localhost', - 'port'=>8080, - 'is_secure'=>false)); - - $url = $this->generator->generate('test', array(), true); + $routes = $this->getRoutes('test', new Route('/testing')); + $url = $this->getGenerator($routes, array('httpPort' => 8080))->generate('test', array(), true); $this->assertEquals('http://localhost:8080/app.php/testing', $url); } public function testAbsoluteSecureUrlWithNonStandardPort() { - $this->routeCollection->add('test', new Route('/testing')); - $this->generator->setContext(array( - 'base_url'=>'/app.php', - 'method'=>'GET', - 'host'=>'localhost', - 'port'=>8080, - 'is_secure'=>true)); - - $url = $this->generator->generate('test', array(), true); + $routes = $this->getRoutes('test', new Route('/testing')); + $url = $this->getGenerator($routes, array('httpsPort' => 8080, 'scheme' => 'https'))->generate('test', array(), true); $this->assertEquals('https://localhost:8080/app.php/testing', $url); } public function testRelativeUrlWithoutParameters() { - $this->routeCollection->add('test', new Route('/testing')); - $this->generator->setContext(array( - 'base_url'=>'/app.php', - 'method'=>'GET', - 'host'=>'localhost', - 'port'=>80, - 'is_secure'=>false)); - - $url = $this->generator->generate('test', array(), false); + $routes = $this->getRoutes('test', new Route('/testing')); + $url = $this->getGenerator($routes)->generate('test', array(), false); $this->assertEquals('/app.php/testing', $url); } - + public function testRelativeUrlWithParameter() { - $this->routeCollection->add('test', new Route('/testing/{foo}')); - $this->generator->setContext(array( - 'base_url'=>'/app.php', - 'method'=>'GET', - 'host'=>'localhost', - 'port'=>80, - 'is_secure'=>false)); - - $url = $this->generator->generate('test', array('foo' => 'bar'), false); + $routes = $this->getRoutes('test', new Route('/testing/{foo}')); + $url = $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), false); $this->assertEquals('/app.php/testing/bar', $url); } - + + public function testRelativeUrlWithNullParameter() + { + $routes = $this->getRoutes('test', new Route('/testing.{format}', array('format' => null))); + $url = $this->getGenerator($routes)->generate('test', array(), false); + + $this->assertEquals('/app.php/testing', $url); + } + public function testRelativeUrlWithExtraParameters() { - $this->routeCollection->add('test', new Route('/testing')); - $this->generator->setContext(array( - 'base_url'=>'/app.php', - 'method'=>'GET', - 'host'=>'localhost', - 'port'=>80, - 'is_secure'=>false)); - - $url = $this->generator->generate('test', array('foo' => 'bar'), false); + $routes = $this->getRoutes('test', new Route('/testing')); + $url = $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), false); $this->assertEquals('/app.php/testing?foo=bar', $url); } - + public function testAbsoluteUrlWithExtraParameters() { - $this->routeCollection->add('test', new Route('/testing')); - $this->generator->setContext(array( - 'base_url'=>'/app.php', - 'method'=>'GET', - 'host'=>'localhost', - 'port'=>80, - 'is_secure'=>false)); - - $url = $this->generator->generate('test', array('foo' => 'bar'), true); + $routes = $this->getRoutes('test', new Route('/testing')); + $url = $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), true); $this->assertEquals('http://localhost/app.php/testing?foo=bar', $url); } - + + public function testUrlWithExtraParametersFromGlobals() + { + $routes = $this->getRoutes('test', new Route('/testing')); + $generator = $this->getGenerator($routes); + $context = new RequestContext('/app.php'); + $context->setParameter('bar', 'bar'); + $generator->setContext($context); + $url = $generator->generate('test', array('foo' => 'bar')); + + $this->assertEquals('/app.php/testing?foo=bar', $url); + } + + public function testUrlWithGlobalParameter() + { + $routes = $this->getRoutes('test', new Route('/testing/{foo}')); + $generator = $this->getGenerator($routes); + $context = new RequestContext('/app.php'); + $context->setParameter('foo', 'bar'); + $generator->setContext($context); + $url = $generator->generate('test', array()); + + $this->assertEquals('/app.php/testing/bar', $url); + } + /** * @expectedException \InvalidArgumentException */ public function testGenerateWithoutRoutes() - { - $this->generator->generate('test', array(), true); + { + $routes = $this->getRoutes('foo', new Route('/testing/{foo}')); + $this->getGenerator($routes)->generate('test', array(), true); } - + /** * @expectedException \InvalidArgumentException */ public function testGenerateForRouteWithoutManditoryParameter() { - $this->routeCollection->add('test', new Route('/testing/{foo}')); - $this->generator->generate('test', array(), true); + $routes = $this->getRoutes('test', new Route('/testing/{foo}')); + $this->getGenerator($routes)->generate('test', array(), true); } - + /** * @expectedException \InvalidArgumentException */ public function testGenerateForRouteWithInvalidOptionalParameter() { - $route = new Route('/testing/{foo}', array('foo' => '1'), array('foo' => 'd+')); - $this->routeCollection->add('test', $route); - $this->generator->generate('test', array('foo' => 'bar'), true); + $routes = $this->getRoutes('test', new Route('/testing/{foo}', array('foo' => '1'), array('foo' => 'd+'))); + $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), true); } - + /** * @expectedException \InvalidArgumentException */ public function testGenerateForRouteWithInvalidManditoryParameter() { - $route = new Route('/testing/{foo}', array(), array('foo' => 'd+')); - $this->routeCollection->add('test', $route); - $this->generator->generate('test', array('foo' => 'bar'), true); - } + $routes = $this->getRoutes('test', new Route('/testing/{foo}', array(), array('foo' => 'd+'))); + $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), true); + } + + public function testSchemeRequirementDoesNothingIfSameCurrentScheme() + { + $routes = $this->getRoutes('test', new Route('/', array(), array('_scheme' => 'http'))); + $this->assertEquals('/app.php/', $this->getGenerator($routes)->generate('test')); + + $routes = $this->getRoutes('test', new Route('/', array(), array('_scheme' => 'https'))); + $this->assertEquals('/app.php/', $this->getGenerator($routes, array('scheme' => 'https'))->generate('test')); + } + + public function testSchemeRequirementForcesAbsoluteUrl() + { + $routes = $this->getRoutes('test', new Route('/', array(), array('_scheme' => 'https'))); + $this->assertEquals('https://localhost/app.php/', $this->getGenerator($routes)->generate('test')); + + $routes = $this->getRoutes('test', new Route('/', array(), array('_scheme' => 'http'))); + $this->assertEquals('http://localhost/app.php/', $this->getGenerator($routes, array('scheme' => 'https'))->generate('test')); + } + + protected function getGenerator(RouteCollection $routes, array $parameters = array()) + { + $context = new RequestContext('/app.php'); + foreach ($parameters as $key => $value) { + $method = 'set'.$key; + $context->$method($value); + } + $generator = new UrlGenerator($routes, $context); + + return $generator; + } + + protected function getRoutes($name, Route $route) + { + $routes = new RouteCollection(); + $routes->add($name, $route); + + return $routes; + } } diff --git a/tests/Symfony/Tests/Component/Routing/Matcher/Dumper/PhpMatcherDumperTest.php b/tests/Symfony/Tests/Component/Routing/Matcher/Dumper/PhpMatcherDumperTest.php index fea429d4d4..5286a9a851 100644 --- a/tests/Symfony/Tests/Component/Routing/Matcher/Dumper/PhpMatcherDumperTest.php +++ b/tests/Symfony/Tests/Component/Routing/Matcher/Dumper/PhpMatcherDumperTest.php @@ -14,16 +14,10 @@ namespace Symfony\Tests\Component\Routing; use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Routing\RequestContext; class PhpMatcherDumperTest extends \PHPUnit_Framework_TestCase { - static protected $fixturesPath; - - static public function setUpBeforeClass() - { - self::$fixturesPath = realpath(__DIR__.'/../../Fixtures/'); - } - public function testDump() { $collection = new RouteCollection(); @@ -68,8 +62,44 @@ class PhpMatcherDumperTest extends \PHPUnit_Framework_TestCase array(), array('_method' => 'put') )); + // defaults without variable + $collection->add('foofoo', new Route( + '/foofoo', + array('def' => 'test') + )); - $dumper = new PhpMatcherDumper($collection); - $this->assertStringEqualsFile(self::$fixturesPath.'/dumper/url_matcher1.php', $dumper->dump(), '->dump() dumps basic routes to the correct PHP file.'); + $dumper = new PhpMatcherDumper($collection, new RequestContext()); + $this->assertStringEqualsFile(__DIR__.'/../../Fixtures/dumper/url_matcher1.php', $dumper->dump(), '->dump() dumps basic routes to the correct PHP file.'); + + // force HTTPS redirection + $collection->add('secure', new Route( + '/secure', + array(), + array('_scheme' => 'https') + )); + + // force HTTP redirection + $collection->add('nonsecure', new Route( + '/nonsecure', + array(), + array('_scheme' => 'http') + )); + + $this->assertStringEqualsFile(__DIR__.'/../../Fixtures/dumper/url_matcher2.php', $dumper->dump(array('base_class' => 'Symfony\Tests\Component\Routing\Fixtures\RedirectableUrlMatcher')), '->dump() dumps basic routes to the correct PHP file.'); + } + + /** + * @expectedException \LogicException + */ + public function testDumpWhenSchemeIsUsedWithoutAProperDumper() + { + $collection = new RouteCollection(); + $collection->add('secure', new Route( + '/secure', + array(), + array('_scheme' => 'https') + )); + $dumper = new PhpMatcherDumper($collection, new RequestContext()); + $dumper->dump(); } } diff --git a/tests/Symfony/Tests/Component/Routing/Matcher/RedirectableUrlMatcherTest.php b/tests/Symfony/Tests/Component/Routing/Matcher/RedirectableUrlMatcherTest.php new file mode 100644 index 0000000000..20ff970649 --- /dev/null +++ b/tests/Symfony/Tests/Component/Routing/Matcher/RedirectableUrlMatcherTest.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Tests\Component\Routing\Matcher; + +use Symfony\Component\Routing\Route; +use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Routing\RequestContext; + +class RedirectableUrlMatcherTest extends \PHPUnit_Framework_TestCase +{ + public function testNoMethodSoAllowed() + { + $coll = new RouteCollection(); + $coll->add('foo', new Route('/foo/')); + + $matcher = $this->getMockForAbstractClass('Symfony\Component\Routing\Matcher\RedirectableUrlMatcher', array($coll, new RequestContext())); + $matcher->expects($this->once())->method('redirect'); + $matcher->match('/foo'); + } +} diff --git a/tests/Symfony/Tests/Component/Routing/Matcher/UrlMatcherTest.php b/tests/Symfony/Tests/Component/Routing/Matcher/UrlMatcherTest.php index 7efbef6bda..034ecfcc4e 100644 --- a/tests/Symfony/Tests/Component/Routing/Matcher/UrlMatcherTest.php +++ b/tests/Symfony/Tests/Component/Routing/Matcher/UrlMatcherTest.php @@ -16,6 +16,7 @@ use Symfony\Component\Routing\Matcher\Exception\NotFoundException; use Symfony\Component\Routing\Matcher\UrlMatcher; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Routing\RequestContext; class UrlMatcherTest extends \PHPUnit_Framework_TestCase { @@ -24,7 +25,7 @@ class UrlMatcherTest extends \PHPUnit_Framework_TestCase $coll = new RouteCollection(); $coll->add('foo', new Route('/foo')); - $matcher = new UrlMatcher($coll, array('method' => 'get')); + $matcher = new UrlMatcher($coll, new RequestContext()); $matcher->match('/foo'); } @@ -33,7 +34,7 @@ class UrlMatcherTest extends \PHPUnit_Framework_TestCase $coll = new RouteCollection(); $coll->add('foo', new Route('/foo', array(), array('_method' => 'post'))); - $matcher = new UrlMatcher($coll, array('method' => 'get')); + $matcher = new UrlMatcher($coll, new RequestContext()); try { $matcher->match('/foo'); @@ -49,7 +50,7 @@ class UrlMatcherTest extends \PHPUnit_Framework_TestCase $coll->add('foo1', new Route('/foo', array(), array('_method' => 'post'))); $coll->add('foo2', new Route('/foo', array(), array('_method' => 'put|delete'))); - $matcher = new UrlMatcher($coll, array('method' => 'get')); + $matcher = new UrlMatcher($coll, new RequestContext()); try { $matcher->match('/foo'); @@ -64,7 +65,7 @@ class UrlMatcherTest extends \PHPUnit_Framework_TestCase // test the patterns are matched are parameters are returned $collection = new RouteCollection(); $collection->add('foo', new Route('/foo/{bar}')); - $matcher = new UrlMatcher($collection, array(), array()); + $matcher = new UrlMatcher($collection, new RequestContext(), array()); try { $matcher->match('/no-match'); $this->fail(); @@ -74,26 +75,26 @@ class UrlMatcherTest extends \PHPUnit_Framework_TestCase // test that defaults are merged $collection = new RouteCollection(); $collection->add('foo', new Route('/foo/{bar}', array('def' => 'test'))); - $matcher = new UrlMatcher($collection, array(), array()); + $matcher = new UrlMatcher($collection, new RequestContext(), array()); $this->assertEquals(array('_route' => 'foo', 'bar' => 'baz', 'def' => 'test'), $matcher->match('/foo/baz')); // test that route "method" is ignored if no method is given in the context $collection = new RouteCollection(); $collection->add('foo', new Route('/foo', array(), array('_method' => 'GET|head'))); - $matcher = new UrlMatcher($collection, array(), array()); + $matcher = new UrlMatcher($collection, new RequestContext(), array()); $this->assertInternalType('array', $matcher->match('/foo')); // route does not match with POST method context - $matcher = new UrlMatcher($collection, array('method' => 'POST'), array()); + $matcher = new UrlMatcher($collection, new RequestContext('', 'post'), array()); try { $matcher->match('/foo'); $this->fail(); } catch (MethodNotAllowedException $e) {} // route does match with GET or HEAD method context - $matcher = new UrlMatcher($collection, array('method' => 'GET'), array()); + $matcher = new UrlMatcher($collection, new RequestContext(), array()); $this->assertInternalType('array', $matcher->match('/foo')); - $matcher = new UrlMatcher($collection, array('method' => 'HEAD'), array()); + $matcher = new UrlMatcher($collection, new RequestContext('', 'head'), array()); $this->assertInternalType('array', $matcher->match('/foo')); } } diff --git a/tests/Symfony/Tests/Component/Security/Acl/Dbal/MutableAclProviderTest.php b/tests/Symfony/Tests/Component/Security/Acl/Dbal/MutableAclProviderTest.php index 2aa7d961a7..a0f2f11f82 100644 --- a/tests/Symfony/Tests/Component/Security/Acl/Dbal/MutableAclProviderTest.php +++ b/tests/Symfony/Tests/Component/Security/Acl/Dbal/MutableAclProviderTest.php @@ -301,11 +301,13 @@ class MutableAclProviderTest extends \PHPUnit_Framework_TestCase $acl->insertObjectAce($sid, 1); $acl->insertClassAce($sid, 5, 0, false); $acl->insertObjectAce($sid, 2, 1, true); + $acl->insertClassFieldAce('field', $sid, 2, 0, true); $provider->updateAcl($acl); $acl->updateObjectAce(0, 3); $acl->deleteObjectAce(1); $acl->updateObjectAuditing(0, true, false); + $acl->updateClassFieldAce(0, 'field', 15); $provider->updateAcl($acl); $reloadProvider = $this->getProvider(); @@ -461,4 +463,4 @@ class MutableAclProviderTest extends \PHPUnit_Framework_TestCase { return new MutableAclProvider($this->con, $this->getStrategy(), $this->getOptions(), $cache); } -} \ No newline at end of file +} diff --git a/tests/Symfony/Tests/Component/Security/Acl/Domain/AuditLoggerTest.php b/tests/Symfony/Tests/Component/Security/Acl/Domain/AuditLoggerTest.php index 4974559986..0061c5993f 100644 --- a/tests/Symfony/Tests/Component/Security/Acl/Domain/AuditLoggerTest.php +++ b/tests/Symfony/Tests/Component/Security/Acl/Domain/AuditLoggerTest.php @@ -20,14 +20,14 @@ class AuditLoggerTest extends \PHPUnit_Framework_TestCase { $logger = $this->getLogger(); $ace = $this->getEntry(); - + if (true === $granting) { $ace ->expects($this->once()) ->method('isAuditSuccess') ->will($this->returnValue($audit)) ; - + $ace ->expects($this->never()) ->method('isAuditFailure') @@ -37,7 +37,7 @@ class AuditLoggerTest extends \PHPUnit_Framework_TestCase ->expects($this->never()) ->method('isAuditSuccess') ; - + $ace ->expects($this->once()) ->method('isAuditFailure') @@ -57,10 +57,10 @@ class AuditLoggerTest extends \PHPUnit_Framework_TestCase ->method('doLog') ; } - + $logger->logIfNeeded($granting, $ace); } - + public function getTestLogData() { return array( @@ -70,12 +70,12 @@ class AuditLoggerTest extends \PHPUnit_Framework_TestCase array(false, true), ); } - + protected function getEntry() { return $this->getMock('Symfony\Component\Security\Acl\Model\AuditableEntryInterface'); } - + protected function getLogger() { return $this->getMockForAbstractClass('Symfony\Component\Security\Acl\Domain\AuditLogger'); diff --git a/tests/Symfony/Tests/Component/Security/Acl/Domain/EntryTest.php b/tests/Symfony/Tests/Component/Security/Acl/Domain/EntryTest.php index a484694915..0916462296 100644 --- a/tests/Symfony/Tests/Component/Security/Acl/Domain/EntryTest.php +++ b/tests/Symfony/Tests/Component/Security/Acl/Domain/EntryTest.php @@ -18,7 +18,7 @@ class EntryTest extends \PHPUnit_Framework_TestCase public function testConstructor() { $ace = $this->getAce($acl = $this->getAcl(), $sid = $this->getSid()); - + $this->assertEquals(123, $ace->getId()); $this->assertSame($acl, $ace->getAcl()); $this->assertSame($sid, $ace->getSecurityIdentity()); @@ -28,54 +28,54 @@ class EntryTest extends \PHPUnit_Framework_TestCase $this->assertTrue($ace->isAuditSuccess()); $this->assertFalse($ace->isAuditFailure()); } - + public function testSetAuditSuccess() { $ace = $this->getAce(); - + $this->assertTrue($ace->isAuditSuccess()); $ace->setAuditSuccess(false); $this->assertFalse($ace->isAuditSuccess()); $ace->setAuditsuccess(true); $this->assertTrue($ace->isAuditSuccess()); } - + public function testSetAuditFailure() { $ace = $this->getAce(); - + $this->assertFalse($ace->isAuditFailure()); $ace->setAuditFailure(true); $this->assertTrue($ace->isAuditFailure()); $ace->setAuditFailure(false); $this->assertFalse($ace->isAuditFailure()); } - + public function testSetMask() { $ace = $this->getAce(); - + $this->assertEquals(123456, $ace->getMask()); $ace->setMask(4321); $this->assertEquals(4321, $ace->getMask()); } - + public function testSetStrategy() { $ace = $this->getAce(); - + $this->assertEquals('foostrat', $ace->getStrategy()); $ace->setStrategy('foo'); $this->assertEquals('foo', $ace->getStrategy()); } - + public function testSerializeUnserialize() { $ace = $this->getAce(); - + $serialized = serialize($ace); $uAce = unserialize($serialized); - + $this->assertNull($uAce->getAcl()); $this->assertInstanceOf('Symfony\Component\Security\Acl\Model\SecurityIdentityInterface', $uAce->getSecurityIdentity()); $this->assertEquals($ace->getId(), $uAce->getId()); @@ -85,7 +85,7 @@ class EntryTest extends \PHPUnit_Framework_TestCase $this->assertEquals($ace->isAuditSuccess(), $uAce->isAuditSuccess()); $this->assertEquals($ace->isAuditFailure(), $uAce->isAuditFailure()); } - + protected function getAce($acl = null, $sid = null) { if (null === $acl) { @@ -94,24 +94,24 @@ class EntryTest extends \PHPUnit_Framework_TestCase if (null === $sid) { $sid = $this->getSid(); } - + return new Entry( - 123, - $acl, - $sid, - 'foostrat', - 123456, - true, - false, + 123, + $acl, + $sid, + 'foostrat', + 123456, + true, + false, true - ); + ); } - + protected function getAcl() { return $this->getMock('Symfony\Component\Security\Acl\Model\AclInterface'); } - + protected function getSid() { return $this->getMock('Symfony\Component\Security\Acl\Model\SecurityIdentityInterface'); diff --git a/tests/Symfony/Tests/Component/Security/Acl/Domain/FieldEntryTest.php b/tests/Symfony/Tests/Component/Security/Acl/Domain/FieldEntryTest.php index 4b2e31ab2c..c8dc733826 100644 --- a/tests/Symfony/Tests/Component/Security/Acl/Domain/FieldEntryTest.php +++ b/tests/Symfony/Tests/Component/Security/Acl/Domain/FieldEntryTest.php @@ -18,17 +18,17 @@ class FieldEntryTest extends \PHPUnit_Framework_TestCase public function testConstructor() { $ace = $this->getAce(); - + $this->assertEquals('foo', $ace->getField()); } - + public function testSerializeUnserialize() { $ace = $this->getAce(); - + $serialized = serialize($ace); $uAce = unserialize($serialized); - + $this->assertNull($uAce->getAcl()); $this->assertInstanceOf('Symfony\Component\Security\Acl\Model\SecurityIdentityInterface', $uAce->getSecurityIdentity()); $this->assertEquals($ace->getId(), $uAce->getId()); @@ -39,7 +39,7 @@ class FieldEntryTest extends \PHPUnit_Framework_TestCase $this->assertEquals($ace->isAuditSuccess(), $uAce->isAuditSuccess()); $this->assertEquals($ace->isAuditFailure(), $uAce->isAuditFailure()); } - + protected function getAce($acl = null, $sid = null) { if (null === $acl) { @@ -48,25 +48,25 @@ class FieldEntryTest extends \PHPUnit_Framework_TestCase if (null === $sid) { $sid = $this->getSid(); } - + return new FieldEntry( - 123, - $acl, + 123, + $acl, 'foo', - $sid, - 'foostrat', - 123456, - true, - false, + $sid, + 'foostrat', + 123456, + true, + false, true - ); + ); } - + protected function getAcl() { return $this->getMock('Symfony\Component\Security\Acl\Model\AclInterface'); } - + protected function getSid() { return $this->getMock('Symfony\Component\Security\Acl\Model\SecurityIdentityInterface'); diff --git a/tests/Symfony/Tests/Component/Security/Acl/Permission/MaskBuilderTest.php b/tests/Symfony/Tests/Component/Security/Acl/Permission/MaskBuilderTest.php index 3ab64b41cc..2a5b5ed92d 100644 --- a/tests/Symfony/Tests/Component/Security/Acl/Permission/MaskBuilderTest.php +++ b/tests/Symfony/Tests/Component/Security/Acl/Permission/MaskBuilderTest.php @@ -23,7 +23,7 @@ class MaskBuilderTest extends \PHPUnit_Framework_TestCase { new MaskBuilder($invalidMask); } - + public function getInvalidConstructorData() { return array( @@ -33,32 +33,32 @@ class MaskBuilderTest extends \PHPUnit_Framework_TestCase array(new \stdClass()), ); } - + public function testConstructorWithoutArguments() { $builder = new MaskBuilder(); - + $this->assertEquals(0, $builder->get()); } - + public function testConstructor() { $builder = new MaskBuilder(123456); - + $this->assertEquals(123456, $builder->get()); } - + public function testAddAndRemove() { $builder = new MaskBuilder(); - + $builder ->add('view') ->add('eDiT') ->add('ownEr') ; $mask = $builder->get(); - + $this->assertEquals(MaskBuilder::MASK_VIEW, $mask & MaskBuilder::MASK_VIEW); $this->assertEquals(MaskBuilder::MASK_EDIT, $mask & MaskBuilder::MASK_EDIT); $this->assertEquals(MaskBuilder::MASK_OWNER, $mask & MaskBuilder::MASK_OWNER); @@ -66,37 +66,37 @@ class MaskBuilderTest extends \PHPUnit_Framework_TestCase $this->assertEquals(0, $mask & MaskBuilder::MASK_CREATE); $this->assertEquals(0, $mask & MaskBuilder::MASK_DELETE); $this->assertEquals(0, $mask & MaskBuilder::MASK_UNDELETE); - + $builder->remove('edit')->remove('OWner'); $mask = $builder->get(); $this->assertEquals(0, $mask & MaskBuilder::MASK_EDIT); $this->assertEquals(0, $mask & MaskBuilder::MASK_OWNER); $this->assertEquals(MaskBuilder::MASK_VIEW, $mask & MaskBuilder::MASK_VIEW); } - + public function testGetPattern() { $builder = new MaskBuilder; $this->assertEquals(MaskBuilder::ALL_OFF, $builder->getPattern()); - + $builder->add('view'); $this->assertEquals(str_repeat('.', 31).'V', $builder->getPattern()); - + $builder->add('owner'); $this->assertEquals(str_repeat('.', 24).'N......V', $builder->getPattern()); - + $builder->add(1 << 10); $this->assertEquals(str_repeat('.', 21).MaskBuilder::ON.'..N......V', $builder->getPattern()); } - + public function testReset() { $builder = new MaskBuilder(); $this->assertEquals(0, $builder->get()); - + $builder->add('view'); $this->assertTrue($builder->get() > 0); - + $builder->reset(); $this->assertEquals(0, $builder->get()); } diff --git a/tests/Symfony/Tests/Component/Security/Acl/Voter/AclVoterTest.php b/tests/Symfony/Tests/Component/Security/Acl/Voter/AclVoterTest.php index 94f35545e5..885304fb35 100644 --- a/tests/Symfony/Tests/Component/Security/Acl/Voter/AclVoterTest.php +++ b/tests/Symfony/Tests/Component/Security/Acl/Voter/AclVoterTest.php @@ -360,13 +360,13 @@ class AclVoterTest extends \PHPUnit_Framework_TestCase $this->assertSame(VoterInterface::ACCESS_DENIED, $voter->vote($this->getToken(), new FieldVote(new \stdClass(), 'foo'), array('VIEW'))); } - + public function testWhenReceivingAnObjectIdentityInterfaceWeDontRetrieveANewObjectIdentity() { list($voter, $provider, $permissionMap, $oidStrategy, $sidStrategy) = $this->getVoter(); - + $oid = new ObjectIdentity('someID','someType'); - + $permissionMap ->expects($this->once()) ->method('contains') diff --git a/tests/Symfony/Tests/Component/Security/Http/RememberMe/PersistentTokenBasedRememberMeServicesTest.php b/tests/Symfony/Tests/Component/Security/Http/RememberMe/PersistentTokenBasedRememberMeServicesTest.php index 687a5352f5..1904190d8d 100644 --- a/tests/Symfony/Tests/Component/Security/Http/RememberMe/PersistentTokenBasedRememberMeServicesTest.php +++ b/tests/Symfony/Tests/Component/Security/Http/RememberMe/PersistentTokenBasedRememberMeServicesTest.php @@ -280,7 +280,7 @@ class PersistentTokenBasedRememberMeServicesTest extends \PHPUnit_Framework_Test $this->assertFalse($cookie->isCleared()); $this->assertTrue($cookie->isSecure()); $this->assertTrue($cookie->isHttpOnly()); - $this->assertTrue($cookie->getExpire() > time() + 3590 && $cookie->getExpire() < time() + 3610); + $this->assertTrue($cookie->getExpiresTime() > time() + 3590 && $cookie->getExpiresTime() < time() + 3610); $this->assertEquals('myfoodomain.foo', $cookie->getDomain()); $this->assertEquals('/foo/path', $cookie->getPath()); } diff --git a/tests/Symfony/Tests/Component/Security/Http/RememberMe/TokenBasedRememberMeServicesTest.php b/tests/Symfony/Tests/Component/Security/Http/RememberMe/TokenBasedRememberMeServicesTest.php index f9e0044ae3..b0eb92785d 100644 --- a/tests/Symfony/Tests/Component/Security/Http/RememberMe/TokenBasedRememberMeServicesTest.php +++ b/tests/Symfony/Tests/Component/Security/Http/RememberMe/TokenBasedRememberMeServicesTest.php @@ -214,7 +214,7 @@ class TokenBasedRememberMeServicesTest extends \PHPUnit_Framework_TestCase $this->assertFalse($cookie->isCleared()); $this->assertTrue($cookie->isSecure()); $this->assertTrue($cookie->isHttpOnly()); - $this->assertTrue($cookie->getExpire() > time() + 3590 && $cookie->getExpire() < time() + 3610); + $this->assertTrue($cookie->getExpiresTime() > time() + 3590 && $cookie->getExpiresTime() < time() + 3610); $this->assertEquals('myfoodomain.foo', $cookie->getDomain()); $this->assertEquals('/foo/path', $cookie->getPath()); } diff --git a/tests/Symfony/Tests/Component/Serializer/Encoder/XmlEncoderTest.php b/tests/Symfony/Tests/Component/Serializer/Encoder/XmlEncoderTest.php index 844a2b0c99..80df994b61 100644 --- a/tests/Symfony/Tests/Component/Serializer/Encoder/XmlEncoderTest.php +++ b/tests/Symfony/Tests/Component/Serializer/Encoder/XmlEncoderTest.php @@ -112,6 +112,18 @@ class XmlEncoderTest extends \PHPUnit_Framework_TestCase $this->assertEquals($expected, $this->encoder->encode($array, 'xml')); } + public function testEncodeScalarWithAttribute() + { + $array = array( + 'person' => array('@gender' => 'M', '#' => 'Peter'), + ); + + $expected = ''."\n". + ''."\n"; + + $this->assertEquals($expected, $this->encoder->encode($array, 'xml')); + } + public function testDecodeScalar() { $source = ''."\n". @@ -136,6 +148,38 @@ class XmlEncoderTest extends \PHPUnit_Framework_TestCase $this->assertEquals(get_object_vars($obj), $this->encoder->decode($source, 'xml')); } + public function testDecodeScalarWithAttribute() + { + $source = ''."\n". + 'Peter'."\n"; + + $expected = array( + 'person' => array('@gender' => 'M', '#' => 'Peter'), + ); + + $this->assertEquals($expected, $this->encoder->decode($source, 'xml')); + } + + public function testDecodeArray() + { + $source = ''."\n". + ''. + ''. + 'BenjaminAlexandre'. + 'DamienClay'. + ''. + ''."\n"; + + $expected = array( + 'people' => array('person' => array( + array('firstname' => 'Benjamin', 'lastname' => 'Alexandre'), + array('firstname' => 'Damien', 'lastname' => 'Clay') + )) + ); + + $this->assertEquals($expected, $this->encoder->decode($source, 'xml')); + } + protected function getXmlSource() { return ''."\n". @@ -153,7 +197,7 @@ class XmlEncoderTest extends \PHPUnit_Framework_TestCase $obj = new Dummy; $obj->foo = 'foo'; $obj->bar = array('a', 'b'); - $obj->baz = array('key' => 'val', 'key2' => 'val', 'A B' => 'bar', "Barry" => array('FooBar' => array("@id"=>1,"Baz"=>"Ed"))); + $obj->baz = array('key' => 'val', 'key2' => 'val', 'A B' => 'bar', "Barry" => array('FooBar' => array("Baz"=>"Ed", "@id"=>1))); $obj->qux = "1"; return $obj; } diff --git a/tests/Symfony/Tests/Component/Templating/TemplateNameParserTest.php b/tests/Symfony/Tests/Component/Templating/TemplateNameParserTest.php new file mode 100644 index 0000000000..9711f14ce5 --- /dev/null +++ b/tests/Symfony/Tests/Component/Templating/TemplateNameParserTest.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Tests\Component\Templating; + +use Symfony\Component\Templating\TemplateNameParser; +use Symfony\Component\Templating\TemplateReference; + +class TemplateNameParserTest extends \PHPUnit_Framework_TestCase +{ + protected $parser; + + protected function setUp() + { + $this->parser = new TemplateNameParser(); + } + + protected function tearDown() + { + unset($this->parser); + } + + /** + * @dataProvider getLogicalNameToTemplateProvider + */ + public function testParse($name, $ref) + { + $template = $this->parser->parse($name); + + $this->assertEquals($template->getSignature(), $ref->getSignature()); + $this->assertEquals($template->getLogicalName(), $name); + } + + public function getLogicalNameToTemplateProvider() + { + return array( + array('/path/to/section/name.engine', new TemplateReference('/path/to/section/name.engine', 'engine')), + array('name.engine', new TemplateReference('name.engine', 'engine')), + array('name', new TemplateReference('name')), + ); + } +} diff --git a/tests/Symfony/Tests/Component/Validator/Mapping/Cache/ApcCacheTest.php b/tests/Symfony/Tests/Component/Validator/Mapping/Cache/ApcCacheTest.php new file mode 100644 index 0000000000..063a10db90 --- /dev/null +++ b/tests/Symfony/Tests/Component/Validator/Mapping/Cache/ApcCacheTest.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Tests\Component\Validator\Mapping\Cache; + +use Symfony\Component\Validator\Mapping\Cache\ApcCache; + +class ApcCacheTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!extension_loaded('apc') || !ini_get('apc.enable_cli')) { + $this->markTestSkipped('APC is not loaded.'); + } + } + + public function testWrite() + { + $meta = $this->getMockBuilder('Symfony\\Component\\Validator\\Mapping\\ClassMetadata') + ->disableOriginalConstructor() + ->setMethods(array('getClassName')) + ->getMock(); + + $meta->expects($this->once()) + ->method('getClassName') + ->will($this->returnValue('bar')); + + $cache = new ApcCache('foo'); + $cache->write($meta); + + $this->assertInstanceOf('Symfony\\Component\\Validator\\Mapping\\ClassMetadata', apc_fetch('foobar'), '->write() stores metadata in APC'); + } + + public function testHas() + { + $meta = $this->getMockBuilder('Symfony\\Component\\Validator\\Mapping\\ClassMetadata') + ->disableOriginalConstructor() + ->setMethods(array('getClassName')) + ->getMock(); + + $meta->expects($this->once()) + ->method('getClassName') + ->will($this->returnValue('bar')); + + apc_delete('foobar'); + + $cache = new ApcCache('foo'); + $this->assertFalse($cache->has('bar'), '->has() returns false when there is no entry'); + + $cache->write($meta); + $this->assertTrue($cache->has('bar'), '->has() returns true when the is an entry'); + } + + public function testRead() + { + $meta = $this->getMockBuilder('Symfony\\Component\\Validator\\Mapping\\ClassMetadata') + ->disableOriginalConstructor() + ->setMethods(array('getClassName')) + ->getMock(); + + $meta->expects($this->once()) + ->method('getClassName') + ->will($this->returnValue('bar')); + + $cache = new ApcCache('foo'); + $cache->write($meta); + + $this->assertInstanceOf('Symfony\\Component\\Validator\\Mapping\\ClassMetadata', $cache->read('bar'), '->read() returns metadata'); + } +} diff --git a/vendors.sh b/vendors.sh index 7080580524..3f2723ce44 100755 --- a/vendors.sh +++ b/vendors.sh @@ -38,31 +38,25 @@ install_git() install_git assetic git://github.com/kriswallsmith/assetic.git # Doctrine ORM -install_git doctrine git://github.com/doctrine/doctrine2.git +install_git doctrine git://github.com/doctrine/doctrine2.git 2.0.4 # Doctrine Data Fixtures Extension install_git doctrine-data-fixtures git://github.com/doctrine/data-fixtures.git # Doctrine DBAL -install_git doctrine-dbal git://github.com/doctrine/dbal.git +install_git doctrine-dbal git://github.com/doctrine/dbal.git 2.0.4 # Doctrine Common -install_git doctrine-common git://github.com/doctrine/common.git +install_git doctrine-common git://github.com/doctrine/common.git 2.0.2 # Doctrine migrations install_git doctrine-migrations git://github.com/doctrine/migrations.git -# Doctrine MongoDB -install_git doctrine-mongodb git://github.com/doctrine/mongodb.git - -# Doctrine MongoDB -install_git doctrine-mongodb-odm git://github.com/doctrine/mongodb-odm.git +# Monolog +install_git monolog git://github.com/Seldaek/monolog.git # Swiftmailer install_git swiftmailer git://github.com/swiftmailer/swiftmailer.git origin/4.1 # Twig install_git twig git://github.com/fabpot/Twig.git - -# Zend Framework -install_git zend git://github.com/zendframework/zf2.git