Merge remote branch 'origin/master' into annotations

Conflicts:
	UPDATE.md
This commit is contained in:
Johannes Schmitt 2011-05-03 14:38:51 +02:00
commit 672c4ef122
100 changed files with 899 additions and 548 deletions

View File

@ -5,7 +5,7 @@ What is Symfony2?
-----------------
Symfony2 is a PHP 5.3 full-stack web framework. It is written with speed and
flexibility in mind. It allows developers to built better and easy to maintain
flexibility in mind. It allows developers to build better and easy to maintain
websites with PHP.
Symfony can be used to develop all kind of websites, from your personal blog

View File

@ -89,6 +89,13 @@ beta1 to beta2
*/
private $foo;
* The `doctrine:generate:entities` arguments and options changed. Run
`./app/console doctrine:generate:entities --help` for more information about
the new syntax.
* The `doctrine:generate:repositories` command has been removed. The
functionality has been moved to the `doctrine:generate:entities`.
* Doctrine event subscribers now use a unique "doctrine.event_subscriber" tag.
Doctrine event listeners also use a unique "doctrine.event_listener" tag. To
specify a connection, use the optional "connection" attribute.

View File

@ -143,7 +143,6 @@ class EntityChoiceList extends ArrayChoiceList
$entities = $this->em->getRepository($this->class)->findAll();
}
$propertyPath = null;
$this->choices = array();
$this->entities = array();

View File

@ -32,7 +32,6 @@ class TransTokenParser extends \Twig_TokenParser
$lineno = $token->getLine();
$stream = $this->parser->getStream();
$body = null;
$vars = new \Twig_Node_Expression_Array(array(), $lineno);
$domain = new \Twig_Node_Expression_Constant('messages', $lineno);
if (!$stream->test(\Twig_Token::BLOCK_END_TYPE)) {

View File

@ -23,7 +23,7 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
/**
* Assetic integration.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Kris Wallsmith <kris@symfony.com>
*/
class AsseticBundle extends Bundle
{

View File

@ -17,7 +17,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* The AssetManagerCacheWarmer warms up the formula loader.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Kris Wallsmith <kris@symfony.com>
*/
class AssetManagerCacheWarmer implements CacheWarmerInterface
{

View File

@ -18,7 +18,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* The AssetWriterCacheWarmer processes and writes the asset files.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Kris Wallsmith <kris@symfony.com>
*/
class AssetWriterCacheWarmer implements CacheWarmerInterface
{

View File

@ -22,7 +22,7 @@ use Symfony\Component\Console\Output\OutputInterface;
/**
* Dumps assets to the filesystem.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Kris Wallsmith <kris@symfony.com>
*/
class DumpCommand extends Command
{
@ -59,10 +59,10 @@ class DumpCommand extends Command
* This method includes an infinite loop the continuously polls the asset
* manager for changes.
*
* @param LazyAssetManager $am The asset manager
* @param LazyAssetManager $am The asset manager
* @param string $basePath The base directory to write to
* @param OutputInterface $output The command output
* @param Boolean $debug Debug mode
* @param OutputInterface $output The command output
* @param Boolean $debug Debug mode
*/
protected function watch(LazyAssetManager $am, $basePath, OutputInterface $output, $debug = false)
{
@ -144,7 +144,7 @@ class DumpCommand extends Command
*/
protected function dumpAsset(AssetInterface $asset, $basePath, OutputInterface $output)
{
$target = rtrim($basePath, '/') . '/' . $asset->getTargetUrl();
$target = rtrim($basePath, '/').'/'.str_replace('_controller/', '', $asset->getTargetUrl());
if (!is_dir($dir = dirname($target))) {
$output->writeln('<info>[dir+]</info> '.$dir);
if (false === @mkdir($dir, 0777, true)) {

View File

@ -22,7 +22,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Serves assets.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Kris Wallsmith <kris@symfony.com>
*/
class AsseticController
{

View File

@ -22,7 +22,7 @@ use Symfony\Component\HttpKernel\DependencyInjection\Extension;
/**
* Semantic asset configuration.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Kris Wallsmith <kris@symfony.com>
*/
class AsseticExtension extends Extension
{

View File

@ -18,7 +18,7 @@ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
/**
* Adds services tagged as workers to the asset factory.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Kris Wallsmith <kris@symfony.com>
*/
class AssetFactoryPass implements CompilerPassInterface
{

View File

@ -18,7 +18,7 @@ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
/**
* Adds services tagged as assets to the asset manager.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Kris Wallsmith <kris@symfony.com>
*/
class AssetManagerPass implements CompilerPassInterface
{

View File

@ -17,7 +17,7 @@ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
/**
* Tags either the closure JAR or API filter for the filter manager.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Kris Wallsmith <kris@symfony.com>
*/
class CheckClosureFilterPass implements CompilerPassInterface
{

View File

@ -17,7 +17,7 @@ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
/**
* Checks that the location of the YUI JAR has been configured.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Kris Wallsmith <kris@symfony.com>
*/
class CheckYuiFilterPass implements CompilerPassInterface
{

View File

@ -18,7 +18,7 @@ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
/**
* Adds services tagged as filters to the filter manager.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Kris Wallsmith <kris@symfony.com>
*/
class FilterManagerPass implements CompilerPassInterface
{

View File

@ -17,7 +17,7 @@ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
/**
* This pass removes services associated with unused templating engines.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Kris Wallsmith <kris@symfony.com>
*/
class TemplatingPass implements CompilerPassInterface
{

View File

@ -17,7 +17,7 @@ use Symfony\Component\HttpKernel\KernelInterface;
/**
* Loads asset formulae from the filesystem.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Kris Wallsmith <kris@symfony.com>
*/
class AssetFactory extends BaseAssetFactory
{

View File

@ -16,7 +16,7 @@ use Assetic\Factory\Loader\BasePhpFormulaLoader;
/**
* Loads formulae from Symfony2 PHP templates.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Kris Wallsmith <kris@symfony.com>
*/
class AsseticHelperFormulaLoader extends BasePhpFormulaLoader
{

View File

@ -17,7 +17,7 @@ use Symfony\Component\Templating\Loader\LoaderInterface;
/**
* A directory resource that creates Symfony2 templating resources.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Kris Wallsmith <kris@symfony.com>
*/
class DirectoryResource extends BaseDirectoryResource
{

View File

@ -18,7 +18,7 @@ use Symfony\Component\Templating\Loader\LoaderInterface;
/**
* A file resource.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Kris Wallsmith <kris@symfony.com>
*/
class FileResource implements ResourceInterface
{

View File

@ -17,7 +17,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Lazy filter manager.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Kris Wallsmith <kris@symfony.com>
*/
class FilterManager extends BaseFilterManager
{

View File

@ -16,7 +16,7 @@ use Symfony\Component\HttpKernel\Event\GetResponseEvent;
/**
* Adds a few formats to each request.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Kris Wallsmith <kris@symfony.com>
*/
class RequestListener
{

View File

@ -5,13 +5,14 @@
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="assetic.filter.compass.class">Assetic\Filter\CompassFilter</parameter>
<parameter key="assetic.filter.compass.class">Assetic\Filter\Sass\CompassFilter</parameter>
<parameter key="assetic.filter.compass.sass">%assetic.sass.bin%</parameter>
</parameters>
<services>
<service id="assetic.filter.compass" class="%assetic.filter.compass.class%">
<tag name="assetic.filter" alias="compass" />
<argument>%assetic.read_from%</argument>
<argument>%assetic.filter.compass.sass%</argument>
</service>
</services>

View File

@ -12,6 +12,7 @@
<services>
<service id="assetic.filter.sass" class="%assetic.filter.sass.class%">
<tag name="assetic.filter" alias="sass" />
<argument>%assetic.read_from%</argument>
<argument>%assetic.filter.sass.bin%</argument>
</service>
</services>

View File

@ -12,6 +12,7 @@
<services>
<service id="assetic.filter.scss" class="%assetic.filter.scss.class%">
<tag name="assetic.filter" alias="scss" />
<argument>%assetic.read_from%</argument>
<argument>%assetic.filter.scss.sass%</argument>
</service>
</services>

View File

@ -33,7 +33,7 @@ use Symfony\Component\Routing\RouteCollection;
* In a production environment you should use the `assetic:dump` command to
* create static asset files.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Kris Wallsmith <kris@symfony.com>
*/
class AsseticLoader extends Loader
{

View File

@ -18,7 +18,7 @@ use Symfony\Component\Templating\Helper\Helper;
/**
* The "assetic" templating helper.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Kris Wallsmith <kris@symfony.com>
*/
abstract class AsseticHelper extends Helper
{

View File

@ -18,7 +18,7 @@ use Symfony\Bundle\FrameworkBundle\Templating\Helper\RouterHelper;
/**
* The dynamic "assetic" templating helper.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Kris Wallsmith <kris@symfony.com>
*/
class DynamicAsseticHelper extends AsseticHelper
{

View File

@ -18,7 +18,7 @@ use Symfony\Component\Templating\Helper\AssetsHelper;
/**
* The static "assetic" templating helper.
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Kris Wallsmith <kris@symfony.com>
*/
class StaticAsseticHelper extends AsseticHelper
{

View File

@ -42,7 +42,7 @@ abstract class AbstractDoctrineExtension extends Extension
*/
protected function loadMappingInformation(array $objectManager, ContainerBuilder $container)
{
if (!$objectManager['mappings'] && $objectManager['auto_mapping']) {
if ($objectManager['auto_mapping']) {
// automatically register bundle mappings
foreach (array_keys($container->getParameter('kernel.bundles')) as $bundle) {
if (!isset($objectManager['mappings'][$bundle])) {
@ -52,7 +52,7 @@ abstract class AbstractDoctrineExtension extends Extension
}
foreach ($objectManager['mappings'] as $mappingName => $mappingConfig) {
if (false === $mappingConfig) {
if (null !== $mappingConfig && false === $mappingConfig['mapping']) {
continue;
}

View File

@ -11,13 +11,10 @@
namespace Symfony\Bundle\DoctrineBundle\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\HttpKernel\Util\Filesystem;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DriverManager;
/**
* Database tool allows you to easily drop and create your configured databases.
@ -31,16 +28,18 @@ class CreateDatabaseDoctrineCommand extends DoctrineCommand
{
$this
->setName('doctrine:database:create')
->setDescription('Create the configured databases.')
->addOption('connection', null, InputOption::VALUE_OPTIONAL, 'The connection to use for this command.')
->setDescription('Create the configured databases')
->addOption('connection', null, InputOption::VALUE_OPTIONAL, 'The connection to use for this command')
->setHelp(<<<EOT
The <info>doctrine:database:create</info> command creates the default connections database:
The <info>doctrine:database:create</info> command creates the default
connections database:
<info>./app/console doctrine:database:create</info>
<info>./app/console doctrine:database:create</info>
You can also optionally specify the name of a connection to create the database for:
You can also optionally specify the name of a connection to create the
database for:
<info>./app/console doctrine:database:create --connection=default</info>
<info>./app/console doctrine:database:create --connection=default</info>
EOT
);
}
@ -50,11 +49,11 @@ EOT
$connection = $this->getDoctrineConnection($input->getOption('connection'));
$params = $connection->getParams();
$name = isset($params['path']) ? $params['path']:$params['dbname'];
$name = isset($params['path']) ? $params['path'] : $params['dbname'];
unset($params['dbname']);
$tmpConnection = \Doctrine\DBAL\DriverManager::getConnection($params);
$tmpConnection = DriverManager::getConnection($params);
try {
$tmpConnection->getSchemaManager()->createDatabase($name);
@ -66,4 +65,4 @@ EOT
$tmpConnection->close();
}
}
}

View File

@ -12,65 +12,26 @@
namespace Symfony\Bundle\DoctrineBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\Command;
use Symfony\Component\Console\Input\ArrayInput;
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\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper;
use Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper;
use Doctrine\ORM\Tools\DisconnectedClassMetadataFactory;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Doctrine\ORM\Tools\EntityGenerator;
use Doctrine\ORM\Version as DoctrineVersion;
use Doctrine\ORM\ORMException;
/**
* Base class for Doctrine console commands to extend from.
*
* Provides some helper and convenience methods to configure doctrine commands in the context of bundles
* and multiple connections/entity managers.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
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
*/
public static function setApplicationEntityManager(Application $application, $emName)
{
$container = $application->getKernel()->getContainer();
$em = self::getEntityManager($container, $emName);
$helperSet = $application->getHelperSet();
$helperSet->set(new ConnectionHelper($em->getConnection()), 'db');
$helperSet->set(new EntityManagerHelper($em), 'em');
}
public static function setApplicationConnection(Application $application, $connName)
{
$container = $application->getKernel()->getContainer();
$connName = $connName ? $connName : $container->getParameter('doctrine.dbal.default_connection');
$connServiceName = sprintf('doctrine.dbal.%s_connection', $connName);
if (!$container->has($connServiceName)) {
throw new \InvalidArgumentException(sprintf('Could not find Doctrine Connection named "%s"', $connName));
}
$connection = $container->get($connServiceName);
$helperSet = $application->getHelperSet();
$helperSet->set(new ConnectionHelper($connection), 'db');
}
protected function getEntityGenerator()
{
$entityGenerator = new EntityGenerator();
if (version_compare(\Doctrine\ORM\Version::VERSION, "2.0.2-DEV") >= 0) {
if (version_compare(DoctrineVersion::VERSION, "2.0.2-DEV") >= 0) {
$entityGenerator->setAnnotationPrefix("orm:");
}
$entityGenerator->setGenerateAnnotations(false);
@ -78,18 +39,20 @@ abstract class DoctrineCommand extends Command
$entityGenerator->setRegenerateEntityIfExists(false);
$entityGenerator->setUpdateEntityIfExists(true);
$entityGenerator->setNumSpaces(4);
return $entityGenerator;
}
protected static function getEntityManager($container, $name = null)
protected function getEntityManager($name)
{
$name = $name ? $name : $container->getParameter('doctrine.orm.default_entity_manager');
$serviceName = sprintf('doctrine.orm.%s_entity_manager', $name);
if (!$container->has($serviceName)) {
$name = $name ?: $this->container->getParameter('doctrine.orm.default_entity_manager');
$ems = $this->container->getParameter('doctrine.orm.entity_managers');
if (!isset($ems[$name])) {
throw new \InvalidArgumentException(sprintf('Could not find Doctrine EntityManager named "%s"', $name));
}
return $container->get($serviceName);
return $this->container->get($ems[$name]);
}
/**
@ -100,42 +63,51 @@ abstract class DoctrineCommand extends Command
*/
protected function getDoctrineConnection($name)
{
$connectionName = $name ?: $this->container->getParameter('doctrine.dbal.default_connection');
$connectionName = sprintf('doctrine.dbal.%s_connection', $connectionName);
$name = $name ?: $this->container->getParameter('doctrine.dbal.default_connection');
if (!$this->container->has($connectionName)) {
$connections = $this->container->getParameter('doctrine.dbal.connections');
if (!isset($connections[$name])) {
throw new \InvalidArgumentException(sprintf('<error>Could not find a connection named <comment>%s</comment></error>', $name));
}
return $this->container->get($connectionName);
return $this->container->get($connections[$name]);
}
protected function getDoctrineEntityManagers()
protected function findMetadatasByNamespace($namespace)
{
$entityManagers = array();
foreach ($this->container->getParameter('doctrine.orm.entity_managers') as $id) {
$entityManagers[] = $this->container->get($id);
}
return $entityManagers;
}
protected function getBundleMetadatas(Bundle $bundle)
{
$namespace = $bundle->getNamespace();
$bundleMetadatas = array();
$entityManagers = $this->getDoctrineEntityManagers();
foreach ($entityManagers as $key => $em) {
$cmf = new DisconnectedClassMetadataFactory();
$cmf->setEntityManager($em);
$metadatas = $cmf->getAllMetadata();
foreach ($metadatas as $metadata) {
if (strpos($metadata->name, $namespace) === 0) {
$bundleMetadatas[$metadata->name] = $metadata;
}
$metadatas = array();
foreach ($this->findAllMetadatas() as $name => $metadata) {
if (strpos($name, $namespace) === 0) {
$metadatas[$name] = $metadata;
}
}
return $bundleMetadatas;
return $metadatas;
}
protected function findMetadatasByClass($entity)
{
foreach ($this->findAllMetadatas() as $name => $metadata) {
if ($name === $entity) {
return array($name => $metadata);
}
}
return array();
}
protected function findAllMetadatas()
{
$metadatas = array();
foreach ($this->container->getParameter('doctrine.orm.entity_managers') as $id) {
$cmf = new DisconnectedClassMetadataFactory();
$cmf->setEntityManager($this->container->get($id));
foreach ($cmf->getAllMetadata() as $metadata) {
$metadatas[$metadata->name] = $metadata;
}
}
return $metadatas;
}
/**
@ -144,16 +116,33 @@ abstract class DoctrineCommand extends Command
* @param Bundle $bundle
* @return string
*/
protected function findBasePathForBundle($bundle)
protected function findBasePathForClass($name, $namespace, $path)
{
$path = str_replace('\\', '/', $bundle->getNamespace());
$search = str_replace('\\', '/', $bundle->getPath());
$destination = str_replace('/'.$path, '', $search, $c);
$namespace = str_replace('\\', '/', $namespace);
$search = str_replace('\\', '/', $path);
$destination = str_replace('/'.$namespace, '', $search, $c);
if ($c != 1) {
throw new \RuntimeException(sprintf('Can\'t find base path for bundle (path: "%s", destination: "%s").', $path, $destination));
throw new \RuntimeException(sprintf('Can\'t find base path for "%s" (path: "%s", destination: "%s").', $name, $path, $destination));
}
return $destination;
}
protected function getAliasedClassName($name)
{
$pos = strpos($name, ':');
$alias = substr($name, 0, $pos);
foreach ($this->container->getParameter('doctrine.orm.entity_managers') as $id) {
$em = $this->container->get($id);
try {
return $em->getConfiguration()->getEntityNamespace($alias).'\\'.substr($name, $pos + 1);
} catch (ORMException $e) {
}
}
throw new \RuntimeException(sprintf('Entity "%s" does not exist.', $name));
}
}

View File

@ -11,13 +11,9 @@
namespace Symfony\Bundle\DoctrineBundle\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\HttpKernel\Util\Filesystem;
use Doctrine\DBAL\Connection;
/**
* Database tool allows you to easily drop and create your configured databases.
@ -31,21 +27,24 @@ class DropDatabaseDoctrineCommand extends DoctrineCommand
{
$this
->setName('doctrine:database:drop')
->setDescription('Drop the configured databases.')
->addOption('connection', null, InputOption::VALUE_OPTIONAL, 'The connection to use for this command.')
->addOption('force', null, InputOption::VALUE_NONE, 'Set this parameter to execute this action.')
->setDescription('Drop the configured databases')
->addOption('connection', null, InputOption::VALUE_OPTIONAL, 'The connection to use for this command')
->addOption('force', null, InputOption::VALUE_NONE, 'Set this parameter to execute this action')
->setHelp(<<<EOT
The <info>doctrine:database:drop</info> command drops the default connections database:
The <info>doctrine:database:drop</info> command drops the default connections
database:
<info>./app/console doctrine:database:drop</info>
<info>./app/console doctrine:database:drop</info>
The --force parameter has to be used to actually drop the database.
You can also optionally specify the name of a connection to drop the database for:
You can also optionally specify the name of a connection to drop the database
for:
<info>./app/console doctrine:database:drop --connection=default</info>
<info>./app/console doctrine:database:drop --connection=default</info>
<error>Be careful: All data in a given database will be lost when executing this command.</error>
<error>Be careful: All data in a given database will be lost when executing
this command.</error>
EOT
);
}
@ -56,7 +55,7 @@ EOT
$params = $connection->getParams();
$name = isset($params['path'])?$params['path']:(isset($params['dbname'])?$params['dbname']:false);
$name = isset($params['path']) ? $params['path'] : (isset($params['dbname']) ? $params['dbname'] : false);
if (!$name) {
throw new \InvalidArgumentException("Connection does not contain a 'path' or 'dbname' parameter and cannot be dropped.");
@ -71,10 +70,11 @@ EOT
$output->writeln(sprintf('<error>%s</error>', $e->getMessage()));
}
} else {
$output->writeln('<error>ATTENTION:</error> This operation should not be executed in a production environment.' . PHP_EOL);
$output->writeln('<error>ATTENTION:</error> This operation should not be executed in a production environment.');
$output->writeln('');
$output->writeln(sprintf('<info>Would drop the database named <comment>%s</comment>.</info>', $name));
$output->writeln('Please run the operation with --force to execute');
$output->writeln('<error>All data will be lost!</error>');
}
}
}
}

View File

@ -15,7 +15,6 @@ 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 entity classes from mapping information
@ -29,52 +28,108 @@ class GenerateEntitiesDoctrineCommand extends DoctrineCommand
{
$this
->setName('doctrine:generate:entities')
->setDescription('Generate entity classes and method stubs from your mapping information.')
->addArgument('bundle', InputArgument::REQUIRED, 'The bundle to initialize the entity or entities in.')
->addOption('entity', null, InputOption::VALUE_OPTIONAL, 'The entity class to initialize (shortname without namespace).')
->setDescription('Generate entity classes and method stubs from your mapping information')
->addArgument('name', InputArgument::REQUIRED, 'A bundle name, a namespace, or a class name')
->setHelp(<<<EOT
The <info>doctrine:generate:entities</info> command generates entity classes and method stubs from your mapping information:
The <info>doctrine:generate:entities</info> command generates entity classes
and method stubs from your mapping information:
You have to limit generation of entities to an individual bundle:
You have to limit generation of entities:
* To a bundle:
<info>./app/console doctrine:generate:entities MyCustomBundle</info>
Alternatively, you can limit generation to a single entity within a bundle:
* To a single entity:
<info>./app/console doctrine:generate:entities "MyCustomBundle" --entity="User"</info>
<info>./app/console doctrine:generate:entities MyCustomBundle:User</info>
<info>./app/console doctrine:generate:entities MyCustomBundle/Entity/User</info>
You have to specify the shortname (without namespace) of the entity you want to filter for.
* To a namespace
<info>./app/console doctrine:generate:entities MyCustomBundle/Entity</info>
EOT
);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$bundleName = $input->getArgument('bundle');
$filterEntity = $input->getOption('entity');
try {
$bundle = $this->getApplication()->getKernel()->getBundle($input->getArgument('name'));
$foundBundle = $this->getApplication()->getKernel()->getBundle($bundleName);
$output->writeln(sprintf('Generating entities for bundle "<info>%s</info>"', $bundle->getName()));
list($metadatas, $path) = $this->getBundleInfo($bundle);
} catch (\InvalidArgumentException $e) {
$name = strtr($input->getArgument('name'), '/', '\\');
if ($metadatas = $this->getBundleMetadatas($foundBundle)) {
$output->writeln(sprintf('Generating entities for "<info>%s</info>"', $foundBundle->getName()));
$entityGenerator = $this->getEntityGenerator();
if (false !== strpos($name, ':')) {
$name = $this->getAliasedClassName($name);
}
foreach ($metadatas as $metadata) {
if ($filterEntity && $metadata->getReflectionClass()->getShortName() !== $filterEntity) {
if (class_exists($name)) {
$output->writeln(sprintf('Generating entity "<info>%s</info>"', $name));
list($metadatas, $path) = $this->getClassInfo($name);
} else {
$output->writeln(sprintf('Generating entities for namespace "<info>%s</info>"', $name));
list($metadatas, $path) = $this->getNamespaceInfo($name);
}
}
$generator = $this->getEntityGenerator();
foreach ($metadatas as $metadata) {
$output->writeln(sprintf(' > generating <comment>%s</comment>', $metadata->name));
$generator->generate(array($metadata), $path);
if ($metadata->customRepositoryClassName) {
if (false === strpos($metadata->customRepositoryClassName, $namespace)) {
continue;
}
if (strpos($metadata->name, $foundBundle->getNamespace()) === false) {
throw new \RuntimeException(
"Entity " . $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));
$entityGenerator->generate(array($metadata), $this->findBasePathForBundle($foundBundle));
$generator->writeEntityRepositoryClass($metadata->customRepositoryClassName, $path);
}
} else {
throw new \RuntimeException("Bundle " . $bundleName . " does not contain any mapped entities.");
}
}
}
private function getBundleInfo($bundle)
{
$namespace = $bundle->getNamespace();
if (!$metadatas = $this->findMetadatasByNamespace($namespace)) {
throw new \RuntimeException(sprintf('Bundle "%s" does not contain any mapped entities.', $bundle->getName()));
}
$path = $this->findBasePathForClass($bundle->getName(), $bundle->getNamespace(), $bundle->getPath());
return array($metadatas, $path);
}
private function getClassInfo($class)
{
if (!$metadatas = $this->findMetadatasByClass($class)) {
throw new \RuntimeException(sprintf('Entity "%s" is not a mapped entity.', $class));
}
$r = $metadatas[$class]->getReflectionClass();
if (!$r) {
throw new \RuntimeException('Unable to determine where to save the "%s" class.', $class);
}
$path = $this->findBasePathForClass($class, $r->getNamespacename(), dirname($r->getFilename()));
return array($metadatas, $path);
}
private function getNamespaceInfo($namespace)
{
if (!$metadatas = $this->findMetadatasByNamespace($namespace)) {
throw new \RuntimeException(sprintf('Namespace "%s" does not contain any mapped entities.', $namespace));
}
$first = reset($metadatas);
$r = $first->getReflectionClass();
if (!$r) {
throw new \RuntimeException('Unable to determine where to save the "%s" class.', $class);
}
$path = $this->findBasePathForClass($namespace, $r->getNamespacename(), dirname($r->getFilename()));
return array($metadatas, $path);
}
}

View File

@ -15,9 +15,7 @@ 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\ORM\Tools\Export\ClassMetadataExporter;
use Doctrine\ORM\Tools\EntityGenerator;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
/**
@ -32,21 +30,24 @@ class GenerateEntityDoctrineCommand extends DoctrineCommand
{
$this
->setName('doctrine:generate:entity')
->setDescription('Generate a new Doctrine entity inside a bundle.')
->addArgument('bundle', InputArgument::REQUIRED, 'The bundle to initialize the entity in.')
->addArgument('entity', InputArgument::REQUIRED, 'The entity class to initialize.')
->addOption('mapping-type', null, InputOption::VALUE_OPTIONAL, 'The mapping type to to use for the entity.', 'xml')
->addOption('fields', null, InputOption::VALUE_OPTIONAL, 'The fields to create with the new entity.')
->setDescription('Generate a new Doctrine entity inside a bundle')
->addArgument('bundle', InputArgument::REQUIRED, 'The bundle to initialize the entity in')
->addArgument('entity', InputArgument::REQUIRED, 'The entity class to initialize')
->addOption('mapping-type', null, InputOption::VALUE_OPTIONAL, 'The mapping type to to use for the entity', 'xml')
->addOption('fields', null, InputOption::VALUE_OPTIONAL, 'The fields to create with the new entity')
->setHelp(<<<EOT
The <info>doctrine:generate:entity</info> task initializes a new Doctrine entity inside a bundle:
The <info>doctrine:generate:entity</info> task initializes a new Doctrine
entity inside a bundle:
<info>./app/console doctrine:generate:entity "MyCustomBundle" "User\Group"</info>
<info>./app/console doctrine:generate:entity "MyCustomBundle" "User\Group"</info>
The above would initialize a new entity in the following entity namespace <info>Bundle\MyCustomBundle\Entity\User\Group</info>.
The above would initialize a new entity in the following entity namespace
<info>Bundle\MyCustomBundle\Entity\User\Group</info>.
You can also optionally specify the fields you want to generate in the new entity:
You can also optionally specify the fields you want to generate in the new
entity:
<info>./app/console doctrine:generate:entity "MyCustomBundle" "User\Group" --fields="name:string(255) description:text"</info>
<info>./app/console doctrine:generate:entity "MyCustomBundle" "User\Group" --fields="name:string(255) description:text"</info>
EOT
);
}

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\DoctrineBundle\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\ORM\Tools\EntityRepositoryGenerator;
/**
* Command to generate repository classes for mapping information.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jonathan H. Wage <jonwage@gmail.com>
*/
class GenerateRepositoriesDoctrineCommand extends DoctrineCommand
{
protected function configure()
{
$this
->setName('doctrine:generate:repositories')
->setDescription('Generate repository classes from your mapping information.')
->addArgument('bundle', InputArgument::REQUIRED, 'The bundle to initialize the repositories in.')
->addOption('entity', null, InputOption::VALUE_OPTIONAL, 'The entity class to generate the repository for (shortname without namespace).')
->setHelp(<<<EOT
The <info>doctrine:generate:repositories</info> command generates the configured entity repository classes from your mapping information:
<info>./app/console doctrine:generate:repositories</info>
EOT
);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$bundleName = $input->getArgument('bundle');
$filterEntity = $input->getOption('entity');
$foundBundle = $this->getApplication()->getKernel()->getBundle($bundleName);
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;
}
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->writeEntityRepositoryClass($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 entities.");
}
}
}

View File

@ -15,10 +15,6 @@ 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\ORM\Tools\Console\Command\ConvertMappingCommand;
use Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper;
use Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper;
use Doctrine\ORM\Mapping\Driver\DatabaseDriver;
use Doctrine\ORM\Tools\DisconnectedClassMetadataFactory;
use Doctrine\ORM\Tools\Export\ClassMetadataExporter;
@ -35,18 +31,20 @@ class ImportMappingDoctrineCommand extends DoctrineCommand
{
$this
->setName('doctrine:mapping:import')
->addArgument('bundle', InputArgument::REQUIRED, 'The bundle to import the mapping information to.')
->addArgument('mapping-type', InputArgument::OPTIONAL, 'The mapping type to export the imported mapping information to.')
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command.')
->setDescription('Import mapping information from an existing database.')
->addArgument('bundle', InputArgument::REQUIRED, 'The bundle to import the mapping information to')
->addArgument('mapping-type', InputArgument::OPTIONAL, 'The mapping type to export the imported mapping information to')
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command')
->setDescription('Import mapping information from an existing database')
->setHelp(<<<EOT
The <info>doctrine:mapping:import</info> command imports mapping information from an existing database:
The <info>doctrine:mapping:import</info> command imports mapping information
from an existing database:
<info>./app/console doctrine:mapping:import "MyCustomBundle" xml</info>
<info>./app/console doctrine:mapping:import "MyCustomBundle" xml</info>
You can also optionally specify which entity manager to import from with the <info>--em</info> option:
You can also optionally specify which entity manager to import from with the
<info>--em</info> option:
<info>./app/console doctrine:mapping:import "MyCustomBundle" xml --em=default</info>
<info>./app/console doctrine:mapping:import "MyCustomBundle" xml --em=default</info>
EOT
);
}
@ -74,7 +72,8 @@ EOT
$exporter->setEntityGenerator($entityGenerator);
}
$em = $this->getEntityManager($this->container, $input->getOption('em'));
$em = $this->getEntityManager($input->getOption('em'));
$databaseDriver = new DatabaseDriver($em->getConnection()->getSchemaManager());
$em->getConfiguration()->setMetadataDriverImpl($databaseDriver);
@ -102,7 +101,8 @@ EOT
file_put_contents($path, $code);
}
} else {
$output->writeln('Database does not have any mapping information.'.PHP_EOL, 'ERROR');
$output->writeln('Database does not have any mapping information.', 'ERROR');
$output->writeln('', 'ERROR');
}
}
}

View File

@ -12,7 +12,6 @@
namespace Symfony\Bundle\DoctrineBundle\Command;
use Doctrine\ORM\Mapping\MappingException;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
@ -28,31 +27,29 @@ class InfoDoctrineCommand extends DoctrineCommand
{
$this
->setName('doctrine:mapping:info')
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command.')
->setDescription('Show basic information about all mapped entities.')
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command')
->setDescription('Show basic information about all mapped entities')
->setHelp(<<<EOT
The <info>doctrine:mapping:info</info> shows basic information about which
entities exist and possibly if their mapping information contains errors or not.
entities exist and possibly if their mapping information contains errors or
not.
<info>./app/console doctrine:mapping:info</info>
<info>./app/console doctrine:mapping:info</info>
If you are using multiple entity managers you can pick your choice with the <info>--em</info> option:
If you are using multiple entity managers you can pick your choice with the
<info>--em</info> option:
<info>./app/console doctrine:mapping:info --em=default</info>
<info>./app/console doctrine:mapping:info --em=default</info>
EOT
);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$entityManagerName = $input->getOption('em') ?
$input->getOption('em') :
$this->container->getParameter('doctrine.orm.default_entity_manager');
$entityManagerService = sprintf('doctrine.orm.%s_entity_manager', $entityManagerName);
$entityManagerName = $input->getOption('em') ? $input->getOption('em') : $this->container->getParameter('doctrine.orm.default_entity_manager');
/* @var $entityManager Doctrine\ORM\EntityManager */
$entityManager = $this->container->get($entityManagerService);
$entityManager = $this->getEntityManager($input->getOption('em'));
$entityClassNames = $entityManager->getConfiguration()
->getMetadataDriverImpl()
@ -67,18 +64,17 @@ EOT
);
}
$output->write(sprintf("Found <info>%d</info> entities mapped in entity manager <info>%s</info>:\n",
count($entityClassNames), $entityManagerName), true);
$output->writeln(sprintf("Found <info>%d</info> entities mapped in entity manager <info>%s</info>:", count($entityClassNames), $entityManagerName));
foreach ($entityClassNames as $entityClassName) {
try {
$cm = $entityManager->getClassMetadata($entityClassName);
$output->write("<info>[OK]</info> " . $entityClassName, true);
$output->writeln(sprintf("<info>[OK]</info> %s", $entityClassName));
} catch (MappingException $e) {
$output->write("<error>[FAIL]</error> " . $entityClassName, true);
$output->write("<comment>" . $e->getMessage()."</comment>", true);
$output->write("", true);
$output->writeln("<error>[FAIL]</error> ".$entityClassName);
$output->writeln(sprintf("<comment>%s</comment>", $e->getMessage()));
$output->writeln('');
}
}
}
}
}

View File

@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\DoctrineBundle\Command;
namespace Symfony\Bundle\DoctrineBundle\Command\Proxy;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
@ -30,23 +30,25 @@ class ClearMetadataCacheDoctrineCommand extends MetadataCommand
$this
->setName('doctrine:cache:clear-metadata')
->setDescription('Clear all metadata cache for a entity manager.')
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command.')
->setDescription('Clear all metadata cache for a entity manager')
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command')
->setHelp(<<<EOT
The <info>doctrine:cache:clear-metadata</info> command clears all metadata cache for the default entity manager:
The <info>doctrine:cache:clear-metadata</info> command clears all metadata
cache for the default entity manager:
<info>./app/console doctrine:cache:clear-metadata</info>
<info>./app/console doctrine:cache:clear-metadata</info>
You can also optionally specify the <comment>--em</comment> option to specify which entity manager to clear the cache for:
You can also optionally specify the <comment>--em</comment> option to specify
which entity manager to clear the cache for:
<info>./app/console doctrine:cache:clear-metadata --em=default</info>
<info>./app/console doctrine:cache:clear-metadata --em=default</info>
EOT
);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
DoctrineCommand::setApplicationEntityManager($this->getApplication(), $input->getOption('em'));
DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em'));
return parent::execute($input, $output);
}

View File

@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\DoctrineBundle\Command;
namespace Symfony\Bundle\DoctrineBundle\Command\Proxy;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
@ -30,23 +30,25 @@ class ClearQueryCacheDoctrineCommand extends QueryCommand
$this
->setName('doctrine:cache:clear-query')
->setDescription('Clear all query cache for a entity manager.')
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command.')
->setDescription('Clear all query cache for a entity manager')
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command')
->setHelp(<<<EOT
The <info>doctrine:cache:clear-query</info> command clears all query cache for the default entity manager:
The <info>doctrine:cache:clear-query</info> command clears all query cache for
the default entity manager:
<info>./app/console doctrine:cache:clear-query</info>
<info>./app/console doctrine:cache:clear-query</info>
You can also optionally specify the <comment>--em</comment> option to specify which entity manager to clear the cache for:
You can also optionally specify the <comment>--em</comment> option to specify
which entity manager to clear the cache for:
<info>./app/console doctrine:cache:clear-query --em=default</info>
<info>./app/console doctrine:cache:clear-query --em=default</info>
EOT
);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
DoctrineCommand::setApplicationEntityManager($this->getApplication(), $input->getOption('em'));
DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em'));
return parent::execute($input, $output);
}

View File

@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\DoctrineBundle\Command;
namespace Symfony\Bundle\DoctrineBundle\Command\Proxy;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
@ -30,35 +30,40 @@ class ClearResultCacheDoctrineCommand extends ResultCommand
$this
->setName('doctrine:cache:clear-result')
->setDescription('Clear result cache for a entity manager.')
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command.')
->setDescription('Clear result cache for a entity manager')
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command')
->setHelp(<<<EOT
The <info>doctrine:cache:clear-result</info> command clears all result cache for the default entity manager:
The <info>doctrine:cache:clear-result</info> command clears all result cache
for the default entity manager:
<info>./app/console doctrine:cache:clear-result</info>
<info>./app/console doctrine:cache:clear-result</info>
You can also optionally specify the <comment>--em</comment> option to specify which entity manager to clear the cache for:
You can also optionally specify the <comment>--em</comment> option to specify
which entity manager to clear the cache for:
<info>./app/console doctrine:cache:clear-result --em=default</info>
<info>./app/console doctrine:cache:clear-result --em=default</info>
If you don't want to clear all result cache you can specify some additional options to control what cache is deleted:
If you don't want to clear all result cache you can specify some additional
options to control what cache is deleted:
<info>./app/console doctrine:cache:clear-result --id=cache_key</info>
<info>./app/console doctrine:cache:clear-result --id=cache_key</info>
Or you can specify a <comment>--regex</comment> to delete cache entries that match it:
Or you can specify a <comment>--regex</comment> to delete cache entries that
match it:
<info>./app/console doctrine:cache:clear-result --regex="user_(.*)"</info>
<info>./app/console doctrine:cache:clear-result --regex="user_(.*)"</info>
You can also specify a <comment>--prefix</comment> or <comment>--suffix</comment> to delete cache entries for:
You can also specify a <comment>--prefix</comment> or
<comment>--suffix</comment> to delete cache entries for:
<info>./app/console doctrine:cache:clear-result --prefix="user_" --suffix="_frontend"</info>
<info>./app/console doctrine:cache:clear-result --prefix="user_" --suffix="_frontend"</info>
EOT
);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
DoctrineCommand::setApplicationEntityManager($this->getApplication(), $input->getOption('em'));
DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em'));
return parent::execute($input, $output);
}

View File

@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\DoctrineBundle\Command;
namespace Symfony\Bundle\DoctrineBundle\Command\Proxy;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
@ -32,18 +32,19 @@ class ConvertMappingDoctrineCommand extends ConvertMappingCommand
parent::configure();
$this
->setName('doctrine:mapping:convert')
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command.')
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command')
->setHelp(<<<EOT
The <info>doctrine:mapping:convert</info> command converts mapping information between supported formats:
The <info>doctrine:mapping:convert</info> command converts mapping information
between supported formats:
<info>./app/console doctrine:mapping:convert xml /path/to/output</info>
<info>./app/console doctrine:mapping:convert xml /path/to/output</info>
EOT
);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
DoctrineCommand::setApplicationEntityManager($this->getApplication(), $input->getOption('em'));
DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em'));
return parent::execute($input, $output);
}

View File

@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\DoctrineBundle\Command;
namespace Symfony\Bundle\DoctrineBundle\Command\Proxy;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
@ -32,22 +32,24 @@ class CreateSchemaDoctrineCommand extends CreateCommand
$this
->setName('doctrine:schema:create')
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command.')
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command')
->setHelp(<<<EOT
The <info>doctrine:schema:create</info> command creates the default entity managers schema:
The <info>doctrine:schema:create</info> command creates the default entity
managers schema:
<info>./app/console doctrine:schema:create</info>
<info>./app/console doctrine:schema:create</info>
You can also optionally specify the name of a entity manager to create the schema for:
You can also optionally specify the name of a entity manager to create the
schema for:
<info>./app/console doctrine:schema:create --em=default</info>
<info>./app/console doctrine:schema:create --em=default</info>
EOT
);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
DoctrineCommand::setApplicationEntityManager($this->getApplication(), $input->getOption('em'));
DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em'));
parent::execute($input, $output);
}

View File

@ -0,0 +1,79 @@
<?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\DoctrineBundle\Command\Proxy;
use Symfony\Component\Console\Application;
use Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper;
use Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper;
/**
* Provides some helper and convenience methods to configure doctrine commands in the context of bundles
* and multiple connections/entity managers.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
abstract class DoctrineCommandHelper
{
/**
* Convenience method to push the helper sets of a given entity manager into the application.
*
* @param string $emName
*/
static public function setApplicationEntityManager(Application $application, $emName)
{
$em = self::getEntityManager($application, $emName);
$helperSet = $application->getHelperSet();
$helperSet->set(new ConnectionHelper($em->getConnection()), 'db');
$helperSet->set(new EntityManagerHelper($em), 'em');
}
static public function setApplicationConnection(Application $application, $connName)
{
$connection = self::getDoctrineConnection($application, $connName);
$helperSet = $application->getHelperSet();
$helperSet->set(new ConnectionHelper($connection), 'db');
}
static protected function getEntityManager(Application $application, $name)
{
$container = $application->getKernel()->getContainer();
$name = $name ?: $container->getParameter('doctrine.orm.default_entity_manager');
$ems = $container->getParameter('doctrine.orm.entity_managers');
if (!isset($ems[$name])) {
throw new \InvalidArgumentException(sprintf('Could not find Doctrine EntityManager named "%s"', $name));
}
return $container->get($ems[$name]);
}
/**
* Get a doctrine dbal connection by symfony name.
*
* @param string $name
* @return Doctrine\DBAL\Connection
*/
static protected function getDoctrineConnection(Application $application, $name)
{
$container = $application->getKernel()->getContainer();
$name = $name ?: $container->getParameter('doctrine.dbal.default_connection');
$connections = $container->getParameter('doctrine.dbal.connections');
if (!isset($connections[$name])) {
throw new \InvalidArgumentException(sprintf('<error>Could not find a connection named <comment>%s</comment></error>', $name));
}
return $container->get($connections[$name]);
}
}

View File

@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\DoctrineBundle\Command;
namespace Symfony\Bundle\DoctrineBundle\Command\Proxy;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
@ -32,22 +32,24 @@ class DropSchemaDoctrineCommand extends DropCommand
$this
->setName('doctrine:schema:drop')
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command.')
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command')
->setHelp(<<<EOT
The <info>doctrine:schema:drop</info> command drops the default entity managers schema:
The <info>doctrine:schema:drop</info> command drops the default entity
managers schema:
<info>./app/console doctrine:schema:drop</info>
<info>./app/console doctrine:schema:drop</info>
You can also optionally specify the name of a entity manager to drop the schema for:
You can also optionally specify the name of a entity manager to drop the
schema for:
<info>./app/console doctrine:schema:drop --em=default</info>
<info>./app/console doctrine:schema:drop --em=default</info>
EOT
);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
DoctrineCommand::setApplicationEntityManager($this->getApplication(), $input->getOption('em'));
DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em'));
parent::execute($input, $output);
}

View File

@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\DoctrineBundle\Command;
namespace Symfony\Bundle\DoctrineBundle\Command\Proxy;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
@ -32,22 +32,24 @@ class EnsureProductionSettingsDoctrineCommand extends EnsureProductionSettingsCo
$this
->setName('doctrine:ensure-production-settings')
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command.')
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command')
->setHelp(<<<EOT
The <info>doctrine:ensure-production-settings</info> command ensures that Doctrine is properly configured for a production environment.:
The <info>doctrine:ensure-production-settings</info> command ensures that
Doctrine is properly configured for a production environment.:
<info>./app/console doctrine:ensure-production-settings</info>
<info>./app/console doctrine:ensure-production-settings</info>
You can also optionally specify the <comment>--em</comment> option to specify which entity manager to use:
You can also optionally specify the <comment>--em</comment> option to specify
which entity manager to use:
<info>./app/console doctrine:ensure-production-settings --em=default</info>
<info>./app/console doctrine:ensure-production-settings --em=default</info>
EOT
);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
DoctrineCommand::setApplicationEntityManager($this->getApplication(), $input->getOption('em'));
DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em'));
parent::execute($input, $output);
}

View File

@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\DoctrineBundle\Command;
namespace Symfony\Bundle\DoctrineBundle\Command\Proxy;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
@ -32,22 +32,23 @@ class GenerateProxiesDoctrineCommand extends GenerateProxiesCommand
$this
->setName('doctrine:generate:proxies')
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command.')
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command')
->setHelp(<<<EOT
The <info>doctrine:generate:proxies</info> command generates proxy classes for your default entity manager:
The <info>doctrine:generate:proxies</info> command generates proxy classes for
your default entity manager:
<info>./app/console doctrine:generate:proxies</info>
<info>./app/console doctrine:generate:proxies</info>
You can specify the entity manager you want to generate the proxies for:
<info>./app/console doctrine:generate:proxies --em=name</info>
<info>./app/console doctrine:generate:proxies --em=name</info>
EOT
);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
DoctrineCommand::setApplicationEntityManager($this->getApplication(), $input->getOption('em'));
DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em'));
return parent::execute($input, $output);
}

View File

@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\DoctrineBundle\Command;
namespace Symfony\Bundle\DoctrineBundle\Command\Proxy;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
@ -32,26 +32,29 @@ class RunDqlDoctrineCommand extends RunDqlCommand
$this
->setName('doctrine:query:dql')
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command.')
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command')
->setHelp(<<<EOT
The <info>doctrine:query:dql</info> command executes the given DQL query and outputs the results:
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 UserBundle: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:
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 UserBundle: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:
Additionally you can specify the first result and maximum amount of results to
show:
<info>./app/console doctrine:query:dql "SELECT u FROM UserBundle: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
);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
DoctrineCommand::setApplicationEntityManager($this->getApplication(), $input->getOption('em'));
DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em'));
return parent::execute($input, $output);
}

View File

@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\DoctrineBundle\Command;
namespace Symfony\Bundle\DoctrineBundle\Command\Proxy;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
@ -32,19 +32,20 @@ class RunSqlDoctrineCommand extends RunSqlCommand
$this
->setName('doctrine:query:sql')
->addOption('connection', null, InputOption::VALUE_OPTIONAL, 'The connection to use for this command.')
->addOption('connection', null, InputOption::VALUE_OPTIONAL, 'The connection to use for this command')
->setHelp(<<<EOT
The <info>doctrine:query:sql</info> command executes the given DQL query and outputs the results:
The <info>doctrine:query:sql</info> command executes the given DQL query and
outputs the results:
<info>./app/console doctrine:query:sql "SELECT * from user"</info>
<info>./app/console doctrine:query:sql "SELECT * from user"</info>
EOT
);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
DoctrineCommand::setApplicationConnection($this->getApplication(), $input->getOption('connection'));
DoctrineCommandHelper::setApplicationConnection($this->getApplication(), $input->getOption('connection'));
return parent::execute($input, $output);
}
}
}

View File

@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\DoctrineBundle\Command;
namespace Symfony\Bundle\DoctrineBundle\Command\Proxy;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
@ -32,22 +32,24 @@ class UpdateSchemaDoctrineCommand extends UpdateCommand
$this
->setName('doctrine:schema:update')
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command.')
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command')
->setHelp(<<<EOT
The <info>doctrine:schema:update</info> command updates the default entity managers schema:
The <info>doctrine:schema:update</info> command updates the default entity
managers schema:
<info>./app/console doctrine:schema:update</info>
<info>./app/console doctrine:schema:update</info>
You can also optionally specify the name of a entity manager to update the schema for:
You can also optionally specify the name of a entity manager to update the
schema for:
<info>./app/console doctrine:schema:update --em=default</info>
<info>./app/console doctrine:schema:update --em=default</info>
EOT
);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
DoctrineCommand::setApplicationEntityManager($this->getApplication(), $input->getOption('em'));
DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em'));
parent::execute($input, $output);
}

View File

@ -23,10 +23,14 @@ use Symfony\Bundle\DoctrineBundle\Logger\DbalLogger;
*/
class DoctrineDataCollector extends DataCollector
{
protected $logger;
private $connections;
private $managers;
private $logger;
public function __construct(DbalLogger $logger = null)
public function __construct($connections, $managers, DbalLogger $logger = null)
{
$this->connections = $connections;
$this->managers = $managers;
$this->logger = $logger;
}
@ -36,10 +40,22 @@ class DoctrineDataCollector extends DataCollector
public function collect(Request $request, Response $response, \Exception $exception = null)
{
$this->data = array(
'queries' => null !== $this->logger ? $this->logger->queries : array(),
'queries' => null !== $this->logger ? $this->logger->queries : array(),
'connections' => $this->connections,
'managers' => $this->managers,
);
}
public function getManagers()
{
return $this->data['managers'];
}
public function getConnections()
{
return $this->data['connections'];
}
public function getQueryCount()
{
return count($this->data['queries']);

View File

@ -40,7 +40,7 @@ class RegisterEventListenersAndSubscribersPass implements CompilerPassInterface
}
foreach ($connections as $name) {
$this->getEventManager($name)->addMethodCall('addEventSubscriber', array(new Reference($subscriberId)));
$this->getEventManager($name, $subscriberId)->addMethodCall('addEventSubscriber', array(new Reference($subscriberId)));
}
}
@ -59,7 +59,7 @@ class RegisterEventListenersAndSubscribersPass implements CompilerPassInterface
}
foreach ($cs as $connection) {
if (!is_array($connections[$connection])) {
if (!isset($connections[$connection]) || !is_array($connections[$connection])) {
$connections[$connection] = array();
}
$connections[$connection][] = $attributes['event'];
@ -67,14 +67,14 @@ class RegisterEventListenersAndSubscribersPass implements CompilerPassInterface
}
foreach ($connections as $name => $events) {
$this->getEventManager($name)->addMethodCall('addEventListener', array(
$this->getEventManager($name, $listenerId)->addMethodCall('addEventListener', array(
array_unique($events),
new Reference($listenerId),
));
}
}
private function getEventManager($name)
private function getEventManager($name, $listenerId = null)
{
if (null === $this->eventManagers) {
$this->eventManagers = array();

View File

@ -224,11 +224,13 @@ class Configuration implements ConfigurationInterface
->prototype('array')
->beforeNormalization()
->ifString()
->then(function($v) { return array ('type' => $v); })
->then(function($v) { return array('type' => $v); })
->end()
->treatNullLike(array ())
->treatNullLike(array())
->treatFalseLike(array('mapping' => false))
->performNoDeepMerging()
->children()
->scalarNode('mapping')->defaultValue(true)->end()
->scalarNode('type')->end()
->scalarNode('dir')->end()
->scalarNode('alias')->end()
@ -272,7 +274,7 @@ class Configuration implements ConfigurationInterface
->addDefaultsIfNotSet()
->beforeNormalization()
->ifString()
->then(function($v) { return array ('type' => $v); })
->then(function($v) { return array('type' => $v); })
->end()
->children()
->scalarNode('type')->defaultValue('array')->isRequired()->end()

View File

@ -99,7 +99,7 @@ class DoctrineExtension extends AbstractDoctrineExtension
}
// event manager
$container->setDefinition(sprintf('doctrine.dbal.%s_connection.event_manager', $name), new DefinitionDecorator('doctrine.dbal.connection.event_manager'));
$def = $container->setDefinition(sprintf('doctrine.dbal.%s_connection.event_manager', $name), new DefinitionDecorator('doctrine.dbal.connection.event_manager'));
// connection
if (isset($connection['charset'])) {
@ -230,7 +230,6 @@ class DoctrineExtension extends AbstractDoctrineExtension
$ormEmDef = new Definition('%doctrine.orm.entity_manager.class%', $ormEmArgs);
$ormEmDef->setFactoryClass('%doctrine.orm.entity_manager.class%');
$ormEmDef->setFactoryMethod('create');
$ormEmDef->addTag('doctrine.orm.entity_manager');
$container->setDefinition($entityManagerService, $ormEmDef);
$container->setAlias(

View File

@ -26,6 +26,8 @@
<service id="data_collector.doctrine" class="%doctrine.data_collector.class%" public="false">
<tag name="data_collector" template="DoctrineBundle:Collector:db" id="db" />
<argument>%doctrine.dbal.connections%</argument>
<argument>%doctrine.orm.entity_managers%</argument>
<argument type="service" id="doctrine.dbal.logger" />
</service>
@ -35,8 +37,8 @@
<service id="doctrine.dbal.connection" class="%doctrine.dbal.connection.class%" factory-service="doctrine.dbal.connection_factory" factory-method="createConnection" abstract="true" />
<service id="doctrine.dbal.connection.event_manager" class="%doctrine.dbal.connection.event_manager.class%" abstract="true" />
<service id="doctrine.dbal.connection.event_manager" class="%doctrine.dbal.connection.event_manager.class%" public="false" abstract="true" />
<service id="doctrine.dbal.connection.configuration" class="%doctrine.dbal.configuration.class%" abstract="true" />
<service id="doctrine.dbal.connection.configuration" class="%doctrine.dbal.configuration.class%" public="false" abstract="true" />
</services>
</container>

View File

@ -28,7 +28,7 @@
<!-- cache warmer -->
<parameter key="doctrine.orm.proxy_cache_warmer.class">Symfony\Bundle\DoctrineBundle\CacheWarmer\ProxyCacheWarmer</parameter>
<!-- form field factory guesser -->
<parameter key="form.type_guesser.doctrine.class">Symfony\Bridge\Doctrine\Form\DoctrineOrmTypeGuesser</parameter>
</parameters>
@ -43,17 +43,17 @@
<tag name="kernel.cache_warmer" />
<argument type="service" id="service_container" />
</service>
<service id="form.type_guesser.doctrine" class="%form.type_guesser.doctrine.class%">
<tag name="form.type_guesser" />
<argument type="service" id="doctrine.orm.entity_manager" />
</service>
<service id="form.type.entity" class="Symfony\Bridge\Doctrine\Form\Type\EntityType">
<tag name="form.type" alias="entity" />
<argument type="service" id="doctrine.orm.entity_manager" />
</service>
<service id="doctrine.orm.configuration" class="%doctrine.orm.configuration.class%" abstract="true" />
<service id="doctrine.orm.configuration" class="%doctrine.orm.configuration.class%" abstract="true" public="false" />
</services>
</container>

View File

@ -43,4 +43,46 @@
{% endfor %}
</ul>
{% endif %}
<h2>Database Connections</h2>
{% if collector.connections %}
<table>
<tr>
<th>Name</th>
<th>Service</th>
</tr>
{% for name, service in collector.connections %}
<tr>
<th>{{ name }}</th>
<td>{{ service }}</td>
</tr>
{% endfor %}
</table>
{% else %}
<p>
<em>No entity managers.</em>
</p>
{% endif %}
<h2>Entity Managers</h2>
{% if collector.managers %}
<table>
<tr>
<th>Name</th>
<th>Service</th>
</tr>
{% for name, service in collector.managers %}
<tr>
<th>{{ name }}</th>
<td>{{ service }}</td>
</tr>
{% endfor %}
</table>
{% else %}
<p>
<em>No entity managers.</em>
</p>
{% endif %}
{% endblock %}

View File

@ -1,56 +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\DoctrineBundle\Tests\Command;
use Symfony\Bundle\DoctrineBundle\Tests\TestCase;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\DoctrineBundle\Command\DoctrineCommand;
class DoctrineCommandTest extends TestCase
{
private $em;
public function testSetApplicationEntityManager()
{
$kernel = $this->createKernelMock('test');
$application = new Application($kernel);
DoctrineCommand::setApplicationEntityManager($application, 'test');
$this->assertTrue($application->getHelperSet()->has('em'));
$this->assertTrue($application->getHelperSet()->has('db'));
}
public function testSetApplicationConnection()
{
$kernel = $this->createKernelMock('test');
$application = new Application($kernel);
DoctrineCommand::setApplicationConnection($application, 'test');
$this->assertFalse($application->getHelperSet()->has('em'));
$this->assertTrue($application->getHelperSet()->has('db'));
}
public function createKernelMock($name)
{
$this->em = $this->createTestEntityManager();
$kernel = $this->getMock('Symfony\Component\HttpKernel\KernelInterface');
$container = new \Symfony\Component\DependencyInjection\Container();
$container->set(sprintf('doctrine.orm.%s_entity_manager', $name), $this->em);
$container->set(sprintf('doctrine.dbal.%s_connection', $name), $this->em->getConnection());
$kernel->expects($this->once())->method('getContainer')->will($this->returnValue($container));
$kernel->expects($this->once())->method('getBundles')->will($this->returnValue(array()));
return $kernel;
}
}

View File

@ -16,17 +16,14 @@ class InfoDoctrineCommandTest extends TestCase
$input = new StringInput("doctrine:mapping:info");
$output = $this->getMock('Symfony\Component\Console\Output\OutputInterface');
$output->expects($this->at(0))
->method('write')
->with($this->equalTo("Found <info>1</info> entities mapped in entity manager <info>default</info>:\n"), $this->equalTo(true));
->method('writeln')
->with($this->equalTo("Found <info>1</info> entities mapped in entity manager <info>default</info>:"));
$output->expects($this->at(1))
->method('write')
->with($this->equalTo("<info>[OK]</info> Fixtures\Bundles\YamlBundle\Entity\Test"), $this->equalTo(true));
->method('writeln')
->with($this->equalTo("<info>[OK]</info> Fixtures\Bundles\YamlBundle\Entity\Test"));
$testContainer = $this->createYamlBundleTestContainer();
$kernel = $this->getMock('Symfony\Component\HttpKernel\Kernel', array(), array(), '', false);
$kernel->expects($this->once())
->method('getBundles')
->will($this->returnValue(array()));
$kernel->expects($this->once())
->method('getContainer')
->will($this->returnValue($testContainer));
@ -36,4 +33,4 @@ class InfoDoctrineCommandTest extends TestCase
$cmd->setApplication($application);
$cmd->run($input, $output);
}
}
}

View File

@ -154,7 +154,6 @@ abstract class AbstractDoctrineExtensionTest extends TestCase
$this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
$this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getFactoryClass());
$this->assertEquals('create', $definition->getFactoryMethod());
$this->assertArrayHasKey('doctrine.orm.entity_manager', $definition->getTags());
$this->assertEquals(array('default' => 'doctrine.orm.default_entity_manager'), $container->getParameter('doctrine.orm.entity_managers'), "Set of the existing EntityManagers names is incorrect.");
@ -196,7 +195,6 @@ abstract class AbstractDoctrineExtensionTest extends TestCase
$this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
$this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getFactoryClass());
$this->assertEquals('create', $definition->getFactoryMethod());
$this->assertArrayHasKey('doctrine.orm.entity_manager', $definition->getTags());
$this->assertDICConstructorArguments($definition, array(
new Reference('database_connection'), new Reference('doctrine.orm.default_configuration')
@ -235,7 +233,6 @@ abstract class AbstractDoctrineExtensionTest extends TestCase
$this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
$this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getFactoryClass());
$this->assertEquals('create', $definition->getFactoryMethod());
$this->assertArrayHasKey('doctrine.orm.entity_manager', $definition->getTags());
$this->assertDICConstructorArguments($definition, array(
new Reference('database_connection'), new Reference('doctrine.orm.default_configuration')
@ -275,7 +272,6 @@ abstract class AbstractDoctrineExtensionTest extends TestCase
$this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
$this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getFactoryClass());
$this->assertEquals('create', $definition->getFactoryMethod());
$this->assertArrayHasKey('doctrine.orm.entity_manager', $definition->getTags());
$this->assertDICConstructorArguments($definition, array(
new Reference('doctrine.dbal.default_connection'), new Reference('doctrine.orm.default_configuration')
@ -308,7 +304,6 @@ abstract class AbstractDoctrineExtensionTest extends TestCase
$this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
$this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getFactoryClass());
$this->assertEquals('create', $definition->getFactoryMethod());
$this->assertArrayHasKey('doctrine.orm.entity_manager', $definition->getTags());
$arguments = $definition->getArguments();
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[0]);
@ -330,7 +325,6 @@ abstract class AbstractDoctrineExtensionTest extends TestCase
$this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
$this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getFactoryClass());
$this->assertEquals('create', $definition->getFactoryMethod());
$this->assertArrayHasKey('doctrine.orm.entity_manager', $definition->getTags());
$arguments = $definition->getArguments();
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $arguments[0]);

View File

@ -16,9 +16,11 @@ 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\Bundle\FrameworkBundle\DependencyInjection\Compiler\ContainerBuilderDebugDumpPass;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
/**
* A console command for retrieving information about services
@ -28,7 +30,7 @@ use Symfony\Component\DependencyInjection\Definition;
class ContainerDebugCommand extends Command
{
/**
* @var \Symfony\Component\DependencyInjection\ContainerBuilder
* @var ContainerBuilder
*/
private $containerBuilder;
@ -78,8 +80,7 @@ EOF
if ($name) {
$this->outputService($output, $name);
} else {
$showPrivate = $input->getOption('show-private');
$this->outputServices($output, $serviceIds, $showPrivate);
$this->outputServices($output, $serviceIds, $input->getOption('show-private'));
}
}
@ -94,7 +95,7 @@ EOF
$output->writeln($this->getHelper('formatter')->formatSection('container', $label));
// loop through to find get space needed and filter private services
// loop through to get space needed and filter private services
$maxName = 4;
$maxScope = 6;
foreach ($serviceIds as $key => $serviceId) {
@ -174,18 +175,24 @@ EOF
/**
* Loads the ContainerBuilder from the cache.
*
* @see ContainerBuilderDebugDumpPass
* @return \Symfony\Component\DependencyInjection\ContainerBuilder
* @return ContainerBuilder
*/
private function getContainerBuilder()
{
$cachedFile = ContainerBuilderDebugDumpPass::getBuilderCacheFilename($this->container);
if (!$this->getApplication()->getKernel()->isDebug()) {
throw new \LogicException(sprintf('Debug information about the container is only available in debug mode.'));
}
if (!file_exists($cachedFile)) {
if (!file_exists($cachedFile = $this->container->getParameter('debug.container.dump'))) {
throw new \LogicException(sprintf('Debug information about the container could not be found. Please clear the cache and try again.'));
}
return unserialize(file_get_contents($cachedFile));
$container = new ContainerBuilder();
$loader = new XmlFileLoader($container, new FileLocator());
$loader->load($cachedFile);
return $container;
}
/**

View File

@ -41,10 +41,6 @@ class Application extends BaseApplication
$this->getDefinition()->addOption(new InputOption('--shell', '-s', InputOption::VALUE_NONE, 'Launch the shell.'));
$this->getDefinition()->addOption(new InputOption('--env', '-e', InputOption::VALUE_REQUIRED, 'The Environment name.', 'dev'));
$this->getDefinition()->addOption(new InputOption('--no-debug', null, InputOption::VALUE_NONE, 'Switches off debug mode.'));
$this->kernel->boot();
$this->registerCommands();
}
/**
@ -67,6 +63,8 @@ class Application extends BaseApplication
*/
public function doRun(InputInterface $input, OutputInterface $output)
{
$this->registerCommands();
if (true === $input->hasParameterOption(array('--shell', '-s'))) {
$shell = new Shell($this);
$shell->run();
@ -79,8 +77,9 @@ class Application extends BaseApplication
protected function registerCommands()
{
$this->kernel->boot();
foreach ($this->kernel->getBundles() as $bundle) {
$bundle->registerCommands($this);
}
}
}
}

View File

@ -12,7 +12,7 @@
namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Dumper\XmlDumper;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\Config\ConfigCache;
@ -27,22 +27,8 @@ class ContainerBuilderDebugDumpPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$cache = new ConfigCache(self::getBuilderCacheFilename($container), false);
$cache->write(serialize($container));
}
/**
* Calculates the cache filename to be used to cache the ContainerBuilder
*
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
*
* @return string
*/
static public function getBuilderCacheFilename(ContainerInterface $container)
{
$class = $container->getParameter('kernel.container_class');
return $container->getParameter('kernel.cache_dir').'/'.$class.'Builder.cache';
$dumper = new XmlDumper($container);
$cache = new ConfigCache($container->getParameter('debug.container.dump'), false);
$cache->write($dumper->dump());
}
}

View File

@ -23,7 +23,6 @@ class RegisterKernelListenersPass implements CompilerPassInterface
return;
}
$listeners = array();
$definition = $container->getDefinition('event_dispatcher');
foreach ($container->findTaggedServiceIds('kernel.listener') as $id => $events) {

View File

@ -449,7 +449,6 @@ class FrameworkExtension extends Extension
}
// Register translation resources
$resources = array();
if ($dirs) {
$finder = new Finder();
$finder->files()->filter(function (\SplFileInfo $file) { return 2 === substr_count($file->getBasename(), '.'); })->in($dirs);

View File

@ -60,7 +60,7 @@ class FrameworkBundle extends Bundle
$container->addCompilerPass(new AddCacheWarmerPass());
if ($container->getParameter('kernel.debug')) {
$container->addCompilerPass(new ContainerBuilderDebugDumpPass(), PassConfig::TYPE_BEFORE_REMOVING);
$container->addCompilerPass(new ContainerBuilderDebugDumpPass(), PassConfig::TYPE_AFTER_REMOVING);
$container->addCompilerPass(new CompilerDebugDumpPass(), PassConfig::TYPE_AFTER_REMOVING);
}
}

View File

@ -82,8 +82,6 @@ class ProfilerListener
*/
public function onCoreResponse(FilterResponseEvent $event)
{
$response = $event->getResponse();
if ($this->onlyMasterRequests && HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
return;
}

View File

@ -6,6 +6,7 @@
<parameters>
<parameter key="debug.event_dispatcher.class">Symfony\Bundle\FrameworkBundle\Debug\TraceableEventDispatcher</parameter>
<parameter key="debug.container.dump">%kernel.cache_dir%/%kernel.container_class%.xml</parameter>
</parameters>
<services>

View File

@ -10,7 +10,7 @@
</parameters>
<services>
<service id="esi" class="%esi.class%" public="false" />
<service id="esi" class="%esi.class%" />
<service id="esi_listener" class="%esi_listener.class%">
<tag name="kernel.listener" event="onCoreResponse" />

View File

@ -1,7 +1,7 @@
<ol class="traces">
{% for log in logs %}
<li>
{% if 'ERR' == log.priorityName %}
{% if log.priorityName in ['EMERG', 'ERR', 'CRIT', 'ALERT', 'ERROR', 'CRITICAL'] %}
<em>{{ log.priorityName }}</em>
{% else %}
{{ log.priorityName }}
@ -10,4 +10,4 @@
{{ log.message }}
</li>
{% endfor %}
</ol>
</ol>

View File

@ -12,6 +12,7 @@
namespace Symfony\Bundle\FrameworkBundle\Routing;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Routing\RequestContext;
/**
* This Router is optimized to work with matcher and generator classes
@ -51,9 +52,9 @@ class CachedRouter implements RouterInterface
/**
* Sets the request context.
*
* @param array $context The context
* @param RequestContext $context The context
*/
public function setContext(array $context = array())
public function setContext(RequestContext $context)
{
$this->matcher->setContext($context);
$this->generator->setContext($context);

View File

@ -55,7 +55,6 @@ abstract class WebTestCase extends BaseWebTestCase
*/
protected function getPhpUnitXmlDir()
{
$dir = null;
if (!isset($_SERVER['argv']) || false === strpos($_SERVER['argv'][0], 'phpunit')) {
throw new \RuntimeException('You must override the WebTestCase::createKernel() method.');
}

View File

@ -35,7 +35,7 @@ class PhpEngineTest extends TestCase
{
$container = new Container();
$loader = $this->getMockForAbstractClass('Symfony\Component\Templating\Loader\Loader');
$engine = new PhpEngine(new TemplateNameParser(), $container, $loader, $app = new GlobalVariables($container));
$engine = new PhpEngine(new TemplateNameParser(), $container, $loader, new GlobalVariables($container));
$container->set('request', null);

View File

@ -34,7 +34,7 @@ use Symfony\Component\Validator\ConstraintValidatorFactoryInterface;
* return 'some_alias';
* }
*
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Kris Wallsmith <kris@symfony.com>
*/
class ConstraintValidatorFactory implements ConstraintValidatorFactoryInterface
{

View File

@ -11,6 +11,7 @@
namespace Symfony\Bundle\MonologBundle\Logger;
use Monolog\Logger as MonologLogger;
use Monolog\Handler\TestHandler;
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
@ -35,6 +36,7 @@ class DebugHandler extends TestHandler implements DebugLoggerInterface
'priorityName' => $record['level_name'],
);
}
return $records;
}
@ -43,8 +45,13 @@ class DebugHandler extends TestHandler implements DebugLoggerInterface
*/
public function countErrors()
{
return isset($this->recordsByLevel[\Monolog\Logger::ERROR])
? count($this->recordsByLevel[\Monolog\Logger::ERROR])
: 0;
$cnt = 0;
foreach (array(MonologLogger::ERROR, MonologLogger::CRITICAL, MonologLogger::ALERT) as $level) {
if (isset($this->recordsByLevel[$level])) {
$cnt += count($this->recordsByLevel[$level]);
}
}
return $cnt;
}
}

View File

@ -36,15 +36,19 @@
<xsd:simpleType name="level">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="error" />
<xsd:enumeration value="warning" />
<xsd:enumeration value="info" />
<xsd:enumeration value="debug" />
<xsd:enumeration value="info" />
<xsd:enumeration value="warning" />
<xsd:enumeration value="error" />
<xsd:enumeration value="critical" />
<xsd:enumeration value="alert" />
<xsd:enumeration value="100" />
<xsd:enumeration value="200" />
<xsd:enumeration value="300" />
<xsd:enumeration value="400" />
<xsd:enumeration value="500" />
<xsd:enumeration value="550" />
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>

View File

@ -244,7 +244,6 @@ class SecurityExtension extends Extension
// Register listeners
$listeners = array();
$providers = array();
// Channel listener
$listeners[] = new Reference('security.channel_listener');

View File

@ -23,10 +23,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
class TwigExtensionTest extends TestCase
{
/**
* @dataProvider getFormats
*/
public function testLoadEmptyConfiguration($format)
public function testLoadEmptyConfiguration()
{
$container = $this->createContainer();
$container->registerExtension(new TwigExtension());

View File

@ -209,7 +209,7 @@ class ProfilerController extends ContainerAware
$profiler = $this->container->get('profiler');
$profiler->disable();
$pofiler = $profiler->loadFromToken($token);
$profiler = $profiler->loadFromToken($token);
$ip = $this->container->get('request')->query->get('ip');
$url = $this->container->get('request')->query->get('url');

View File

@ -341,6 +341,10 @@ table th.value
display: none;
}
ul.alt {
margin:10px 0 30px;
}
ul.alt li {
padding: 5px 7px;
font-size: 13px;

View File

@ -0,0 +1,75 @@
<?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\WebProfilerBundle\Tests\Controller;
use Symfony\Bundle\WebProfilerBundle\Controller\ExceptionController;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Scope;
use Symfony\Component\DependencyInjection\Definition;
class ExceptionControllerTest extends \PHPUnit_Framework_TestCase
{
protected $controller;
protected $container;
protected $flatten;
protected $kernel;
protected function setUp()
{
$this->flatten = $this->getMock('Symfony\Component\HttpKernel\Exception\FlattenException');
$this->flatten->expects($this->once())->method('getStatusCode')->will($this->returnValue(404));
$this->controller = new ExceptionController();
$this->kernel = $this->getMock('Symfony\\Component\\HttpKernel\\KernelInterface');
$this->container = $this->getContainer();
}
/**
* @dataProvider getDebugModes
*/
public function testShowActionDependingOnDebug($debug)
{
$this->container->setParameter('kernel.debug', $debug);
$this->controller->setContainer($this->container);
$this->controller->showAction($this->flatten);
}
public function getDebugModes()
{
return array(
array(true),
array(false),
);
}
private function getContainer()
{
$container = new ContainerBuilder();
$container->addScope(new Scope('request'));
$container->register('request', 'Symfony\\Component\\HttpFoundation\\Request')->setScope('request');
$container->register('templating.helper.assets', $this->getMockClass('Symfony\\Component\\Templating\\Helper\\AssetsHelper'));
$container->register('templating.helper.router', $this->getMockClass('Symfony\\Bundle\\FrameworkBundle\\Templating\\Helper\\RouterHelper'))
->addArgument(new Definition($this->getMockClass('Symfony\\Component\\Routing\\RouterInterface')));
$container->register('twig', 'Twig_Environment');
$container->register('templating.engine.twig',$this->getMockClass('Symfony\\Bundle\\TwigBundle\\TwigEngine'))
->addArgument($this->getMock('Twig_Environment'))
->addArgument($this->getMock('Symfony\\Component\\Templating\\TemplateNameParserInterface'))
->addArgument($this->getMock('Symfony\\Bundle\\FrameworkBundle\\Templating\\GlobalVariables', array(), array($this->getMock('Symfony\\Component\\DependencyInjection\\Container'))));
$container->setAlias('templating', 'templating.engine.twig');
$container->setParameter('kernel.bundles', array());
$container->setParameter('kernel.cache_dir', __DIR__);
$container->setParameter('kernel.root_dir', __DIR__);
$container->set('kernel', $this->kernel);
return $container;
}
}

View File

@ -0,0 +1,40 @@
<?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\WebProfilerBundle\Tests\DependencyInjection;
use Symfony\Bundle\WebProfilerBundle\DependencyInjection\Configuration;
use Symfony\Component\Config\Definition\Processor;
class ConfigurationTest extends \PHPUnit_Framework_TestCase
{
/**
* @dataProvider getDebugModes
*/
public function testConfigTree($options, $results)
{
$processor = new Processor();
$configuration = new Configuration(array());
$config = $processor->processConfiguration($configuration, array($options));
$this->assertEquals($results, $config);
}
public function getDebugModes()
{
return array(
array(array(), array('intercept_redirects' => false, 'toolbar' => false, 'verbose' => true)),
array(array('intercept_redirects' => true), array('intercept_redirects' => true, 'toolbar' => false, 'verbose' => true)),
array(array('intercept_redirects' => false), array('intercept_redirects' => false, 'toolbar' => false, 'verbose' => true)),
array(array('toolbar' => true), array('intercept_redirects' => false, 'toolbar' => true, 'verbose' => true)),
array(array('verbose' => false), array('intercept_redirects' => false, 'toolbar' => false, 'verbose' => false)),
);
}
}

View File

@ -0,0 +1,127 @@
<?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\WebProfilerBundle\Tests\DependencyInjection;
use Symfony\Bundle\WebProfilerBundle\DependencyInjection\WebProfilerExtension;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Parameter;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\Scope;
class WebProfilerExtensionTest extends \PHPUnit_Framework_TestCase
{
private $kernel;
/**
* @var Symfony\Component\DependencyInjection\Container $container
*/
private $container;
static public function assertSaneContainer(Container $container, $message = '')
{
$errors = array();
foreach ($container->getServiceIds() as $id) {
try {
$container->get($id);
} catch (\Exception $e) {
$errors[$id] = $e->getMessage();
}
}
self::assertEquals(array(), $errors, $message);
}
protected function setUp()
{
$this->kernel = $this->getMock('Symfony\\Component\\HttpKernel\\KernelInterface');
$this->container = new ContainerBuilder();
$this->container->addScope(new Scope('request'));
$this->container->register('request', 'Symfony\\Component\\HttpFoundation\\Request')->setScope('request');
$this->container->register('templating.helper.assets', $this->getMockClass('Symfony\\Component\\Templating\\Helper\\AssetsHelper'));
$this->container->register('templating.helper.router', $this->getMockClass('Symfony\\Bundle\\FrameworkBundle\\Templating\\Helper\\RouterHelper'))
->addArgument(new Definition($this->getMockClass('Symfony\\Component\\Routing\\RouterInterface')));
$this->container->register('twig', 'Twig_Environment');
$this->container->register('templating.engine.twig', $this->getMockClass('Symfony\\Bundle\\TwigBundle\\TwigEngine'))
->addArgument(new Definition($this->getMockClass('Twig_Environment')))
->addArgument(new Definition($this->getMockClass('Symfony\\Component\\Templating\\TemplateNameParserInterface')))
->addArgument(new Definition($this->getMockClass('Symfony\\Bundle\\FrameworkBundle\\Templating\\GlobalVariables'), array(new Definition($this->getMockClass('Symfony\\Component\\DependencyInjection\\Container')))));
$this->container->setParameter('kernel.bundles', array());
$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);
}
/**
* @dataProvider getDebugModes
*/
public function testDefaultConfig($debug)
{
$this->container->setParameter('kernel.debug', $debug);
$extension = new WebProfilerExtension();
$extension->load(array(array()), $this->container);
$this->assertFalse($this->container->has('web_profiler.debug.toolbar'));
$this->assertSaneContainer($this->getDumpedContainer());
}
/**
* @dataProvider getDebugModes
*/
public function testToolbarConfig($debug)
{
$this->container->setParameter('kernel.debug', $debug);
$extension = new WebProfilerExtension();
$extension->load(array(array('toolbar' => $debug)), $this->container);
$this->assertTrue($debug === $this->container->has('web_profiler.debug.toolbar'), '->load() registers web_profiler.debug.toolbar only when toolbar is true');
$this->assertSaneContainer($this->getDumpedContainer());
}
public function getDebugModes()
{
return array(
array(true),
array(false),
);
}
private function getDumpedContainer()
{
static $i = 0;
$class = 'WebProfilerExtensionTestContainer'.$i++;
$this->container->compile();
$dumper = new PhpDumper($this->container);
eval('?>'.$dumper->dump(array('class' => $class)));
$container = new $class();
$container->enterScope('request');
$container->set('kernel', $this->kernel);
return $container;
}
}

View File

@ -56,7 +56,7 @@ namespace Symfony\Component\ClassLoader;
* found before giving up.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Kris Wallsmith <kris.wallsmith@symfony.com>
* @author Kris Wallsmith <kris@symfony.com>
*
* @api
*/

View File

@ -110,7 +110,7 @@ class Command
*
* @return integer 0 if everything went fine, or an error code
*
* @throws \LogicException When this abstract class is not implemented
* @throws \LogicException When this abstract method is not implemented
* @see setCode()
*/
protected function execute(InputInterface $input, OutputInterface $output)
@ -349,7 +349,7 @@ class Command
}
/**
* Returns the command name
* Returns the command name.
*
* @return string The command name
*

View File

@ -10,7 +10,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
* into account which is contained in the definition itself.
*
* Later passes can rely on the following, and specifically do not need to
* perform these checks themself:
* perform these checks themselves:
*
* - non synthetic, non abstract services always have a class set
* - synthetic services are always public

View File

@ -105,7 +105,6 @@ class Compiler
*/
public function compile(ContainerBuilder $container)
{
$start = microtime(true);
foreach ($this->passConfig->getPasses() as $pass) {
$pass->process($container);
}

View File

@ -51,7 +51,6 @@ class RepeatedPass implements CompilerPassInterface
$compiler = $container->getCompiler();
$this->repeat = false;
foreach ($this->passes as $pass) {
$time = microtime(true);
$pass->process($container);
}

View File

@ -122,6 +122,9 @@ class XmlDumper extends Dumper
if (ContainerInterface::SCOPE_CONTAINER !== $scope = $definition->getScope()) {
$service->setAttribute('scope', $scope);
}
if (!$definition->isPublic()) {
$service->setAttribute('public', 'false');
}
foreach ($definition->getTags() as $name => $tags) {
foreach ($tags as $attributes) {

View File

@ -259,6 +259,9 @@ class XmlFileLoader extends FileLoader
// resolve definitions
krsort($definitions);
foreach ($definitions as $id => $def) {
// anonymous services are always private
$def[0]['public'] = false;
$this->parseDefinition($id, $def[0], $def[1]);
$oNode = dom_import_simplexml($def[0]);

View File

@ -166,7 +166,6 @@ class PdoSessionStorage extends NativeSessionStorage
$dbTable = $this->dbOptions['db_table'];
$dbDataCol = $this->dbOptions['db_data_col'];
$dbIdCol = $this->dbOptions['db_id_col'];
$dbTimeCol = $this->dbOptions['db_time_col'];
try {
$sql = 'SELECT '.$dbDataCol.' FROM '.$dbTable.' WHERE '.$dbIdCol.'=?';

View File

@ -77,7 +77,11 @@ class ExceptionListener
} catch (\Exception $e) {
$message = sprintf('Exception thrown when handling an exception (%s: %s)', get_class($e), $e->getMessage());
if (null !== $this->logger) {
$this->logger->err($message);
if ($exception instanceof HttpExceptionInterface && $exception->getStatusCode() >= 500) {
$this->logger->crit($message);
} else {
$this->logger->err($message);
}
} else {
error_log($message);
}

View File

@ -242,8 +242,11 @@ abstract class Kernel implements KernelInterface
throw new \RuntimeException(sprintf('File name "%s" contains invalid characters (..).', $name));
}
$name = substr($name, 1);
list($bundleName, $path) = explode('/', $name, 2);
$bundleName = substr($name, 1);
$path = '';
if (false !== strpos($bundleName, '/')) {
list($bundleName, $path) = explode('/', $bundleName, 2);
}
$isResource = 0 === strpos($path, 'Resources') && null !== $dir;
$overridePath = substr($path, 9);
@ -280,7 +283,7 @@ abstract class Kernel implements KernelInterface
return $first && $isResource ? $files[0] : $files;
}
throw new \InvalidArgumentException(sprintf('Unable to find file "@%s".', $name));
throw new \InvalidArgumentException(sprintf('Unable to find file "%s".', $name));
}
/**

View File

@ -18,8 +18,6 @@ namespace Symfony\Component\HttpKernel\Log;
*/
interface LoggerInterface
{
function log($message, $priority);
function emerg($message);
function alert($message);

View File

@ -180,7 +180,6 @@ abstract class PdoProfilerStorage implements ProfilerStorageInterface
protected function fetch($db, $query, array $args = array())
{
$return = array();
$stmt = $this->prepareStatement($db, $query);
foreach ($args as $arg => $val) {

View File

@ -71,15 +71,22 @@ class RouteCompiler implements RouteCompilerInterface
// compute the matching regexp
$regex = '';
$indent = 1;
foreach ($tokens as $i => $token) {
if ('text' === $token[0]) {
$regex .= str_repeat(' ', $indent * 4).preg_quote($token[1], '#')."\n";
} else {
if ($i >= $firstOptional) {
$regex .= str_repeat(' ', $indent * 4)."(?:\n";
++$indent;
if (1 === count($tokens) && 0 === $firstOptional) {
$token = $tokens[0];
++$indent;
$regex .= str_repeat(' ', $indent * 4).sprintf("%s(?:\n", preg_quote($token[1], '#'));
$regex .= str_repeat(' ', $indent * 4).sprintf("(?P<%s>%s)\n", $token[3], $token[2]);
} else {
foreach ($tokens as $i => $token) {
if ('text' === $token[0]) {
$regex .= str_repeat(' ', $indent * 4).preg_quote($token[1], '#')."\n";
} else {
if ($i >= $firstOptional) {
$regex .= str_repeat(' ', $indent * 4)."(?:\n";
++$indent;
}
$regex .= str_repeat(' ', $indent * 4).sprintf("%s(?P<%s>%s)\n", preg_quote($token[1], '#'), $token[3], $token[2]);
}
$regex .= str_repeat(' ', $indent * 4).sprintf("%s(?P<%s>%s)\n", preg_quote($token[1], '#'), $token[3], $token[2]);
}
}
while (--$indent) {

View File

@ -30,7 +30,7 @@ class Serializer implements SerializerInterface
{
private $normalizers = array();
private $encoders = array();
private $normalizerCache = array();
protected $normalizerCache = array();
/**
* @param mixed $value value to test

View File

@ -45,9 +45,8 @@ class ExceptionListenerTest extends \PHPUnit_Framework_TestCase
*/
public function testHandleWithoutLogger($event, $event2)
{
//store the current error_log, and set the new one to dev/null
$error_log = ini_get('error_log');
ini_set('error_log', '/dev/null');
// store the current error_log, and disable it temporarily
$errorLog = ini_set('error_log', file_exists('/dev/null') ? '/dev/null' : 'nul');
$l = new ExceptionListener('foo');
$l->onCoreException($event);
@ -60,8 +59,8 @@ class ExceptionListenerTest extends \PHPUnit_Framework_TestCase
$this->assertSame('foo', $e->getMessage());
}
//restore the old error_log
ini_set('error_log', $error_log);
// restore the old error_log
ini_set('error_log', $errorLog);
}
/**

View File

@ -96,6 +96,19 @@ class UrlMatcherTest extends \PHPUnit_Framework_TestCase
$this->assertInternalType('array', $matcher->match('/foo'));
$matcher = new UrlMatcher($collection, new RequestContext('', 'head'), array());
$this->assertInternalType('array', $matcher->match('/foo'));
// route with an optional variable as the first segment
$collection = new RouteCollection();
$collection->add('bar', new Route('/{bar}/foo', array('bar' => 'bar'), array('bar' => 'foo|bar')));
$matcher = new UrlMatcher($collection, new RequestContext(), array());
$this->assertEquals(array('_route' => 'bar', 'bar' => 'bar'), $matcher->match('/bar/foo'));
$this->assertEquals(array('_route' => 'bar', 'bar' => 'foo'), $matcher->match('/foo/foo'));
$collection = new RouteCollection();
$collection->add('bar', new Route('/{bar}', array('bar' => 'bar'), array('bar' => 'foo|bar')));
$matcher = new UrlMatcher($collection, new RequestContext(), array());
$this->assertEquals(array('_route' => 'bar', 'bar' => 'foo'), $matcher->match('/foo'));
$this->assertEquals(array('_route' => 'bar', 'bar' => 'bar'), $matcher->match('/'));
}
public function testMatchRegression()

View File

@ -82,6 +82,20 @@ class RouteCompilerTest extends \PHPUnit_Framework_TestCase
array('variable', '/', '[^/]*?', 'bar'),
array('text', '/foo'),
)),
array(
'Route with an optional variable as the first segment',
array('/{bar}', array('bar' => 'bar')),
'', '#^/(?:(?P<bar>[^/]*?))?$#x', array('bar'), array(
array('variable', '/', '[^/]*?', 'bar'),
)),
array(
'Route with an optional variable as the first segment with requirements',
array('/{bar}', array('bar' => 'bar'), array('bar' => '(foo|bar)')),
'', '#^/(?:(?P<bar>(foo|bar)))?$#x', array('bar'), array(
array('variable', '/', '(foo|bar)', 'bar'),
)),
);
}
}