diff --git a/src/Symfony/Framework/DoctrineBundle/Bundle.php b/src/Symfony/Framework/DoctrineBundle/Bundle.php index dedfd70def..3f49562755 100644 --- a/src/Symfony/Framework/DoctrineBundle/Bundle.php +++ b/src/Symfony/Framework/DoctrineBundle/Bundle.php @@ -22,11 +22,36 @@ use Symfony\Framework\DoctrineBundle\DependencyInjection\DoctrineExtension; * * @package symfony * @author Fabien Potencier + * @author Jonathan H. Wage */ class Bundle extends BaseBundle { public function buildContainer(ContainerInterface $container) { Loader::registerExtension(new DoctrineExtension()); + + $metadataDirs = array(); + $entityDirs = array(); + $bundleDirs = $container->getParameter('kernel.bundle_dirs'); + foreach ($container->getParameter('kernel.bundles') as $className) + { + $tmp = dirname(str_replace('\\', '/', $className)); + $namespace = dirname($tmp); + $class = basename($tmp); + + if (isset($bundleDirs[$namespace])) + { + if (is_dir($dir = $bundleDirs[$namespace].'/'.$class.'/Resources/config/doctrine/metadata')) + { + $metadataDirs[] = $dir; + } + if (is_dir($dir = $bundleDirs[$namespace].'/'.$class.'/Entities')) + { + $entityDirs[] = $dir; + } + } + } + $container->setParameter('doctrine.orm.metadata_driver_impl.dirs', $metadataDirs); + $container->setParameter('doctrine.entity_dirs', $entityDirs); } -} +} \ No newline at end of file diff --git a/src/Symfony/Framework/DoctrineBundle/Command/ClearCacheDoctrineCommand.php b/src/Symfony/Framework/DoctrineBundle/Command/ClearCacheDoctrineCommand.php new file mode 100644 index 0000000000..56f6f6d6cf --- /dev/null +++ b/src/Symfony/Framework/DoctrineBundle/Command/ClearCacheDoctrineCommand.php @@ -0,0 +1,62 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * Manage the cache clearing of the Doctrine ORM. + * + * @package symfony + * @subpackage console + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class ClearCacheDoctrineCommand extends DoctrineCommand +{ + /** + * @see Command + */ + protected function configure() + { + $this + ->setName('doctrine:clear-cache') + ->setDescription('Clear cache from configured query, result and metadata drivers.') + ->setAliases(array('doctrine:cc')) + ->addOption('query', null, null, 'Clear the query cache.') + ->addOption('metadata', null, null, 'Clear the metadata cache.') + ->addOption('result', null, null, 'Clear the result cache.') + ->addOption('id', null, null, 'Clear a cache entry by its id.') + ->addOption('regex', null, null, 'Clear cache entries that match a regular expression.') + ->addOption('prefix', null, null, 'Clear cache entries that match a prefix.') + ->addOption('suffix', null, null, 'Clear cache entries that match a suffix.') + ; + } + + /** + * @see Command + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $options = $this->buildDoctrineCliTaskOptions($input, array( + 'query', 'metadata', 'result', 'id', 'regex', 'prefix', 'suffix' + )); + $this->runDoctrineCliTask('orm:clear-cache', $options); + } +} \ No newline at end of file diff --git a/src/Symfony/Framework/DoctrineBundle/Command/ConvertMappingDoctrineCommand.php b/src/Symfony/Framework/DoctrineBundle/Command/ConvertMappingDoctrineCommand.php new file mode 100644 index 0000000000..f867b29976 --- /dev/null +++ b/src/Symfony/Framework/DoctrineBundle/Command/ConvertMappingDoctrineCommand.php @@ -0,0 +1,58 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * Convert Doctrine ORM metadata mapping information between the various supported + * formats. + * + * @package symfony + * @subpackage console + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class ConvertMappingDoctrineCommand extends DoctrineCommand +{ + /** + * @see Command + */ + protected function configure() + { + $this + ->setName('doctrine:convert-mapping') + ->setDescription('Convert mapping information between supported formats.') + ->addOption('from', null, null, 'The source to convert from.') + ->addOption('to', null, null, 'The type of mapping to convert to.') + ->addOption('dest', null, null, 'Where to output the converted source.') + ; + } + + /** + * @see Command + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $options = $this->buildDoctrineCliTaskOptions($input, array( + 'from', 'to', 'dest' + )); + $this->runDoctrineCliTask('orm:convert-mapping', $options); + } +} \ No newline at end of file diff --git a/src/Symfony/Framework/DoctrineBundle/Command/DoctrineCommand.php b/src/Symfony/Framework/DoctrineBundle/Command/DoctrineCommand.php index e233909924..55fe976d80 100644 --- a/src/Symfony/Framework/DoctrineBundle/Command/DoctrineCommand.php +++ b/src/Symfony/Framework/DoctrineBundle/Command/DoctrineCommand.php @@ -10,6 +10,7 @@ use Symfony\Components\Console\Output\OutputInterface; use Symfony\Components\Console\Output\Output; use Symfony\Framework\WebBundle\Util\Filesystem; use Doctrine\Common\Cli\Configuration; +use Doctrine\Common\Cli\CliController as DoctrineCliController; /* * This file is part of the symfony framework. @@ -21,7 +22,7 @@ use Doctrine\Common\Cli\Configuration; */ /** - * + * Base class for Doctrine consol commands to extend from. * * @package symfony * @subpackage console @@ -29,4 +30,46 @@ use Doctrine\Common\Cli\Configuration; */ abstract class DoctrineCommand extends Command { -} + protected $cli; + + protected function getDoctrineCli() + { + if ($this->cli === null) + { + $configuration = new Configuration(); + $configuration->setAttribute('em', $this->container->getDoctrine_Orm_EntityManagerService()); + $this->cli = new DoctrineCliController($configuration); + } + return $this->cli; + } + + protected function runDoctrineCliTask($name, $options = array()) + { + $builtOptions = array(); + foreach ($options as $key => $value) + { + if ($value === null) + { + $builtOptions[] = sprintf('--%s', $key); + } + else + { + $builtOptions[] = sprintf('--%s=%s', $key, $value); + } + } + return $this->getDoctrineCli()->run(array_merge(array('doctrine', $name), $builtOptions)); + } + + public function buildDoctrineCliTaskOptions(InputInterface $input, array $options) + { + $taskOptions = array(); + foreach ($options as $option) + { + if ($value = $input->getOption($option)) + { + $options[$option] = $value; + } + } + return $options; + } +} \ No newline at end of file diff --git a/src/Symfony/Framework/DoctrineBundle/Command/EnsureProductionSettingsDoctrineCommand.php b/src/Symfony/Framework/DoctrineBundle/Command/EnsureProductionSettingsDoctrineCommand.php new file mode 100644 index 0000000000..b6a04dd1c0 --- /dev/null +++ b/src/Symfony/Framework/DoctrineBundle/Command/EnsureProductionSettingsDoctrineCommand.php @@ -0,0 +1,51 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * Ensure the Doctrine ORM is configured properly for a production environment. + * + * @package symfony + * @subpackage console + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class EnsureProductionSettingsDoctrineCommand extends DoctrineCommand +{ + /** + * @see Command + */ + protected function configure() + { + $this + ->setName('doctrine:ensure-production-settings') + ->setDescription('Verify that Doctrine is properly configured for a production environment.') + ; + } + + /** + * @see Command + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $this->runDoctrineCliTask('orm:ensure-production-settings'); + } +} \ No newline at end of file diff --git a/src/Symfony/Framework/DoctrineBundle/Command/GenerateProxiesDoctrineCommand.php b/src/Symfony/Framework/DoctrineBundle/Command/GenerateProxiesDoctrineCommand.php index e04bea33aa..02774605b8 100644 --- a/src/Symfony/Framework/DoctrineBundle/Command/GenerateProxiesDoctrineCommand.php +++ b/src/Symfony/Framework/DoctrineBundle/Command/GenerateProxiesDoctrineCommand.php @@ -8,8 +8,6 @@ use Symfony\Components\Console\Input\InputInterface; use Symfony\Components\Console\Output\OutputInterface; use Symfony\Components\Console\Output\Output; use Symfony\Framework\WebBundle\Util\Filesystem; -use Doctrine\Common\Cli\Configuration; -use Doctrine\Common\Cli\CliController as DoctrineCliController; /* * This file is part of the symfony framework. @@ -21,7 +19,7 @@ use Doctrine\Common\Cli\CliController as DoctrineCliController; */ /** - * + * Generate the Doctrine ORM entity proxies to your cache directory. * * @package symfony * @subpackage console @@ -36,6 +34,7 @@ class GenerateProxiesDoctrineCommand extends DoctrineCommand { $this ->setName('doctrine:generate-proxies') + ->setDescription('Generates proxy classes for entity classes.') ; } @@ -44,9 +43,6 @@ class GenerateProxiesDoctrineCommand extends DoctrineCommand */ protected function execute(InputInterface $input, OutputInterface $output) { - $configuration = new Configuration(); - $configuration->setAttribute('em', $this->container->getDoctrine_Orm_ManagerService()); - $dirs = array(); $bundleDirs = $this->container->getKernelService()->getBundleDirs(); foreach ($this->container->getKernelService()->getBundles() as $bundle) @@ -55,7 +51,7 @@ class GenerateProxiesDoctrineCommand extends DoctrineCommand $namespace = dirname($tmp); $class = basename($tmp); - if (isset($bundleDirs[$namespace]) && is_dir($dir = $bundleDirs[$namespace].'/'.$class.'/Model/Doctrine')) + if (isset($bundleDirs[$namespace]) && is_dir($dir = $bundleDirs[$namespace].'/'.$class.'/Entities')) { $dirs[] = $dir; } @@ -66,10 +62,9 @@ class GenerateProxiesDoctrineCommand extends DoctrineCommand mkdir($dir, 0777, true); } - $cli = new DoctrineCliController($configuration); foreach ($dirs as $dir) { - $cli->run(array('doctrine', 'orm:generate-proxies', '--class-dir='.$dir)); + $this->runDoctrineCliTask('orm:generate-proxies', array('class-dir' => $dir)); } } -} +} \ No newline at end of file diff --git a/src/Symfony/Framework/DoctrineBundle/Command/LoadDataFixturesDoctrineCommand.php b/src/Symfony/Framework/DoctrineBundle/Command/LoadDataFixturesDoctrineCommand.php new file mode 100644 index 0000000000..49d23d83da --- /dev/null +++ b/src/Symfony/Framework/DoctrineBundle/Command/LoadDataFixturesDoctrineCommand.php @@ -0,0 +1,157 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * Load data fixtures from bundles + * + * @package symfony + * @subpackage console + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class LoadDataFixturesDoctrineCommand extends DoctrineCommand +{ + /** + * @see Command + */ + protected function configure() + { + $this + ->setName('doctrine:load-data-fixtures') + ->setDescription('Load data fixtures to your database.') + ->addOption('dir_or_file', null, null, 'The directory or file to load data fixtures from.') + ->addOption('append', null, InputOption::PARAMETER_OPTIONAL, 'Whether or not to append the data fixtures.', false) + ; + } + + /** + * @see Command + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $em = $this->container->getDoctrine_ORM_EntityManagerService(); + if (!$input->getOption('append')) + { + $classes = array(); + $metadatas = $em->getMetadataFactory()->getAllMetadata(); + + foreach ($metadatas as $metadata) + { + if (!$metadata->isMappedSuperclass) + { + $classes[] = $metadata; + } + } + $cmf = $em->getMetadataFactory(); + $classes = $this->getCommitOrder($em, $classes); + for ($i = count($classes) - 1; $i >= 0; --$i) + { + $class = $classes[$i]; + if ($cmf->hasMetadataFor($class->name)) + { + try { + $em->createQuery('DELETE FROM '.$class->name.' a')->execute(); + } catch (Exception $e) {} + } + } + } + + $dirOrFile = $input->getOption('dir_or_file'); + if ($dirOrFile) + { + $paths = $dirOrFile; + } else { + $paths = array(); + $bundleDirs = $this->container->getKernelService()->getBundleDirs(); + foreach ($this->container->getKernelService()->getBundles() as $bundle) + { + $tmp = dirname(str_replace('\\', '/', get_class($bundle))); + $namespace = dirname($tmp); + $class = basename($tmp); + + if (isset($bundleDirs[$namespace]) && is_dir($dir = $bundleDirs[$namespace].'/'.$class.'/Resources/data/fixtures/doctrine')) + { + $paths[] = $dir; + } + } + } + + $files = array(); + foreach ($paths as $path) + { + if (is_dir($path)) + { + $found = Finder::type('file') + ->name('*.php') + ->in($path); + } else { + $found = array($path); + } + $files = array_merge($files, $found); + } + + $files = array_unique($files); + + foreach ($files as $file) + { + $before = array_keys(get_defined_vars()); + include($file); + $after = array_keys(get_defined_vars()); + $new = array_diff($after, $before); + $entities = array_values($new); + unset($entities[array_search('before', $entities)]); + foreach ($entities as $entity) { + $em->persist($$entity); + } + $em->flush(); + } + } + + protected function getCommitOrder(EntityManager $em, array $classes) + { + $calc = new CommitOrderCalculator; + + foreach ($classes as $class) + { + $calc->addClass($class); + + foreach ($class->associationMappings as $assoc) + { + if ($assoc->isOwningSide) { + $targetClass = $em->getClassMetadata($assoc->targetEntityName); + + if ( ! $calc->hasClass($targetClass->name)) { + $calc->addClass($targetClass); + } + + // add dependency ($targetClass before $class) + $calc->addDependency($targetClass, $class); + } + } + } + + return $calc->getCommitOrder(); + } +} \ No newline at end of file diff --git a/src/Symfony/Framework/DoctrineBundle/Command/RunDqlDoctrineCommand.php b/src/Symfony/Framework/DoctrineBundle/Command/RunDqlDoctrineCommand.php new file mode 100644 index 0000000000..343929a056 --- /dev/null +++ b/src/Symfony/Framework/DoctrineBundle/Command/RunDqlDoctrineCommand.php @@ -0,0 +1,56 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * Execute a Doctrine DQL query and output the results + * + * @package symfony + * @subpackage console + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class RunDqlDoctrineCommand extends DoctrineCommand +{ + /** + * @see Command + */ + protected function configure() + { + $this + ->setName('doctrine:run-dql') + ->setDescription('Executes arbitrary DQL directly from the command line.') + ->addOption('dql', null, null, 'The DQL query to run.') + ->addOption('depth', null, null, 'The depth to output the data to.') + ; + } + + /** + * @see Command + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $options = $this->buildDoctrineCliTaskOptions($input, array( + 'dql', 'depth' + )); + $this->runDoctrineCliTask('orm:run-dql', $options); + } +} \ No newline at end of file diff --git a/src/Symfony/Framework/DoctrineBundle/Command/RunSqlDoctrineCommand.php b/src/Symfony/Framework/DoctrineBundle/Command/RunSqlDoctrineCommand.php new file mode 100644 index 0000000000..44c393264c --- /dev/null +++ b/src/Symfony/Framework/DoctrineBundle/Command/RunSqlDoctrineCommand.php @@ -0,0 +1,57 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * Execute a SQL query and output the results + * + * @package symfony + * @subpackage console + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class RunSqlDoctrineCommand extends DoctrineCommand +{ + /** + * @see Command + */ + protected function configure() + { + $this + ->setName('doctrine:run-sql') + ->setDescription('Executes arbitrary SQL from a file or directly from the command line.') + ->addOption('sql', null, null, 'The SQL query to run.') + ->addOption('file', null, null, 'Path to a SQL file to run.') + ->addOption('depth', null, null, 'The depth to output the data to.') + ; + } + + /** + * @see Command + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $options = $this->buildDoctrineCliTaskOptions($input, array( + 'sql', 'file', 'depth' + )); + $this->runDoctrineCliTask('dbal:run-sql', $options); + } +} \ No newline at end of file diff --git a/src/Symfony/Framework/DoctrineBundle/Command/SchemaToolDoctrineCommand.php b/src/Symfony/Framework/DoctrineBundle/Command/SchemaToolDoctrineCommand.php new file mode 100644 index 0000000000..298c3092b2 --- /dev/null +++ b/src/Symfony/Framework/DoctrineBundle/Command/SchemaToolDoctrineCommand.php @@ -0,0 +1,62 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * Create, drop, and update your Doctrine ORM schema in the DBMS. + * + * @package symfony + * @subpackage console + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class SchemaToolDoctrineCommand extends DoctrineCommand +{ + /** + * @see Command + */ + protected function configure() + { + $this + ->setName('doctrine:schema-tool') + ->setDescription('Processes the schema and either apply it directly on EntityManager or generate the SQL output.') + ->addOption('create', null, null, 'Create your database schema.') + ->addOption('drop', null, null, 'Drop your database schema.') + ->addOption('update', null, null, 'Update your database schema and add anything that is not in your database but exists in your schema.') + ->addOption('complete-update', null, null, 'Complete update and drop anything that is not in your schema.') + ->addOption('re-create', null, null, 'Drop and re-create your database schema.') + ->addOption('dump-sql', null, null, 'Dump the SQL instead of executing it.') + ; + } + + /** + * @see Command + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $options = $this->buildDoctrineCliTaskOptions($input, array( + 'create', 'drop', 'update', 'complete-update', 're-create', 'dump-sql' + )); + $entityDirs = $this->container->getParameter('doctrine.entity_dirs'); + $options['class-dir'] = implode(', ', $entityDirs); + $this->runDoctrineCliTask('orm:schema-tool', $options); + } +} \ No newline at end of file diff --git a/src/Symfony/Framework/DoctrineBundle/Command/VersionDoctrineCommand.php b/src/Symfony/Framework/DoctrineBundle/Command/VersionDoctrineCommand.php new file mode 100644 index 0000000000..d8eb4795b1 --- /dev/null +++ b/src/Symfony/Framework/DoctrineBundle/Command/VersionDoctrineCommand.php @@ -0,0 +1,51 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * Check what version of the Doctrine ORM being used. + * + * @package symfony + * @subpackage console + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class VersionDoctrineCommand extends DoctrineCommand +{ + /** + * @see Command + */ + protected function configure() + { + $this + ->setName('doctrine:version') + ->setDescription('Displays the current installed Doctrine version.') + ; + } + + /** + * @see Command + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $this->runDoctrineCliTask('orm:version'); + } +} \ No newline at end of file diff --git a/src/Symfony/Framework/DoctrineBundle/Controller/DoctrineController.php b/src/Symfony/Framework/DoctrineBundle/Controller/DoctrineController.php index 1a4e96589b..dfb757bfb7 100644 --- a/src/Symfony/Framework/DoctrineBundle/Controller/DoctrineController.php +++ b/src/Symfony/Framework/DoctrineBundle/Controller/DoctrineController.php @@ -23,18 +23,18 @@ use Symfony\Components\RequestHandler\Exception\NotFoundHttpException; */ class DoctrineController extends Controller { - protected function getManager() + protected function getEntityManager() { - return $this->container->getDoctrine_ORM_ManagerService(); + return $this->container->getDoctrine_ORM_EntityManagerService(); } public function createQueryBuilder() { - return $this->getManager()->createQueryBuilder(); + return $this->getEntityManager()->createQueryBuilder(); } public function createQuery($dql = '') { - return $this->getManager()->createQuery($dql); + return $this->getEntityManager()->createQuery($dql); } } diff --git a/src/Symfony/Framework/DoctrineBundle/DependencyInjection/DoctrineExtension.php b/src/Symfony/Framework/DoctrineBundle/DependencyInjection/DoctrineExtension.php index 0983cc1d87..aeff9db162 100644 --- a/src/Symfony/Framework/DoctrineBundle/DependencyInjection/DoctrineExtension.php +++ b/src/Symfony/Framework/DoctrineBundle/DependencyInjection/DoctrineExtension.php @@ -97,6 +97,14 @@ class DoctrineExtension extends LoaderExtension $loader = new XmlFileLoader(__DIR__.'/../Resources/config'); $configuration->merge($loader->load($this->resources['orm'])); + foreach (array('entity_manager.class', 'metadata_driver_impl.class', 'cache.class') as $key) + { + if (isset($config[$key])) + { + $configuration->setParameter('doctrine.orm.'.$key, $config[$key]); + } + } + return $configuration; } diff --git a/src/Symfony/Framework/DoctrineBundle/Resources/config/orm.xml b/src/Symfony/Framework/DoctrineBundle/Resources/config/orm.xml index 28db29c62a..0286a932bb 100644 --- a/src/Symfony/Framework/DoctrineBundle/Resources/config/orm.xml +++ b/src/Symfony/Framework/DoctrineBundle/Resources/config/orm.xml @@ -5,25 +5,31 @@ xsi:schemaLocation="http://www.symfony-project.org/schema/dic/services http://www.symfony-project.org/schema/dic/services/services-1.0.xsd"> - Doctrine\ORM\EntityManager + Doctrine\ORM\EntityManager + Doctrine\ORM\Mapping\Driver\XmlDriver + Doctrine\Common\Cache\ArrayCache - + + + + + - + + %kernel.cache_dir%/doctrine/Proxies Proxies true - -