Merge branch 'master' into fix-stub-locale-method-signature

This commit is contained in:
Eriksen Costa 2011-04-22 00:07:29 -03:00
commit 9cf7fba913
507 changed files with 6074 additions and 6724 deletions

View File

@ -5,6 +5,71 @@
このドキュメントでは、フレームワークの "パブリックな" APIを使っている場合に必要な変更点についてのみ説明しています。
フレームワークのコアコードを "ハック" している場合は、変更履歴を注意深く追跡する必要があるでしょう。
PR11 to PR12
------------
* HttpFoundation\Cookie::getExpire() は getExpiresTime() に名前が変更されました。
* XMLのコンフィギュレーションの記述方法が変更されました。属性が1つしかないタグは、すべてタグのコンテンツとして記述するように変更されました。
変更前:
<bundle name="MyBundle" />
<app:engine id="twig" />
<twig:extension id="twig.extension.debug" />
変更後:
<bundle>MyBundle</bundle>
<app:engine>twig</app:engine>
<twig:extension>twig.extension.debug</twig:extension>
* 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

115
UPDATE.md
View File

@ -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:
<bundle name="MyBundle" />
<app:engine id="twig" />
<twig:extension id="twig.extension.debug" />
After:
<bundle>MyBundle</bundle>
<app:engine>twig</app:engine>
<twig:extension>twig.extension.debug</twig:extension>
* 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

View File

@ -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',

View File

@ -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.
*

View File

@ -12,13 +12,13 @@
namespace Symfony\Bridge\Twig\Node;
/**
*
*
*
* @author Fabien Potencier <fabien@symfony.com>
*/
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';

View File

@ -14,7 +14,7 @@ namespace Symfony\Bridge\Twig\TokenParser;
use Symfony\Bridge\Twig\Node\TransNode;
/**
*
*
*
* @author Fabien Potencier <fabien@symfony.com>
*/
@ -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);

View File

@ -14,7 +14,7 @@ namespace Symfony\Bridge\Twig\TokenParser;
use Symfony\Bridge\Twig\Node\TransNode;
/**
*
*
*
* @author Fabien Potencier <fabien@symfony.com>
*/
@ -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);

View File

@ -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()

View File

@ -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()

View File

@ -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];
}
}
}

View File

@ -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) {

View File

@ -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) {

View File

@ -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');
}
}
}

View File

@ -39,6 +39,6 @@ class FilterManagerPass implements CompilerPassInterface
$container
->getDefinition('assetic.filter_manager')
->setArgument(1, $mapping);
->replaceArgument(1, $mapping);
}
}

View File

@ -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);
}
}
}

View File

@ -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 <stof@notk.org>
* @author Kris Wallsmith <kris@symfony.com>
*/
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;
}
}

View File

@ -0,0 +1,33 @@
<?php
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Symfony\Bundle\AsseticBundle\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 <kris@symfony.com>
*/
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;
}
}

View File

@ -12,7 +12,7 @@
<services>
<service id="assetic.asset_writer_cache_warmer" class="%assetic.asset_writer_cache_warmer.class%" public="false">
<tag name="kernel.cache_warmer" />
<argument type="service" id="assetic.asset_manager" />
<argument type="service" id="service_container" />
<argument type="service" id="assetic.asset_writer" />
</service>
<service id="assetic.asset_writer" class="%assetic.asset_writer.class%" public="false">

View File

@ -42,7 +42,7 @@
<service id="assetic.asset_manager_cache_warmer" class="%assetic.asset_manager_cache_warmer.class%" public="false">
<tag name="kernel.cache_warmer" priority="10" />
<argument type="service" id="assetic.asset_manager" />
<argument type="service" id="service_container" />
</service>
</services>
</container>

View File

@ -8,6 +8,7 @@
<parameter key="assetic.controller.class">Symfony\Bundle\AsseticBundle\Controller\AsseticController</parameter>
<parameter key="assetic.routing_loader.class">Symfony\Bundle\AsseticBundle\Routing\AsseticLoader</parameter>
<parameter key="assetic.cache.class">Assetic\Cache\FilesystemCache</parameter>
<parameter key="assetic.use_controller_worker.class">Symfony\Bundle\AsseticBundle\Factory\Worker\UseControllerWorker</parameter>
</parameters>
<services>
@ -23,5 +24,8 @@
<service id="assetic.cache" class="%assetic.cache.class%" public="false">
<argument>%assetic.cache_dir%/assets</argument>
</service>
<service id="assetic.use_controller_worker" class="%assetic.use_controller_worker.class%" public="false">
<tag name="assetic.factory_worker" />
</service>
</services>
</container>

View File

@ -5,8 +5,7 @@
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="assetic.twig_extension.dynamic.class">Symfony\Bundle\AsseticBundle\Twig\DynamicExtension</parameter>
<parameter key="assetic.twig_extension.static.class">Symfony\Bundle\AsseticBundle\Twig\StaticExtension</parameter>
<parameter key="assetic.twig_extension.class">Symfony\Bundle\AsseticBundle\Twig\AsseticExtension</parameter>
<parameter key="assetic.twig_formula_loader.class">Assetic\Extension\Twig\TwigFormulaLoader</parameter>
</parameters>
@ -16,6 +15,7 @@
<tag name="assetic.templating.twig" />
<argument type="service" id="assetic.asset_factory" />
<argument>%assetic.debug%</argument>
<argument>%assetic.use_controller%</argument>
</service>
<service id="assetic.twig_formula_loader" class="%assetic.cached_formula_loader.class%" public="false">
<tag name="assetic.formula_loader" alias="twig" />

View File

@ -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;

View File

@ -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']);
}
}

View File

@ -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');
}
}

View File

@ -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');
}
}

View File

@ -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);
}
/**

View File

@ -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'),
);
}
}

View File

@ -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),
);
}

View File

@ -1,7 +1,7 @@
<?php $view->extend('::base.html.php') ?>
<?php $view['slots']->start('stylesheets') ?>
<?php foreach($view['assetic']->stylesheets('stylesheet1.css, stylesheet2.css, @Test/Resources/css/bundle.css') as $url): ?>
<?php foreach($view['assetic']->stylesheets('stylesheet1.css, stylesheet2.css, @TestBundle/Resources/css/bundle.css') as $url): ?>
<link href="<?php echo $view->escape($url) ?>" type="text/css" rel="stylesheet" />
<?php endforeach; ?>
<?php $view['slots']->stop() ?>

View File

@ -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' %}
<link href="{{ asset_url }}" type="text/css" rel="stylesheet" />
{% endstylesheets %}
{% endblock %}

View File

@ -19,4 +19,4 @@ twig:
assetic:
use_controller: true
read_from: "%kernel.root_dir%/web"
bundles: [Test]
bundles: [TestBundle]

View File

@ -0,0 +1,49 @@
<?php
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Symfony\Bundle\AsseticBundle\Twig;
use Assetic\Extension\Twig\AsseticExtension as BaseAsseticExtension;
use Assetic\Factory\AssetFactory;
/**
* Assetic extension.
*
* @author Kris Wallsmith <kris@symfony.com>
*/
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;
}
}

View File

@ -0,0 +1,57 @@
<?php
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Symfony\Bundle\AsseticBundle\Twig;
use Assetic\Asset\AssetInterface;
use Assetic\Extension\Twig\AsseticNode as BaseAsseticNode;
/**
* Assetic node.
*
* @author Kris Wallsmith <kris@symfony.com>
*/
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()
);
}
}

View File

@ -0,0 +1,28 @@
<?php
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Symfony\Bundle\AsseticBundle\Twig;
use Assetic\Asset\AssetInterface;
use Assetic\Extension\Twig\AsseticTokenParser as BaseAsseticTokenParser;
/**
* Assetic token parser.
*
* @author Kris Wallsmith <kris@symfony.com>
*/
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);
}
}

View File

@ -1,32 +0,0 @@
<?php
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Symfony\Bundle\AsseticBundle\Twig;
use Assetic\Extension\Twig\AsseticExtension;
use Assetic\Factory\AssetFactory;
/**
* The dynamic extension is used when use_controllers is enabled.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
*/
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')),
);
}
}

View File

@ -1,36 +0,0 @@
<?php
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Symfony\Bundle\AsseticBundle\Twig;
use Assetic\Extension\Twig\AsseticNode;
/**
* The "dynamic" node uses a controller to render assets.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
*/
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()
);
}
}

View File

@ -1,27 +0,0 @@
<?php
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Symfony\Bundle\AsseticBundle\Twig;
use Assetic\Extension\Twig\AsseticTokenParser;
/**
* Parses an Assetic tag.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
*/
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);
}
}

View File

@ -1,32 +0,0 @@
<?php
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Symfony\Bundle\AsseticBundle\Twig;
use Assetic\Extension\Twig\AsseticExtension;
use Assetic\Factory\AssetFactory;
/**
* The static extension is used when use_controllers is disabled.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
*/
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')),
);
}
}

View File

@ -1,37 +0,0 @@
<?php
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Symfony\Bundle\AsseticBundle\Twig;
use Assetic\Extension\Twig\AsseticNode;
/**
* The "static" node references a file in the web directory.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
*/
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()
);
}
}

View File

@ -1,27 +0,0 @@
<?php
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Symfony\Bundle\AsseticBundle\Twig;
use Assetic\Extension\Twig\AsseticTokenParser;
/**
* Parses an Assetic tag.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
*/
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);
}
}

View File

@ -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'];

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -51,7 +51,7 @@ EOT
if ($metadatas = $this->getBundleMetadatas($foundBundle)) {
$output->writeln(sprintf('Generating entity repositories for "<info>%s</info>"', $foundBundle->getName()));
$generator = new EntityRepositoryGenerator();
foreach ($metadatas as $metadata) {
if ($filterEntity && $filterEntity !== $metadata->reflClass->getShortname()) {
continue;

View File

@ -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';

View File

@ -69,7 +69,7 @@ EOT
$output->write(sprintf("Found <info>%d</info> entities mapped in entity manager <info>%s</info>:\n",
count($entityClassNames), $entityManagerName), true);
foreach ($entityClassNames as $entityClassName) {
try {
$cm = $entityManager->getClassMetadata($entityClassName);

View File

@ -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(<<<EOT
The <info>doctrine:data:load</info> command loads data fixtures from your bundles:

View File

@ -36,15 +36,15 @@ class RunDqlDoctrineCommand extends RunDqlCommand
->setHelp(<<<EOT
The <info>doctrine:query:dql</info> command executes the given DQL query and outputs the results:
<info>./app/console doctrine:query:dql "SELECT u FROM User:User u"</info>
<info>./app/console doctrine:query:dql "SELECT u FROM UserBundle:User u"</info>
You can also optional specify some additional options like what type of hydration to use when executing the query:
<info>./app/console doctrine:query:dql "SELECT u FROM User:User u" --hydrate=array</info>
<info>./app/console doctrine:query:dql "SELECT u FROM UserBundle:User u" --hydrate=array</info>
Additionally you can specify the first result and maximum amount of results to show:
<info>./app/console doctrine:query:dql "SELECT u FROM User:User u" --first-result=0 --max-result=30</info>
<info>./app/console doctrine:query:dql "SELECT u FROM UserBundle:User u" --first-result=0 --max-result=30</info>
EOT
);
}

View File

@ -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 <stof@notk.org>
*/
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()

View File

@ -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));

View File

@ -20,11 +20,12 @@
<service id="doctrine.dbal.logger.debug" class="%doctrine.dbal.logger.debug_class%" public="false" />
<service id="doctrine.dbal.logger" class="%doctrine.dbal.logger_class%" public="false">
<tag name="monolog.logger" channel="doctrine" />
<argument type="service" id="logger" on-invalid="null" />
</service>
<service id="data_collector.doctrine" class="%doctrine.data_collector.class%" public="false">
<tag name="data_collector" template="Doctrine:Collector:db" id="db" />
<tag name="data_collector" template="DoctrineBundle:Collector:db" id="db" />
<argument type="service" id="doctrine.dbal.logger" />
</service>

View File

@ -43,8 +43,11 @@
</xsd:complexType>
<xsd:complexType name="type">
<xsd:attribute name="name" type="xsd:string" use="required" />
<xsd:attribute name="class" type="xsd:string" use="required" />
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="connection">
@ -93,6 +96,7 @@
<xsd:element name="mapping" type="mapping" />
<xsd:element name="metadata-cache-driver" type="metadata_cache_driver" minOccurs="0" maxOccurs="1" />
<xsd:element name="dql" type="dql" minOccurs="0" maxOccurs="1" />
<xsd:element name="hydrator" type="type" minOccurs="0" maxOccurs="unbounded" />
</xsd:choice>
<xsd:attribute name="connection" type="xsd:string" />
@ -111,7 +115,10 @@
</xsd:complexType>
<xsd:complexType name="dql_function">
<xsd:attribute name="name" type="xsd:string" use="required" />
<xsd:attribute name="class" type="xsd:string" use="required" />
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
</xsd:schema>

View File

@ -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 %}
<span title="{{ '%0.2f'|format(collector.time * 1000) }} ms">{{ collector.querycount }}</span>
{% 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 %}

View File

@ -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(

View File

@ -8,7 +8,7 @@
<config>
<dbal default-connection="default">
<type name="test" class="Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestType" />
<type name="test">Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestType</type>
<connection name="default" />
</dbal>
</config>

View File

@ -10,11 +10,11 @@
<dbal />
<orm default-entity-manager="default">
<entity-manager name="default">
<mapping name="Yaml" />
<mapping name="YamlBundle" />
<dql>
<string-function name="test_string" class="Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestStringFunction" />
<numeric-function name="test_numeric" class="Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestNumericFunction" />
<datetime-function name="test_datetime" class="Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestDatetimeFunction" />
<string-function name="test_string">Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestStringFunction</string-function>
<numeric-function name="test_numeric">Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestNumericFunction</numeric-function>
<datetime-function name="test_datetime">Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestDatetimeFunction</datetime-function>
</dql>
</entity-manager>
</orm>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" ?>
<srv:container xmlns="http://symfony.com/schema/dic/doctrine"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:srv="http://symfony.com/schema/dic/services"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/doctrine http://symfony.com/schema/dic/doctrine/doctrine-1.0.xsd">
<config>
<dbal />
<orm default-entity-manager="default">
<entity-manager name="default">
<hydrator name="test_hydrator">Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestHydrator</hydrator>
<mapping name="YamlBundle" />
</entity-manager>
</orm>
</config>
</srv:container>

View File

@ -12,7 +12,7 @@
default-entity-manager="default"
>
<entity-manager name="default" metadata-cache-driver="apc">
<mapping name="Yaml" />
<mapping name="YamlBundle" />
</entity-manager>
</orm>
</config>

View File

@ -9,10 +9,10 @@
<config>
<orm default-entity-manager="em2">
<entity-manager name="em1">
<mapping name="Annotations" />
<mapping name="AnnotationsBundle" />
</entity-manager>
<entity-manager name="em2">
<mapping name="Yaml" dir="Resources/config/doctrine/metadata" alias="yml" />
<mapping name="YamlBundle" dir="Resources/config/doctrine/metadata" alias="yml" />
<mapping name="manual" type="xml" prefix="Fixtures\Bundles\XmlBundle"
dir="%kernel.root_dir%/../src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/XmlBundle/Resources/config/doctrine/metadata"
alias="TestAlias"

View File

@ -30,10 +30,10 @@
<orm default-entity-manager="em2" auto-generate-proxy-classes="true">
<entity-manager name="em1" metadata-cache-driver="xcache" connection="conn1">
<mapping name="Yaml" />
<mapping name="YamlBundle" />
</entity-manager>
<entity-manager name="em2" connection="conn2" metadata-cache-driver="apc">
<mapping name="Yaml" />
<mapping name="YamlBundle" />
</entity-manager>
</orm>
</config>

View File

@ -16,7 +16,7 @@
<port>11211</port>
<instance-class>Memcache</instance-class>
</metadata-cache-driver>
<mapping name="Yaml" />
<mapping name="YamlBundle" />
</entity-manager>
</orm>
</config>

View File

@ -32,7 +32,7 @@
<port>11211</port>
<instance-class>Memcache</instance-class>
</metadata-cache-driver>
<mapping name="Yaml" />
<mapping name="YamlBundle" />
</entity-manager>
</orm>
</config>

View File

@ -9,8 +9,8 @@
<config>
<orm default-entity-manager="default">
<entity-manager name="default">
<mapping name="Annotations" />
<mapping name="Yaml" dir="Resources/config/doctrine/metadata" alias="yml" />
<mapping name="AnnotationsBundle" />
<mapping name="YamlBundle" dir="Resources/config/doctrine/metadata" alias="yml" />
<mapping name="manual" type="xml" prefix="Fixtures\Bundles\XmlBundle"
dir="%kernel.root_dir%/../src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/XmlBundle/Resources/config/doctrine/metadata"
alias="TestAlias"

View File

@ -4,7 +4,7 @@ doctrine:
entity_managers:
default:
mappings:
Yaml: ~
YamlBundle: ~
dql:
string_functions:
test_string: Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestStringFunction

View File

@ -0,0 +1,9 @@
doctrine:
dbal: ~
orm:
entity_managers:
default:
hydrators:
test_hydrator: Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestHydrator
mappings:
YamlBundle: ~

View File

@ -6,4 +6,4 @@ doctrine:
default:
metadata_cache_driver: apc
mappings:
Yaml: ~
YamlBundle: ~

View File

@ -4,10 +4,10 @@ doctrine:
entity_managers:
em1:
mappings:
Annotations: ~
AnnotationsBundle: ~
em2:
mappings:
Yaml:
YamlBundle:
dir: Resources/config/doctrine/metadata
alias: yml
manual:

View File

@ -26,9 +26,9 @@ doctrine:
metadata_cache_driver: xcache
connection: conn1
mappings:
Yaml: ~
YamlBundle: ~
em2:
metadata_cache_driver: apc
connection: conn2
mappings:
Yaml: ~
YamlBundle: ~

View File

@ -5,7 +5,7 @@ doctrine:
entity_managers:
default:
mappings:
Yaml: ~
YamlBundle: ~
metadata_cache_driver:
type: memcache
class: Doctrine\Common\Cache\MemcacheCache

View File

@ -17,7 +17,7 @@ doctrine:
default:
connection: default
mappings:
Yaml: ~
YamlBundle: ~
metadata_cache_driver:
type: memcache
class: Doctrine\Common\Cache\MemcacheCache

View File

@ -4,8 +4,8 @@ doctrine:
entity_managers:
default:
mappings:
Annotations: ~
Yaml:
AnnotationsBundle: ~
YamlBundle:
dir: Resources/config/doctrine/metadata
alias: yml
manual:

View File

@ -51,7 +51,7 @@ class TestCase extends \PHPUnit_Framework_TestCase
{
$container = new ContainerBuilder(new ParameterBag(array(
'kernel.debug' => 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',

View File

@ -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 <smith@pooteeweet.org>
*/
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;
}
}

View File

@ -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);

View File

@ -1,76 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\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 <kontakt@beberlei.de>
* @author Jonathan H. Wage <jonwage@gmail.com>
*/
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);
}
}
}

View File

@ -1,76 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\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 <kontakt@beberlei.de>
* @author Jonathan H. Wage <jonwage@gmail.com>
*/
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);
}
}
}

View File

@ -1,54 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\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 <fabien@symfony.com>
* @author Jonathan H. Wage <jonwage@gmail.com>
* @author Henrik Westphal <henrik.westphal@gmail.com>
*/
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(<<<EOT
The <info>doctrine:mongodb:cache:clear-metadata</info> command clears all metadata cache for the default document manager:
<info>./app/console doctrine:mongodb:cache:clear-metadata</info>
You can also optionally specify the <comment>--dm</comment> option to specify which document manager to clear the cache for:
<info>./app/console doctrine:mongodb:cache:clear-metadata --dm=default</info>
EOT
);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
DoctrineODMCommand::setApplicationDocumentManager($this->getApplication(), $input->getOption('dm'));
return parent::execute($input, $output);
}
}

View File

@ -1,53 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\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 <justin@shopopensky.com>
*/
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(<<<EOT
The <info>doctrine:mongodb:schema:create</info> command creates the default document manager's schema:
<info>./app/console doctrine:mongodb:schema:create</info>
You can also optionally specify the name of a document manager to create the schema for:
<info>./app/console doctrine:mongodb:schema:create --dm=default</info>
EOT
);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
DoctrineODMCommand::setApplicationDocumentManager($this->getApplication(), $input->getOption('dm'));
parent::execute($input, $output);
}
}

View File

@ -1,120 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\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 <justin@shopopensky.com>
*/
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;
}
}

View File

@ -1,53 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\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 <justin@shopopensky.com>
*/
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(<<<EOT
The <info>doctrine:mongodb:schema:drop</info> command drops the default document manager's schema:
<info>./app/console doctrine:mongodb:schema:drop</info>
You can also optionally specify the name of a document manager to drop the schema for:
<info>./app/console doctrine:mongodb:schema:drop --dm=default</info>
EOT
);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
DoctrineODMCommand::setApplicationDocumentManager($this->getApplication(), $input->getOption('dm'));
parent::execute($input, $output);
}
}

View File

@ -1,80 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\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 <fabien@symfony.com>
* @author Jonathan H. Wage <jonwage@gmail.com>
*/
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(<<<EOT
The <info>doctrine:mongodb:generate:documents</info> command generates document classes and method stubs from your mapping information:
You have to limit generation of documents to an individual bundle:
<info>./app/console doctrine:mongodb:generate:documents MyCustomBundle</info>
Alternatively, you can limit generation to a single document within a bundle:
<info>./app/console doctrine:mongodb:generate:documents "MyCustomBundle" --document="User"</info>
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 "<info>%s</info>"', $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 <comment>%s</comment>', $metadata->name));
$documentGenerator->generate(array($metadata), $this->findBasePathForBundle($foundBundle));
}
} else {
throw new \RuntimeException("Bundle " . $bundleName . " does not contain any mapped documents.");
}
}
}

View File

@ -1,54 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\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 <fabien@symfony.com>
* @author Jonathan H. Wage <jonwage@gmail.com>
*/
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(<<<EOT
The <info>doctrine:mongodb:generate:hydrators</info> command generates hydrator classes for your documents:
<info>./app/console doctrine:mongodb:generate:hydrators</info>
You can specify the document manager you want to generate the hydrators for:
<info>./app/console doctrine:mongodb:generate:hydrators --dm=name</info>
EOT
);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
DoctrineODMCommand::setApplicationDocumentManager($this->getApplication(), $input->getOption('dm'));
return parent::execute($input, $output);
}
}

View File

@ -1,54 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\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 <fabien@symfony.com>
* @author Jonathan H. Wage <jonwage@gmail.com>
*/
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(<<<EOT
The <info>doctrine:mongodb:generate:proxies</info> command generates proxy classes for your default document manager:
<info>./app/console doctrine:mongodb:generate:proxies</info>
You can specify the document manager you want to generate the proxies for:
<info>./app/console doctrine:mongodb:generate:proxies --dm=name</info>
EOT
);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
DoctrineODMCommand::setApplicationDocumentManager($this->getApplication(), $input->getOption('dm'));
return parent::execute($input, $output);
}
}

View File

@ -1,77 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\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 <fabien@symfony.com>
* @author Jonathan H. Wage <jonwage@gmail.com>
*/
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(<<<EOT
The <info>doctrine:mongodb:generate:repositories</info> command generates the configured document repository classes from your mapping information:
<info>./app/console doctrine:mongodb:generate:repositories</info>
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 "<info>%s</info>"', $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(' > <info>OK</info> generating <comment>%s</comment>', $metadata->customRepositoryClassName));
$generator->writeDocumentRepositoryClass($metadata->customRepositoryClassName, $this->findBasePathForBundle($foundBundle));
} else {
$output->writeln(sprintf(' > <error>SKIP</error> no custom repository for <comment>%s</comment>', $metadata->name));
}
}
} else {
throw new \RuntimeException("Bundle " . $bundleName . " does not contain any mapped documents.");
}
}
}

View File

@ -1,84 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\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 <kontakt@beberlei.de>
* @author Jonathan H. Wage <jonwage@gmail.com>
*/
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(<<<EOT
The <info>doctrine:mongodb:mapping:info</info> shows basic information about which
documents exist and possibly if their mapping information contains errors or not.
<info>./app/console doctrine:mongodb:mapping:info</info>
If you are using multiple document managers you can pick your choice with the <info>--dm</info> option:
<info>./app/console doctrine:mongodb:mapping:info --dm=default</info>
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 <info>%d</info> documents mapped in document manager <info>%s</info>:\n",
count($documentClassNames), $documentManagerName), true);
foreach ($documentClassNames AS $documentClassName) {
try {
$cm = $documentManager->getClassMetadata($documentClassName);
$output->write("<info>[OK]</info> " . $documentClassName, true);
} catch(\Exception $e) {
$output->write("<error>[FAIL]</error> " . $documentClassName, true);
$output->write("<comment>" . $e->getMessage()."</comment>", true);
$output->write("", true);
}
}
}
}

View File

@ -1,108 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\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 <fabien@symfony.com>
* @author Jonathan H. Wage <jonwage@gmail.com>
*/
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(<<<EOT
The <info>doctrine:mongodb:data:load</info> command loads data fixtures from your bundles:
<info>./app/console doctrine:mongodb:data:load</info>
You can also optionally specify the path to fixtures with the <info>--fixtures</info> option:
<info>./app/console doctrine:mongodb:data:load --fixtures=/path/to/fixtures1 --fixtures=/path/to/fixtures2</info>
If you want to append the fixtures instead of flushing the database first you can use the <info>--append</info> option:
<info>./app/console doctrine:mongodb:data:load --append</info>
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(' <comment>></comment> <info>%s</info>', $message));
});
$executor->execute($fixtures, $input->getOption('append'));
}
}

View File

@ -1,44 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\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 <fabien@symfony.com>
* @author Jonathan H. Wage <jonwage@gmail.com>
*/
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);
}
}

View File

@ -1,59 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\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 <kris.wallsmith@symfony.com>
*/
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';
}
}

View File

@ -1,30 +0,0 @@
<?php
namespace Symfony\Bundle\DoctrineMongoDBBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
class CreateHydratorDirectoryPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
if (!$container->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));
}
}
}

View File

@ -1,30 +0,0 @@
<?php
namespace Symfony\Bundle\DoctrineMongoDBBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
class CreateProxyDirectoryPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
if (!$container->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));
}
}
}

View File

@ -1,59 +0,0 @@
<?php
namespace Symfony\Bundle\DoctrineMongoDBBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
class RegisterEventListenersAndSubscribersPass implements CompilerPassInterface
{
protected $container;
public function process(ContainerBuilder $container)
{
$this->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),
));
}
}
}
}

View File

@ -1,190 +0,0 @@
<?php
namespace Symfony\Bundle\DoctrineMongoDBBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
/**
* FrameworkExtension configuration structure.
*
* @author Ryan Weaver <ryan@thatsquality.com>
*/
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;
}
}

View File

@ -1,357 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\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 <bulat@theopenskyproject.com>
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Jonathan H. Wage <jonwage@gmail.com>
*/
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';
}
}

View File

@ -1,38 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\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 <bulat@theopenskyproject.com>
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Jonathan H. Wage <jonwage@gmail.com>
*/
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);
}
}

View File

@ -1,299 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\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 <kris.wallsmith@symfony.com>
*/
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))).' }';
}
}
}

View File

@ -1,118 +0,0 @@
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="doctrine.odm.mongodb.connection_class">Doctrine\MongoDB\Connection</parameter>
<parameter key="doctrine.odm.mongodb.configuration_class">Doctrine\ODM\MongoDB\Configuration</parameter>
<parameter key="doctrine.odm.mongodb.document_manager_class">Doctrine\ODM\MongoDB\DocumentManager</parameter>
<parameter key="doctrine.odm.mongodb.logger_class">Symfony\Bundle\DoctrineMongoDBBundle\Logger\DoctrineMongoDBLogger</parameter>
<parameter key="doctrine.odm.mongodb.data_collector_class">Symfony\Bundle\DoctrineMongoDBBundle\DataCollector\DoctrineMongoDBDataCollector</parameter>
<parameter key="doctrine.odm.mongodb.event_manager_class">Doctrine\Common\EventManager</parameter>
<!-- proxies -->
<parameter key="doctrine.odm.mongodb.proxy_namespace">Proxies</parameter>
<parameter key="doctrine.odm.mongodb.proxy_dir">%kernel.cache_dir%/doctrine/odm/mongodb/Proxies</parameter>
<parameter key="doctrine.odm.mongodb.auto_generate_proxy_classes">false</parameter>
<!-- hydrators -->
<parameter key="doctrine.odm.mongodb.hydrator_namespace">Hydrators</parameter>
<parameter key="doctrine.odm.mongodb.hydrator_dir">%kernel.cache_dir%/doctrine/odm/mongodb/Hydrators</parameter>
<parameter key="doctrine.odm.mongodb.auto_generate_hydrator_classes">false</parameter>
<!-- cache -->
<parameter key="doctrine.odm.mongodb.cache.array_class">Doctrine\Common\Cache\ArrayCache</parameter>
<parameter key="doctrine.odm.mongodb.cache.apc_class">Doctrine\Common\Cache\ApcCache</parameter>
<parameter key="doctrine.odm.mongodb.cache.memcache_class">Doctrine\Common\Cache\MemcacheCache</parameter>
<parameter key="doctrine.odm.mongodb.cache.memcache_host">localhost</parameter>
<parameter key="doctrine.odm.mongodb.cache.memcache_port">11211</parameter>
<parameter key="doctrine.odm.mongodb.cache.memcache_instance_class">Memcache</parameter>
<parameter key="doctrine.odm.mongodb.cache.xcache_class">Doctrine\Common\Cache\XcacheCache</parameter>
<!-- metadata -->
<parameter key="doctrine.odm.mongodb.metadata.driver_chain_class">Doctrine\ODM\MongoDB\Mapping\Driver\DriverChain</parameter>
<parameter key="doctrine.odm.mongodb.metadata.annotation_class">Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver</parameter>
<parameter key="doctrine.odm.mongodb.metadata.annotation_reader_class">Doctrine\Common\Annotations\AnnotationReader</parameter>
<parameter key="doctrine.odm.mongodb.metadata.xml_class">Doctrine\ODM\MongoDB\Mapping\Driver\XmlDriver</parameter>
<parameter key="doctrine.odm.mongodb.metadata.yml_class">Doctrine\ODM\MongoDB\Mapping\Driver\YamlDriver</parameter>
<!-- directories -->
<parameter key="doctrine.odm.mongodb.mapping_dirs" type="collection"></parameter>
<parameter key="doctrine.odm.mongodb.xml_mapping_dirs">%doctrine.odm.mongodb.mapping_dirs%</parameter>
<parameter key="doctrine.odm.mongodb.yml_mapping_dirs">%doctrine.odm.mongodb.mapping_dirs%</parameter>
<parameter key="doctrine.odm.mongodb.document_dirs" type="collection"></parameter>
<!-- security/user -->
<parameter key="doctrine.odm.mongodb.security.user.provider.class">Symfony\Bundle\DoctrineMongoDBBundle\Security\DocumentUserProvider</parameter>
<!-- proxy cache warmer -->
<parameter key="doctrine.odm.mongodb.proxy_cache_warmer.class">Symfony\Bundle\DoctrineMongoDBBundle\CacheWarmer\ProxyCacheWarmer</parameter>
<!-- hydrator cache warmer -->
<parameter key="doctrine.odm.mongodb.hydrator_cache_warmer.class">Symfony\Bundle\DoctrineMongoDBBundle\CacheWarmer\HydratorCacheWarmer</parameter>
<!-- validator -->
<parameter key="doctrine_odm.mongodb.validator.unique.class">Symfony\Bundle\DoctrineMongoDBBundle\Validator\Constraints\UniqueValidator</parameter>
</parameters>
<services>
<!-- defaults -->
<service id="doctrine.odm.mongodb.cache" alias="doctrine.odm.mongodb.cache.array" />
<!-- metadata -->
<service id="doctrine.odm.mongodb.metadata.chain" class="%doctrine.odm.mongodb.metadata.driver_chain_class%" />
<service id="doctrine.odm.mongodb.metadata.annotation" class="%doctrine.odm.mongodb.metadata.annotation_class%">
<argument type="service" id="doctrine.odm.mongodb.metadata.annotation_reader" />
<argument>%doctrine.odm.mongodb.document_dirs%</argument>
</service>
<service id="doctrine.odm.mongodb.metadata.annotation_reader" class="%doctrine.odm.mongodb.metadata.annotation_reader_class%">
<argument type="service" id="doctrine.odm.mongodb.cache" />
<call method="setAnnotationNamespaceAlias">
<argument>Doctrine\ODM\MongoDB\Mapping\</argument>
<argument>mongodb</argument>
</call>
</service>
<service id="doctrine.odm.mongodb.metadata.xml" class="%doctrine.odm.mongodb.metadata.xml_class%">
<argument>%doctrine.odm.mongodb.xml_mapping_dirs%</argument>
</service>
<service id="doctrine.odm.mongodb.metadata.yml" class="%doctrine.odm.mongodb.metadata.yml_class%">
<argument>%doctrine.odm.mongodb.yml_mapping_dirs%</argument>
</service>
<!-- cache -->
<service id="doctrine.odm.mongodb.cache.array" class="%doctrine.odm.mongodb.cache.array_class%" />
<!-- logger -->
<service id="doctrine.odm.mongodb.logger" class="%doctrine.odm.mongodb.logger_class%">
<argument type="service" id="logger" on-invalid="null" />
</service>
<service id="doctrine.odm.mongodb.data_collector" class="%doctrine.odm.mongodb.data_collector_class%" public="false">
<tag name="data_collector" template="DoctrineMongoDB:Collector:mongodb" id="mongodb" />
<argument type="service" id="doctrine.odm.mongodb.logger" />
</service>
<!-- Cache Warmers -->
<service id="doctrine.odm.mongodb.proxy_cache_warmer" class="%doctrine.odm.mongodb.proxy_cache_warmer.class%" public="false">
<tag name="kernel.cache_warmer" />
<argument type="service" id="service_container" />
</service>
<service id="doctrine.odm.mongodb.hydrator_cache_warmer" class="%doctrine.odm.mongodb.hydrator_cache_warmer.class%" public="false">
<tag name="kernel.cache_warmer" />
<argument type="service" id="service_container" />
</service>
<!-- validator -->
<service id="doctrine_odm.mongodb.validator.unique" class="%doctrine_odm.mongodb.validator.unique.class%">
<tag name="validator.constraint_validator" alias="doctrine_odm.mongodb.unique" />
<argument type="service" id="service_container" />
</service>
<!-- Security -->
<service id="doctrine.odm.mongodb.security.user.provider" class="%doctrine.odm.mongodb.security.user.provider.class%" public="false" abstract="true">
<argument type="service" id="doctrine.odm.mongodb.security.user.document_manager" />
</service>
<service id="doctrine.odm.mongodb.security.user.document_manager" alias="doctrine.odm.mongodb.default_document_manager" public="false" />
</services>
</container>

View File

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns="http://symfony.com/schema/dic/doctrine/odm/mongodb"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://symfony.com/schema/dic/doctrine/odm/mongodb"
elementFormDefault="qualified">
<xsd:element name="config" type="config" />
<xsd:complexType name="config">
<xsd:attribute name="host" type="xsd:string" />
<xsd:attribute name="port" type="xsd:integer" />
<xsd:attribute name="database" type="xsd:string" />
<xsd:attribute name="proxy-dir" type="xsd:string" />
<xsd:attribute name="auto-generate-proxy-classes" type="xsd:boolean" />
<xsd:attribute name="cache" type="cache" />
<xsd:attribute name="metadata" type="metadata" />
</xsd:complexType>
<xsd:simpleType name="cache">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="array" />
<xsd:enumeration value="apc" />
<xsd:enumeration value="memcache" />
<xsd:enumeration value="xcache" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="metadata">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="annotation" />
<xsd:enumeration value="xml" />
<xsd:enumeration value="yml" />
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>

View File

@ -1,45 +0,0 @@
{% extends 'WebProfiler:Profiler:layout.html.twig' %}
{% block toolbar %}
{% set icon %}
<img width="20" height="28" alt="Mongo" style="border-width: 0; vertical-align: middle; margin-right: 5px;" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAcCAYAAABh2p9gAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQRJREFUeNpi/P//PwM1ARMDlcGogZQDlpMnT7pxc3NbA9nhQKxOpL5rQLwJiPeBsI6Ozl+YBOOOHTv+AOllQNwtLS39F2owKYZ/gRq8G4i3ggxEToggWzvc3d2Pk+1lNL4fFAs6ODi8JzdS7mMRVyDVoAMHDsANdAPiOCC+jCQvQKqBQB/BDbwBxK5AHA3E/kB8nKJkA8TMQBwLxaBIKQbi70AvTADSBiSadwFXpCikpKQU8PDwkGTaly9fHFigkaKIJid4584dkiMFFI6jkTJII0WVmpHCAixZQEXWYhDeuXMnyLsVlEQKI45qFBQZ8eRECi4DBaAlDqle/8A48ip6gAADANdQY88Uc0oGAAAAAElFTkSuQmCC"/>
{% endset %}
{% set text %}
<span>{{ collector.querycount }}</span>
{% endset %}
{% include 'WebProfiler:Profiler:toolbar_item.html.twig' with { 'link': profiler_url } %}
{% endblock %}
{% block menu %}
<span class="label">
<span class="icon"><img src="{{ asset('bundles/webprofiler/images/profiler/db.png') }}" alt="" /></span>
<strong>Doctrine MongoDB</strong>
<span class="count">
<span>{{ collector.querycount }}</span>
</span>
</span>
{% endblock %}
{% block panel %}
<h2>Queries</h2>
{% if not collector.queries %}
<p>
<em>Query logging is disabled.</em>
<p>
{% elseif not collector.querycount %}
<p>
<em>No queries.</em>
</p>
{% else %}
<ul class="alt">
{% for query in collector.queries %}
<li class="{{ cycle(['odd', 'even'], loop.index) }}">
<div>
<code>{{ query }}</code>
</div>
</li>
{% endfor %}
</ul>
{% endif %}
{% endblock %}

View File

@ -1,78 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\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;
}
}

Some files were not shown because too many files have changed in this diff Show More