pax_global_header00006660000000000000000000000064132060147770014521gustar00rootroot0000000000000052 comment=eb6e4fb904a459be28872765ab6e2d246aac7c87 DoctrineBundle-1.8.1/000077500000000000000000000000001320601477700144315ustar00rootroot00000000000000DoctrineBundle-1.8.1/Changelog.md000066400000000000000000000123331320601477700166440ustar00rootroot00000000000000## 1.5.2 (2015-08-31) Security: * Fix Security Misconfiguration Vulnerability, allowing potential local arbitrary code execution. ## 1.5.1 (2015-08-12) Bugfix: * Fixed the JS expanding all queries in the profiler in case of multiple connections * Fixed the retrieval of the namespace in DisconnectedMetadataFactory * Changed the composer constraint to allow Symfony 3.0 for people wanting to do early testing ## 1.5.0 (2015-05-28) Features: * Added the possibility to configure the quote strategy in the configuration * Improved the rendering of the query explanation for Postgres * Added support for tagging entity listeners, without the need to map the listener Bugfix: * Fixed the serverVersion configuration for master slave connections * Fixed the enabling of the profiler to avoid automatically enabling the logger * Fixed the detection of existing databases when quoted names are used * Fixed the profiler template when having a manager without any loaded metadata ## 1.4.0 (2015-02-28) Features: * Added the ``--if-not-exists`` option in the ``doctrine:database:create`` command * Added the ``--if-exists`` option in the ``doctrine:database:drop`` command * Added the support for the ``url`` DBAL setting * Added profiling ability for SQL Server Bugfix: * Fixed the cache configuration when using ``cache_provider`` * Removed usage of deprecated DI features when using Symfony 2.6+ * Close connections and clear managers on shutdown. This avoids leaking connections in tests. * Added an exception when the ORM layer is configured but not DBAL ## 1.3.0 (2014-11-28) Features: * add support for bundle namespace alias in the mapping compiler pass * Added support for server_version connection parameter * Added a way to enable auto_mapping option using multiple entity managers Bugfix: * Inlined the profiler picto images instead of getting from FrameworkBundle (where they are gone) * Remove duplicates in the list of mapped entities in the profile * Fixed the compatibility with PHP 5.3 (broken in 1.3.0-beta1) ## 1.3.0-beta2 (2014-07-09) Feature: * add auto-commit DBAL configuration option * Use DoctrineCacheBundle to create cache drivers, supporting more configuration * Added sorting by time in DB panel Bugfix: * Fixed the compatibility of the DataCollector with Doctrine 2.4 (bug introduced in 1.3.0-beta1) * Fixed the exit code of commands on failure * Fixed the replacement of query parameters in the profiler ## 1.3.0-beta1 (2014-01-26) Features: * Added option to configure entity listener resolver service * add compiler pass for bundles to register mappings * Added a button to expand/collapse all queries in the profiler * Added configuration for sharding * Added support for the new ways to generate proxies in Doctrine Common * Added configuration for the second-level cache Bugfix: * Removed deprecated call * fix drop and create command for connections with master slave configuration * Remove usage of deprecated Twig features ## 1.2.0 (2013-03-25) * Bumped the requirement to Symfony 2.2 * Updated the profiler templates for Symfony 2.2 ## 1.1.0 (2013-01-12) * Added syntax highlighting for queries in teh profiler * Added the validation of the mapping in the profiler panel * Added return codes for doctrine:database:[create|drop] commands ## 1.0.0 (2012-09-07) * Removed the mysql charset hack for 5.3.6+ as PDO has been fixed * Implement "keep_slave"/"keepSlave" configuration * Added missing Redis cache class mapping. * Fixed the XSD schema for the configuration. * Added support for schema assets filter configuration * integrate naming_strategy into config ## 1.0.0-RC1 (2012-07-04) * Add support for targetEntity resolving through the ORM 2.2 listener. * Fixed quote database name in doctrine:database:create and doctrine:database:drop commands * added a way to use cache services * Added a way to configure the default entity repository class * Added the support for SQL filters * Removed the InfoCommand and proxy the ORM command instead * Made the ORM fully optional by avoiding breaking the console * Added support for master_slave connections * Fixed xml config for proxy parameters * Fixes doctrine:generate:entities when called with the --path argument * Added missing Memcached cache driver * Fix memory leak in Doctrine Autoload Proxy Magic * adds lazy-loading event manager, improved listener registration * Added a configuration setting for commented types * Fixed bug with MetadataFactory having problem when the StaticReflection is used. * Added the possibility to explain queries in the profiler * Splitted the configuration for the logging and the profiling of the connection ## 1.0.0-beta1 (2011-12-15) * [BC break] Changed the namespace from Symfony\Bundle to Doctrine\Bundle * Enhance error reporting during mapping validation when nested exceptions occur. * Add DoctrineValidationPass to load validation files conditionally * Moved the entity provider service to DoctrineBundle * Added Stopwatch support in debug mode to integrate in the profiler timeline * Removed the IndexedReader * Added the implementation of the ManagerRegistry to replace the symfony 2.0 registry * Added access to Doctrine's ValidateSchema command from the console. See symfony/symfony#2200. * Extracted the bundle from Symfony 2.0 DoctrineBundle-1.8.1/Command/000077500000000000000000000000001320601477700160075ustar00rootroot00000000000000DoctrineBundle-1.8.1/Command/CreateDatabaseDoctrineCommand.php000066400000000000000000000117151320601477700243440ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Command; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Doctrine\DBAL\DriverManager; /** * Database tool allows you to easily drop and create your configured databases. * * @author Fabien Potencier * @author Jonathan H. Wage */ class CreateDatabaseDoctrineCommand extends DoctrineCommand { /** * {@inheritDoc} */ protected function configure() { $this ->setName('doctrine:database:create') ->setDescription('Creates the configured database') ->addOption('shard', null, InputOption::VALUE_REQUIRED, 'The shard connection to use for this command') ->addOption('connection', null, InputOption::VALUE_OPTIONAL, 'The connection to use for this command') ->addOption('if-not-exists', null, InputOption::VALUE_NONE, 'Don\'t trigger an error, when the database already exists') ->setHelp(<<%command.name% command creates the default connections database: php %command.full_name% You can also optionally specify the name of a connection to create the database for: php %command.full_name% --connection=default EOT ); } /** * {@inheritDoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $connectionName = $input->getOption('connection'); if (empty($connectionName) === true) { $connectionName = $this->getContainer()->get('doctrine')->getDefaultConnectionName(); } $connection = $this->getDoctrineConnection($connectionName); $ifNotExists = $input->getOption('if-not-exists'); $params = $connection->getParams(); if (isset($params['master'])) { $params = $params['master']; } // Cannot inject `shard` option in parent::getDoctrineConnection // cause it will try to connect to a non-existing database if (isset($params['shards'])) { $shards = $params['shards']; // Default select global $params = array_merge($params, $params['global']); unset($params['global']['dbname']); if ($input->getOption('shard')) { foreach ($shards as $i => $shard) { if ($shard['id'] === (int)$input->getOption('shard')) { // Select sharded database $params = array_merge($params, $shard); unset($params['shards'][$i]['dbname'], $params['id']); break; } } } } $hasPath = isset($params['path']); $name = $hasPath ? $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."); } // Need to get rid of _every_ occurrence of dbname from connection configuration and we have already extracted all relevant info from url unset($params['dbname'], $params['path'], $params['url']); $tmpConnection = DriverManager::getConnection($params); $tmpConnection->connect($input->getOption('shard')); $shouldNotCreateDatabase = $ifNotExists && in_array($name, $tmpConnection->getSchemaManager()->listDatabases()); // Only quote if we don't have a path if (!$hasPath) { $name = $tmpConnection->getDatabasePlatform()->quoteSingleIdentifier($name); } $error = false; try { if ($shouldNotCreateDatabase) { $output->writeln(sprintf('Database %s for connection named %s already exists. Skipped.', $name, $connectionName)); } else { $tmpConnection->getSchemaManager()->createDatabase($name); $output->writeln(sprintf('Created database %s for connection named %s', $name, $connectionName)); } } catch (\Exception $e) { $output->writeln(sprintf('Could not create database %s for connection named %s', $name, $connectionName)); $output->writeln(sprintf('%s', $e->getMessage())); $error = true; } $tmpConnection->close(); return $error ? 1 : 0; } } DoctrineBundle-1.8.1/Command/DoctrineCommand.php000066400000000000000000000044641320601477700215760ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Command; use Doctrine\DBAL\Connection; use Doctrine\DBAL\Sharding\PoolingShardConnection; use Doctrine\ORM\EntityManager; use Doctrine\ORM\Tools\EntityGenerator; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; /** * Base class for Doctrine console commands to extend from. * * @author Fabien Potencier */ abstract class DoctrineCommand extends ContainerAwareCommand { /** * get a doctrine entity generator * * @return EntityGenerator */ protected function getEntityGenerator() { $entityGenerator = new EntityGenerator(); $entityGenerator->setGenerateAnnotations(false); $entityGenerator->setGenerateStubMethods(true); $entityGenerator->setRegenerateEntityIfExists(false); $entityGenerator->setUpdateEntityIfExists(true); $entityGenerator->setNumSpaces(4); $entityGenerator->setAnnotationPrefix('ORM\\'); return $entityGenerator; } /** * Get a doctrine entity manager by symfony name. * * @param string $name * @param null|integer $shardId * * @return EntityManager */ protected function getEntityManager($name, $shardId = null) { $manager = $this->getContainer()->get('doctrine')->getManager($name); if ($shardId) { if (!$manager->getConnection() instanceof PoolingShardConnection) { throw new \LogicException(sprintf("Connection of EntityManager '%s' must implement shards configuration.", $name)); } $manager->getConnection()->connect($shardId); } return $manager; } /** * Get a doctrine dbal connection by symfony name. * * @param string $name * * @return Connection */ protected function getDoctrineConnection($name) { return $this->getContainer()->get('doctrine')->getConnection($name); } } DoctrineBundle-1.8.1/Command/DropDatabaseDoctrineCommand.php000066400000000000000000000122451320601477700240440ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Command; use Doctrine\DBAL\DriverManager; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; /** * Database tool allows you to easily drop and create your configured databases. * * @author Fabien Potencier * @author Jonathan H. Wage */ class DropDatabaseDoctrineCommand extends DoctrineCommand { const RETURN_CODE_NOT_DROP = 1; const RETURN_CODE_NO_FORCE = 2; /** * {@inheritDoc} */ protected function configure() { $this ->setName('doctrine:database:drop') ->setDescription('Drops the configured database') ->addOption('connection', null, InputOption::VALUE_OPTIONAL, 'The connection to use for this command') ->addOption('shard', null, InputOption::VALUE_REQUIRED, 'The shard connection to use for this command') ->addOption('if-exists', null, InputOption::VALUE_NONE, 'Don\'t trigger an error, when the database doesn\'t exist') ->addOption('force', null, InputOption::VALUE_NONE, 'Set this parameter to execute this action') ->setHelp(<<%command.name% command drops the default connections database: php %command.full_name% 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: php %command.full_name% --connection=default Be careful: All data in a given database will be lost when executing this command. EOT ); } /** * {@inheritDoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $connection = $this->getDoctrineConnection($input->getOption('connection')); $ifExists = $input->getOption('if-exists'); $params = $connection->getParams(); if (isset($params['master'])) { $params = $params['master']; } if (isset($params['shards'])) { $shards = $params['shards']; // Default select global $params = array_merge($params, $params['global']); if ($input->getOption('shard')) { foreach ($shards as $shard) { if ($shard['id'] === (int)$input->getOption('shard')) { // Select sharded database $params = $shard; unset($params['id']); break; } } } } $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."); } unset($params['dbname']); if ($input->getOption('force')) { // Reopen connection without database name set // as some vendors do not allow dropping the database connected to. $connection->close(); $connection = DriverManager::getConnection($params); $shouldDropDatabase = !$ifExists || in_array($name, $connection->getSchemaManager()->listDatabases()); // Only quote if we don't have a path if (!isset($params['path'])) { $name = $connection->getDatabasePlatform()->quoteSingleIdentifier($name); } try { if ($shouldDropDatabase) { $connection->getSchemaManager()->dropDatabase($name); $output->writeln(sprintf('Dropped database for connection named %s', $name)); } else { $output->writeln(sprintf('Database for connection named %s doesn\'t exist. Skipped.', $name)); } } catch (\Exception $e) { $output->writeln(sprintf('Could not drop database for connection named %s', $name)); $output->writeln(sprintf('%s', $e->getMessage())); return self::RETURN_CODE_NOT_DROP; } } else { $output->writeln('ATTENTION: This operation should not be executed in a production environment.'); $output->writeln(''); $output->writeln(sprintf('Would drop the database named %s.', $name)); $output->writeln('Please run the operation with --force to execute'); $output->writeln('All data will be lost!'); return self::RETURN_CODE_NO_FORCE; } } } DoctrineBundle-1.8.1/Command/GenerateEntitiesDoctrineCommand.php000066400000000000000000000131051320601477700247460ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\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 Doctrine\ORM\Tools\EntityRepositoryGenerator; use Doctrine\Bundle\DoctrineBundle\Mapping\DisconnectedMetadataFactory; /** * Generate entity classes from mapping information * * @author Fabien Potencier * @author Jonathan H. Wage */ class GenerateEntitiesDoctrineCommand extends DoctrineCommand { /** * {@inheritDoc} */ protected function configure() { $this ->setName('doctrine:generate:entities') ->setAliases(array('generate:doctrine:entities')) ->setDescription('Generates entity classes and method stubs from your mapping information') ->addArgument('name', InputArgument::REQUIRED, 'A bundle name, a namespace, or a class name') ->addOption('path', null, InputOption::VALUE_REQUIRED, 'The path where to generate entities when it cannot be guessed') ->addOption('no-backup', null, InputOption::VALUE_NONE, 'Do not backup existing entities files.') ->setHelp(<<%command.name% command generates entity classes and method stubs from your mapping information: You have to limit generation of entities: * To a bundle: php %command.full_name% MyCustomBundle * To a single entity: php %command.full_name% MyCustomBundle:User php %command.full_name% MyCustomBundle/Entity/User * To a namespace php %command.full_name% MyCustomBundle/Entity If the entities are not stored in a bundle, and if the classes do not exist, the command has no way to guess where they should be generated. In this case, you must provide the --path option: php %command.full_name% Blog/Entity --path=src/ By default, the unmodified version of each entity is backed up and saved (e.g. Product.php~). To prevent this task from creating the backup file, pass the --no-backup option: php %command.full_name% Blog/Entity --no-backup Important: Even if you specified Inheritance options in your XML or YAML Mapping files the generator cannot generate the base and child classes for you correctly, because it doesn't know which class is supposed to extend which. You have to adjust the entity code manually for inheritance to work! EOT ); } /** * {@inheritDoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $manager = new DisconnectedMetadataFactory($this->getContainer()->get('doctrine')); try { $bundle = $this->getApplication()->getKernel()->getBundle($input->getArgument('name')); $output->writeln(sprintf('Generating entities for bundle "%s"', $bundle->getName())); $metadata = $manager->getBundleMetadata($bundle); } catch (\InvalidArgumentException $e) { $name = strtr($input->getArgument('name'), '/', '\\'); if (false !== $pos = strpos($name, ':')) { $name = $this->getContainer()->get('doctrine')->getAliasNamespace(substr($name, 0, $pos)).'\\'.substr($name, $pos + 1); } if (class_exists($name)) { $output->writeln(sprintf('Generating entity "%s"', $name)); $metadata = $manager->getClassMetadata($name, $input->getOption('path')); } else { $output->writeln(sprintf('Generating entities for namespace "%s"', $name)); $metadata = $manager->getNamespaceMetadata($name, $input->getOption('path')); } } $generator = $this->getEntityGenerator(); $backupExisting = !$input->getOption('no-backup'); $generator->setBackupExisting($backupExisting); $repoGenerator = new EntityRepositoryGenerator(); foreach ($metadata->getMetadata() as $m) { if ($backupExisting) { $basename = substr($m->name, strrpos($m->name, '\\') + 1); $output->writeln(sprintf(' > backing up %s.php to %s.php~', $basename, $basename)); } // Getting the metadata for the entity class once more to get the correct path if the namespace has multiple occurrences try { $entityMetadata = $manager->getClassMetadata($m->getName(), $input->getOption('path')); } catch (\RuntimeException $e) { // fall back to the bundle metadata when no entity class could be found $entityMetadata = $metadata; } $output->writeln(sprintf(' > generating %s', $m->name)); $generator->generate(array($m), $entityMetadata->getPath()); if ($m->customRepositoryClassName && false !== strpos($m->customRepositoryClassName, $metadata->getNamespace())) { $repoGenerator->writeEntityRepositoryClass($m->customRepositoryClassName, $metadata->getPath()); } } } } DoctrineBundle-1.8.1/Command/ImportMappingDoctrineCommand.php000066400000000000000000000125731320601477700243050ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\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 Doctrine\ORM\Mapping\Driver\DatabaseDriver; use Doctrine\ORM\Tools\DisconnectedClassMetadataFactory; use Doctrine\ORM\Tools\Export\ClassMetadataExporter; use Doctrine\ORM\Tools\Console\MetadataFilter; /** * Import Doctrine ORM metadata mapping information from an existing database. * * @author Fabien Potencier * @author Jonathan H. Wage */ class ImportMappingDoctrineCommand extends DoctrineCommand { /** * {@inheritDoc} */ protected function configure() { $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') ->addOption('shard', null, InputOption::VALUE_REQUIRED, 'The shard connection to use for this command') ->addOption('filter', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'A string pattern used to match entities that should be mapped.') ->addOption('force', null, InputOption::VALUE_NONE, 'Force to overwrite existing mapping files.') ->setDescription('Imports mapping information from an existing database') ->setHelp(<<%command.name% command imports mapping information from an existing database: php %command.full_name% "MyCustomBundle" xml You can also optionally specify which entity manager to import from with the --em option: php %command.full_name% "MyCustomBundle" xml --em=default If you don't want to map every entity that can be found in the database, use the --filter option. It will try to match the targeted mapped entity with the provided pattern string. php %command.full_name% "MyCustomBundle" xml --filter=MyMatchedEntity Use the --force option, if you want to override existing mapping files: php %command.full_name% "MyCustomBundle" xml --force EOT ); } /** * {@inheritDoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $bundle = $this->getApplication()->getKernel()->getBundle($input->getArgument('bundle')); $destPath = $bundle->getPath(); $type = $input->getArgument('mapping-type') ? $input->getArgument('mapping-type') : 'xml'; if ('annotation' === $type) { $destPath .= '/Entity'; } else { $destPath .= '/Resources/config/doctrine'; } if ('yaml' === $type) { $type = 'yml'; } $cme = new ClassMetadataExporter(); $exporter = $cme->getExporter($type); $exporter->setOverwriteExistingFiles($input->getOption('force')); if ('annotation' === $type) { $entityGenerator = $this->getEntityGenerator(); $exporter->setEntityGenerator($entityGenerator); } $em = $this->getEntityManager($input->getOption('em'), $input->getOption('shard')); $databaseDriver = new DatabaseDriver($em->getConnection()->getSchemaManager()); $em->getConfiguration()->setMetadataDriverImpl($databaseDriver); $emName = $input->getOption('em'); $emName = $emName ? $emName : 'default'; $cmf = new DisconnectedClassMetadataFactory(); $cmf->setEntityManager($em); $metadata = $cmf->getAllMetadata(); $metadata = MetadataFilter::filter($metadata, $input->getOption('filter')); if ($metadata) { $output->writeln(sprintf('Importing mapping information from "%s" entity manager', $emName)); foreach ($metadata as $class) { $className = $class->name; $class->name = $bundle->getNamespace().'\\Entity\\'.$className; if ('annotation' === $type) { $path = $destPath.'/'.str_replace('\\', '.', $className).'.php'; } else { $path = $destPath.'/'.str_replace('\\', '.', $className).'.orm.'.$type; } $output->writeln(sprintf(' > writing %s', $path)); $code = $exporter->exportClassMetadata($class); if (!is_dir($dir = dirname($path))) { mkdir($dir, 0775, true); } file_put_contents($path, $code); chmod($path, 0664); } return 0; } else { $output->writeln('Database does not have any mapping information.'); $output->writeln(''); return 1; } } } DoctrineBundle-1.8.1/Command/Proxy/000077500000000000000000000000001320601477700171305ustar00rootroot00000000000000DoctrineBundle-1.8.1/Command/Proxy/ClearMetadataCacheDoctrineCommand.php000066400000000000000000000030321320601477700262410ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Doctrine\ORM\Tools\Console\Command\ClearCache\MetadataCommand; /** * Command to clear the metadata cache of the various cache drivers. * * @author Fabien Potencier * @author Jonathan H. Wage */ class ClearMetadataCacheDoctrineCommand extends MetadataCommand { /** * {@inheritDoc} */ protected function configure() { parent::configure(); $this ->setName('doctrine:cache:clear-metadata') ->setDescription('Clears all metadata cache for an entity manager') ->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command'); } /** * {@inheritDoc} */ protected function execute(InputInterface $input, OutputInterface $output) { DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em')); return parent::execute($input, $output); } } DoctrineBundle-1.8.1/Command/Proxy/ClearQueryCacheDoctrineCommand.php000066400000000000000000000030101320601477700256220ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Doctrine\ORM\Tools\Console\Command\ClearCache\QueryCommand; /** * Command to clear the query cache of the various cache drivers. * * @author Fabien Potencier * @author Jonathan H. Wage */ class ClearQueryCacheDoctrineCommand extends QueryCommand { /** * {@inheritDoc} */ protected function configure() { parent::configure(); $this ->setName('doctrine:cache:clear-query') ->setDescription('Clears all query cache for an entity manager') ->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command'); } /** * {@inheritDoc} */ protected function execute(InputInterface $input, OutputInterface $output) { DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em')); return parent::execute($input, $output); } } DoctrineBundle-1.8.1/Command/Proxy/ClearResultCacheDoctrineCommand.php000066400000000000000000000030121320601477700257750ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Doctrine\ORM\Tools\Console\Command\ClearCache\ResultCommand; /** * Command to clear the result cache of the various cache drivers. * * @author Fabien Potencier * @author Jonathan H. Wage */ class ClearResultCacheDoctrineCommand extends ResultCommand { /** * {@inheritDoc} */ protected function configure() { parent::configure(); $this ->setName('doctrine:cache:clear-result') ->setDescription('Clears result cache for an entity manager') ->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command'); } /** * {@inheritDoc} */ protected function execute(InputInterface $input, OutputInterface $output) { DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em')); return parent::execute($input, $output); } } DoctrineBundle-1.8.1/Command/Proxy/CollectionRegionDoctrineCommand.php000066400000000000000000000021401320601477700260640ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; use Doctrine\ORM\Tools\Console\Command\ClearCache\CollectionRegionCommand; /** * Command to clear a collection cache region. * * @author Fabio B. Silva */ class CollectionRegionDoctrineCommand extends DelegateCommand { /** * {@inheritDoc} */ protected function configure() { parent::configure(); $this->setName('doctrine:cache:clear-collection-region'); } /** * {@inheritDoc} */ protected function createCommand() { return new CollectionRegionCommand(); } /** * {@inheritDoc} */ protected function getMinimalVersion() { return '2.5.0-DEV'; } } DoctrineBundle-1.8.1/Command/Proxy/ConvertMappingDoctrineCommand.php000066400000000000000000000042251320601477700255670ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand; use Doctrine\ORM\Tools\Export\Driver\XmlExporter; use Doctrine\ORM\Tools\Export\Driver\YamlExporter; /** * Convert Doctrine ORM metadata mapping information between the various supported * formats. * * @author Fabien Potencier * @author Jonathan H. Wage */ class ConvertMappingDoctrineCommand extends ConvertMappingCommand { /** * {@inheritDoc} */ protected function configure() { parent::configure(); $this ->setName('doctrine:mapping:convert') ->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command'); } /** * {@inheritDoc} */ protected function execute(InputInterface $input, OutputInterface $output) { DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em')); return parent::execute($input, $output); } /** * @param string $toType * @param string $destPath * * @return \Doctrine\ORM\Tools\Export\Driver\AbstractExporter */ protected function getExporter($toType, $destPath) { /** @var $exporter \Doctrine\ORM\Tools\Export\Driver\AbstractExporter */ $exporter = parent::getExporter($toType, $destPath); if ($exporter instanceof XmlExporter) { $exporter->setExtension('.orm.xml'); } elseif ($exporter instanceof YamlExporter) { $exporter->setExtension('.orm.yml'); } return $exporter; } } DoctrineBundle-1.8.1/Command/Proxy/CreateSchemaDoctrineCommand.php000066400000000000000000000030731320601477700251570ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Doctrine\ORM\Tools\Console\Command\SchemaTool\CreateCommand; /** * Command to execute the SQL needed to generate the database schema for * a given entity manager. * * @author Fabien Potencier * @author Jonathan H. Wage */ class CreateSchemaDoctrineCommand extends CreateCommand { /** * {@inheritDoc} */ protected function configure() { parent::configure(); $this ->setName('doctrine:schema:create') ->setDescription('Executes (or dumps) the SQL needed to generate the database schema') ->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command'); } /** * {@inheritDoc} */ protected function execute(InputInterface $input, OutputInterface $output) { DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em')); return parent::execute($input, $output); } } DoctrineBundle-1.8.1/Command/Proxy/DelegateCommand.php000066400000000000000000000060611320601477700226550ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; /** * Command Delegate. * * @author Fabio B. Silva */ abstract class DelegateCommand extends Command { /** * @var \Symfony\Component\Console\Command\Command */ protected $command; /** * @return \Symfony\Component\Console\Command\Command */ abstract protected function createCommand(); /** * @return string */ protected function getMinimalVersion() { return '2.3.0-DEV'; } /** * @return boolean */ private function isVersionCompatible() { return (version_compare(\Doctrine\ORM\Version::VERSION, $this->getMinimalVersion()) >= 0); } /** * {@inheritDoc} */ public function isEnabled() { return $this->isVersionCompatible(); } /** * @param string $entityManagerName * * @return Command */ protected function wrapCommand($entityManagerName) { if (!$this->isVersionCompatible()) { throw new \RuntimeException(sprintf('"%s" requires doctrine-orm "%s" or newer', $this->getName(), $this->getMinimalVersion())); } DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $entityManagerName); $this->command->setApplication($this->getApplication()); return $this->command; } /** * {@inheritDoc} */ protected function configure() { if ($this->isVersionCompatible()) { $this->command = $this->createCommand(); $this->setHelp($this->command->getHelp()); $this->setDefinition($this->command->getDefinition()); $this->setDescription($this->command->getDescription()); } $this->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command'); } /** * {@inheritDoc} */ protected function execute(InputInterface $input, OutputInterface $output) { return $this->wrapCommand($input->getOption('em'))->execute($input, $output); } /** * {@inheritDoc} */ protected function interact(InputInterface $input, OutputInterface $output) { $this->wrapCommand($input->getOption('em'))->interact($input, $output); } /** * {@inheritDoc} */ protected function initialize(InputInterface $input, OutputInterface $output) { $this->wrapCommand($input->getOption('em'))->initialize($input, $output); } } DoctrineBundle-1.8.1/Command/Proxy/DoctrineCommandHelper.php000066400000000000000000000037221320601477700240530ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; use Symfony\Bundle\FrameworkBundle\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 */ abstract class DoctrineCommandHelper { /** * 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) { /** @var $em \Doctrine\ORM\EntityManager */ $em = $application->getKernel()->getContainer()->get('doctrine')->getManager($emName); $helperSet = $application->getHelperSet(); $helperSet->set(new ConnectionHelper($em->getConnection()), 'db'); $helperSet->set(new EntityManagerHelper($em), 'em'); } /** * Convenience method to push the helper sets of a given connection into the application. * * @param Application $application * @param string $connName */ public static function setApplicationConnection(Application $application, $connName) { $connection = $application->getKernel()->getContainer()->get('doctrine')->getConnection($connName); $helperSet = $application->getHelperSet(); $helperSet->set(new ConnectionHelper($connection), 'db'); } } DoctrineBundle-1.8.1/Command/Proxy/DropSchemaDoctrineCommand.php000066400000000000000000000030501320601477700246530ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Doctrine\ORM\Tools\Console\Command\SchemaTool\DropCommand; /** * Command to drop the database schema for a set of classes based on their mappings. * * @author Fabien Potencier * @author Jonathan H. Wage */ class DropSchemaDoctrineCommand extends DropCommand { /** * {@inheritDoc} */ protected function configure() { parent::configure(); $this ->setName('doctrine:schema:drop') ->setDescription('Executes (or dumps) the SQL needed to drop the current database schema') ->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command'); } /** * {@inheritDoc} */ protected function execute(InputInterface $input, OutputInterface $output) { DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em')); return parent::execute($input, $output); } } DoctrineBundle-1.8.1/Command/Proxy/EnsureProductionSettingsDoctrineCommand.php000066400000000000000000000027661320601477700276740ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Doctrine\ORM\Tools\Console\Command\EnsureProductionSettingsCommand; /** * Ensure the Doctrine ORM is configured properly for a production environment. * * @author Fabien Potencier * @author Jonathan H. Wage */ class EnsureProductionSettingsDoctrineCommand extends EnsureProductionSettingsCommand { /** * {@inheritDoc} */ protected function configure() { parent::configure(); $this ->setName('doctrine:ensure-production-settings') ->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command'); } /** * {@inheritDoc} */ protected function execute(InputInterface $input, OutputInterface $output) { DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em')); return parent::execute($input, $output); } } DoctrineBundle-1.8.1/Command/Proxy/EntityRegionCacheDoctrineCommand.php000066400000000000000000000021211320601477700261700ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; use Doctrine\ORM\Tools\Console\Command\ClearCache\EntityRegionCommand; /** * Command to clear a entity cache region. * * @author Fabio B. Silva */ class EntityRegionCacheDoctrineCommand extends DelegateCommand { /** * {@inheritDoc} */ protected function configure() { parent::configure(); $this->setName('doctrine:cache:clear-entity-region'); } /** * {@inheritDoc} */ protected function createCommand() { return new EntityRegionCommand(); } /** * {@inheritDoc} */ protected function getMinimalVersion() { return '2.5.0-DEV'; } } DoctrineBundle-1.8.1/Command/Proxy/ImportDoctrineCommand.php000066400000000000000000000023341320601477700241040ustar00rootroot00000000000000 * @author Sebastian Landwehr */ class ImportDoctrineCommand extends ImportCommand { /** * {@inheritDoc} */ protected function configure() { parent::configure(); $this ->setName('doctrine:database:import') ->addOption('connection', null, InputOption::VALUE_OPTIONAL, 'The connection to use for this command'); } /** * {@inheritDoc} */ protected function execute(InputInterface $input, OutputInterface $output) { DoctrineCommandHelper::setApplicationConnection($this->getApplication(), $input->getOption('connection')); return parent::execute($input, $output); } } DoctrineBundle-1.8.1/Command/Proxy/InfoDoctrineCommand.php000066400000000000000000000024711320601477700235270ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; use Doctrine\ORM\Tools\Console\Command\InfoCommand; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; /** * Show information about mapped entities * * @author Benjamin Eberlei */ class InfoDoctrineCommand extends InfoCommand { /** * {@inheritDoc} */ protected function configure() { $this ->setName('doctrine:mapping:info') ->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command'); } /** * {@inheritDoc} */ protected function execute(InputInterface $input, OutputInterface $output) { DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em')); return parent::execute($input, $output); } } DoctrineBundle-1.8.1/Command/Proxy/QueryRegionCacheDoctrineCommand.php000066400000000000000000000021141320601477700260230ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; use Doctrine\ORM\Tools\Console\Command\ClearCache\QueryRegionCommand; /** * Command to clear a query cache region. * * @author Fabio B. Silva */ class QueryRegionCacheDoctrineCommand extends DelegateCommand { /** * {@inheritDoc} */ protected function configure() { parent::configure(); $this->setName('doctrine:cache:clear-query-region'); } /** * {@inheritDoc} */ protected function createCommand() { return new QueryRegionCommand(); } /** * {@inheritDoc} */ protected function getMinimalVersion() { return '2.5.0-DEV'; } } DoctrineBundle-1.8.1/Command/Proxy/RunDqlDoctrineCommand.php000066400000000000000000000037631320601477700240460ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Doctrine\ORM\Tools\Console\Command\RunDqlCommand; /** * Execute a Doctrine DQL query and output the results. * * @author Fabien Potencier * @author Jonathan H. Wage */ class RunDqlDoctrineCommand extends RunDqlCommand { /** * {@inheritDoc} */ protected function configure() { parent::configure(); $this ->setName('doctrine:query:dql') ->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command') ->setHelp(<<%command.name% command executes the given DQL query and outputs the results: php %command.full_name% "SELECT u FROM UserBundle:User u" You can also optional specify some additional options like what type of hydration to use when executing the query: php %command.full_name% "SELECT u FROM UserBundle:User u" --hydrate=array Additionally you can specify the first result and maximum amount of results to show: php %command.full_name% "SELECT u FROM UserBundle:User u" --first-result=0 --max-result=30 EOT ); } /** * {@inheritDoc} */ protected function execute(InputInterface $input, OutputInterface $output) { DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em')); return parent::execute($input, $output); } } DoctrineBundle-1.8.1/Command/Proxy/RunSqlDoctrineCommand.php000066400000000000000000000031351320601477700240560ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Doctrine\DBAL\Tools\Console\Command\RunSqlCommand; /** * Execute a SQL query and output the results. * * @author Fabien Potencier * @author Jonathan H. Wage */ class RunSqlDoctrineCommand extends RunSqlCommand { /** * {@inheritDoc} */ protected function configure() { parent::configure(); $this ->setName('doctrine:query:sql') ->addOption('connection', null, InputOption::VALUE_OPTIONAL, 'The connection to use for this command') ->setHelp(<<%command.name% command executes the given SQL query and outputs the results: php %command.full_name% "SELECT * FROM users" EOT ); } /** * {@inheritDoc} */ protected function execute(InputInterface $input, OutputInterface $output) { DoctrineCommandHelper::setApplicationConnection($this->getApplication(), $input->getOption('connection')); return parent::execute($input, $output); } } DoctrineBundle-1.8.1/Command/Proxy/UpdateSchemaDoctrineCommand.php000066400000000000000000000027451320601477700252030ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand; /** * Command to generate the SQL needed to update the database schema to match * the current mapping information. * * @author Fabien Potencier * @author Jonathan H. Wage */ class UpdateSchemaDoctrineCommand extends UpdateCommand { /** * {@inheritDoc} */ protected function configure() { parent::configure(); $this ->setName('doctrine:schema:update') ->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command'); } /** * {@inheritDoc} */ protected function execute(InputInterface $input, OutputInterface $output) { DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em')); return parent::execute($input, $output); } } DoctrineBundle-1.8.1/Command/Proxy/ValidateSchemaCommand.php000066400000000000000000000030171320601477700240130ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Doctrine\ORM\Tools\Console\Command\ValidateSchemaCommand as DoctrineValidateSchemaCommand; /** * Command to run Doctrine ValidateSchema() on the current mappings. * * @author Fabien Potencier * @author Jonathan H. Wage * @author Neil Katin */ class ValidateSchemaCommand extends DoctrineValidateSchemaCommand { /** * {@inheritDoc} */ protected function configure() { parent::configure(); $this ->setName('doctrine:schema:validate') ->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command'); } /** * {@inheritDoc} */ protected function execute(InputInterface $input, OutputInterface $output) { DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em')); return parent::execute($input, $output); } } DoctrineBundle-1.8.1/ConnectionFactory.php000066400000000000000000000075261320601477700206030ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle; use Doctrine\Common\EventManager; use Doctrine\DBAL\Configuration; use Doctrine\DBAL\Connection; use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\DBALException; use Doctrine\DBAL\Exception\DriverException; use Doctrine\DBAL\Types\Type; /** * Connection */ class ConnectionFactory { private $typesConfig = array(); private $commentedTypes = array(); private $initialized = false; /** * Construct. * * @param array $typesConfig */ public function __construct(array $typesConfig) { $this->typesConfig = $typesConfig; } /** * Create a connection by name. * * @param array $params * @param Configuration $config * @param EventManager $eventManager * @param array $mappingTypes * * @return \Doctrine\DBAL\Connection */ public function createConnection(array $params, Configuration $config = null, EventManager $eventManager = null, array $mappingTypes = array()) { if (!$this->initialized) { $this->initializeTypes(); } $connection = DriverManager::getConnection($params, $config, $eventManager); if (!empty($mappingTypes)) { $platform = $this->getDatabasePlatform($connection); foreach ($mappingTypes as $dbType => $doctrineType) { $platform->registerDoctrineTypeMapping($dbType, $doctrineType); } } if (!empty($this->commentedTypes)) { $platform = $this->getDatabasePlatform($connection); foreach ($this->commentedTypes as $type) { $platform->markDoctrineTypeCommented(Type::getType($type)); } } return $connection; } /** * Try to get the database platform. * * This could fail if types should be registered to an predefined/unused connection * and the platform version is unknown. * For details have a look at DoctrineBundle issue #673. * * @param \Doctrine\DBAL\Connection $connection * * @return \Doctrine\DBAL\Platforms\AbstractPlatform * @throws \Doctrine\DBAL\DBALException */ private function getDatabasePlatform(Connection $connection) { try { return $connection->getDatabasePlatform(); } catch (DBALException $driverException) { if ($driverException instanceof DriverException) { throw new DBALException( "An exception occured while establishing a connection to figure out your platform version." . PHP_EOL . "You can circumvent this by setting a 'server_version' configuration value" . PHP_EOL . PHP_EOL . "For further information have a look at:" . PHP_EOL . "https://github.com/doctrine/DoctrineBundle/issues/673", 0, $driverException ); } throw $driverException; } } /** * initialize the types */ private function initializeTypes() { foreach ($this->typesConfig as $type => $typeConfig) { if (Type::hasType($type)) { Type::overrideType($type, $typeConfig['class']); } else { Type::addType($type, $typeConfig['class']); } if ($typeConfig['commented']) { $this->commentedTypes[] = $type; } } $this->initialized = true; } } DoctrineBundle-1.8.1/Controller/000077500000000000000000000000001320601477700165545ustar00rootroot00000000000000DoctrineBundle-1.8.1/Controller/ProfilerController.php000066400000000000000000000066601320601477700231230ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Controller; use Doctrine\DBAL\Connection; use Doctrine\DBAL\Platforms\SQLServerPlatform; use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Response; /** * ProfilerController. * * @author Christophe Coevoet */ class ProfilerController implements ContainerAwareInterface { /** * @var ContainerInterface */ private $container; /** * {@inheritDoc} */ public function setContainer(ContainerInterface $container = null) { $this->container = $container; } /** * Renders the profiler panel for the given token. * * @param string $token The profiler token * @param string $connectionName * @param integer $query * * @return Response A Response instance */ public function explainAction($token, $connectionName, $query) { /** @var $profiler \Symfony\Component\HttpKernel\Profiler\Profiler */ $profiler = $this->container->get('profiler'); $profiler->disable(); $profile = $profiler->loadProfile($token); $queries = $profile->getCollector('db')->getQueries(); if (!isset($queries[$connectionName][$query])) { return new Response('This query does not exist.'); } $query = $queries[$connectionName][$query]; if (!$query['explainable']) { return new Response('This query cannot be explained.'); } /** @var $connection \Doctrine\DBAL\Connection */ $connection = $this->container->get('doctrine')->getConnection($connectionName); try { if ($connection->getDatabasePlatform() instanceof SQLServerPlatform) { $results = $this->explainSQLServerPlatform($connection, $query); } else { $results = $this->explainOtherPlatform($connection, $query); } } catch (\Exception $e) { return new Response('This query cannot be explained.'); } return new Response($this->container->get('twig')->render('@Doctrine/Collector/explain.html.twig', array( 'data' => $results, 'query' => $query, ))); } private function explainSQLServerPlatform(Connection $connection, $query) { if (stripos($query['sql'], 'SELECT') === 0) { $sql = 'SET STATISTICS PROFILE ON; ' . $query['sql'] . '; SET STATISTICS PROFILE OFF;'; } else { $sql = 'SET SHOWPLAN_TEXT ON; GO; SET NOEXEC ON; ' . $query['sql'] .'; SET NOEXEC OFF; GO; SET SHOWPLAN_TEXT OFF;'; } $stmt = $connection->executeQuery($sql, $query['params'], $query['types']); $stmt->nextRowset(); return $stmt->fetchAll(\PDO::FETCH_ASSOC); } private function explainOtherPlatform(Connection $connection, $query) { return $connection->executeQuery('EXPLAIN '.$query['sql'], $query['params'], $query['types']) ->fetchAll(\PDO::FETCH_ASSOC); } } DoctrineBundle-1.8.1/DataCollector/000077500000000000000000000000001320601477700171515ustar00rootroot00000000000000DoctrineBundle-1.8.1/DataCollector/DoctrineDataCollector.php000066400000000000000000000211261320601477700240740ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\DataCollector; use Doctrine\Common\Persistence\ManagerRegistry; use Doctrine\ORM\Tools\SchemaValidator; use Doctrine\ORM\Version; use Symfony\Bridge\Doctrine\DataCollector\DoctrineDataCollector as BaseCollector; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\VarDumper\Cloner\Data; /** * DoctrineDataCollector. * * @author Christophe Coevoet */ class DoctrineDataCollector extends BaseCollector { private $registry; private $invalidEntityCount; public function __construct(ManagerRegistry $registry) { $this->registry = $registry; parent::__construct($registry); } /** * {@inheritdoc} */ public function collect(Request $request, Response $response, \Exception $exception = null) { parent::collect($request, $response, $exception); $errors = array(); $entities = array(); $caches = array( 'enabled' => false, 'log_enabled' => false, 'counts' => array( 'puts' => 0, 'hits' => 0, 'misses' => 0, ), 'regions' => array( 'puts' => array(), 'hits' => array(), 'misses' => array(), ), ); foreach ($this->registry->getManagers() as $name => $em) { $entities[$name] = array(); /** @var $factory \Doctrine\ORM\Mapping\ClassMetadataFactory */ $factory = $em->getMetadataFactory(); $validator = new SchemaValidator($em); /** @var $class \Doctrine\ORM\Mapping\ClassMetadataInfo */ foreach ($factory->getLoadedMetadata() as $class) { if (!isset($entities[$name][$class->getName()])) { $classErrors = $validator->validateClass($class); $entities[$name][$class->getName()] = $class->getName(); if (!empty($classErrors)) { $errors[$name][$class->getName()] = $classErrors; } } } if (version_compare(Version::VERSION, '2.5.0-DEV') < 0) { continue; } /** @var $emConfig \Doctrine\ORM\Configuration */ $emConfig = $em->getConfiguration(); $slcEnabled = $emConfig->isSecondLevelCacheEnabled(); if (!$slcEnabled) { continue; } $caches['enabled'] = true; /** @var $cacheConfiguration \Doctrine\ORM\Cache\CacheConfiguration */ /** @var $cacheLoggerChain \Doctrine\ORM\Cache\Logging\CacheLoggerChain */ $cacheConfiguration = $emConfig->getSecondLevelCacheConfiguration(); $cacheLoggerChain = $cacheConfiguration->getCacheLogger(); if (!$cacheLoggerChain || !$cacheLoggerChain->getLogger('statistics')) { continue; } /** @var $cacheLoggerStats \Doctrine\ORM\Cache\Logging\StatisticsCacheLogger */ $cacheLoggerStats = $cacheLoggerChain->getLogger('statistics'); $caches['log_enabled'] = true; $caches['counts']['puts'] += $cacheLoggerStats->getPutCount(); $caches['counts']['hits'] += $cacheLoggerStats->getHitCount(); $caches['counts']['misses'] += $cacheLoggerStats->getMissCount(); foreach ($cacheLoggerStats->getRegionsPut() as $key => $value) { if (!isset($caches['regions']['puts'][$key])) { $caches['regions']['puts'][$key] = 0; } $caches['regions']['puts'][$key] += $value; } foreach ($cacheLoggerStats->getRegionsHit() as $key => $value) { if (!isset($caches['regions']['hits'][$key])) { $caches['regions']['hits'][$key] = 0; } $caches['regions']['hits'][$key] += $value; } foreach ($cacheLoggerStats->getRegionsMiss() as $key => $value) { if (!isset($caches['regions']['misses'][$key])) { $caches['regions']['misses'][$key] = 0; } $caches['regions']['misses'][$key] += $value; } } // HttpKernel < 3.2 compatibility layer if (method_exists($this, 'cloneVar')) { // Might be good idea to replicate this block in doctrine bridge so we can drop this from here after some time. // This code is compatible with such change, because cloneVar is supposed to check if input is already cloned. foreach ($this->data['queries'] as &$queries) { foreach ($queries as &$query) { $query['params'] = $this->cloneVar($query['params']); } } } $this->data['entities'] = $entities; $this->data['errors'] = $errors; $this->data['caches'] = $caches; } public function getEntities() { return $this->data['entities']; } public function getMappingErrors() { return $this->data['errors']; } public function getCacheHitsCount() { return $this->data['caches']['counts']['hits']; } public function getCachePutsCount() { return $this->data['caches']['counts']['puts']; } public function getCacheMissesCount() { return $this->data['caches']['counts']['misses']; } public function getCacheEnabled() { return $this->data['caches']['enabled']; } public function getCacheRegions() { return $this->data['caches']['regions']; } public function getCacheCounts() { return $this->data['caches']['counts']; } public function getInvalidEntityCount() { if (null === $this->invalidEntityCount) { $this->invalidEntityCount = array_sum(array_map('count', $this->data['errors'])); } return $this->invalidEntityCount; } public function getGroupedQueries() { static $groupedQueries = null; if ($groupedQueries !== null) { return $groupedQueries; } $groupedQueries = array(); $totalExecutionMS = 0; foreach ($this->data['queries'] as $connection => $queries) { $connectionGroupedQueries = array(); foreach ($queries as $i => $query) { $key = $query['sql']; if (!isset($connectionGroupedQueries[$key])) { $connectionGroupedQueries[$key] = $query; $connectionGroupedQueries[$key]['executionMS'] = 0; $connectionGroupedQueries[$key]['count'] = 0; $connectionGroupedQueries[$key]['index'] = $i; // "Explain query" relies on query index in 'queries'. } $connectionGroupedQueries[$key]['executionMS'] += $query['executionMS']; $connectionGroupedQueries[$key]['count']++; $totalExecutionMS += $query['executionMS']; } usort($connectionGroupedQueries, function ($a, $b) { if ($a['executionMS'] === $b['executionMS']) { return 0; } return ($a['executionMS'] < $b['executionMS']) ? 1 : -1; }); $groupedQueries[$connection] = $connectionGroupedQueries; } foreach ($groupedQueries as $connection => $queries) { foreach ($queries as $i => $query) { $groupedQueries[$connection][$i]['executionPercent'] = $this->executionTimePercentage($query['executionMS'], $totalExecutionMS); } } return $groupedQueries; } private function executionTimePercentage($executionTimeMS, $totalExecutionTimeMS) { if ($totalExecutionTimeMS === 0.0 || $totalExecutionTimeMS === 0) { return 0; } return $executionTimeMS / $totalExecutionTimeMS * 100; } public function getGroupedQueryCount() { $count = 0; foreach ($this->getGroupedQueries() as $connectionGroupedQueries) { $count += count($connectionGroupedQueries); } return $count; } } DoctrineBundle-1.8.1/DependencyInjection/000077500000000000000000000000001320601477700203525ustar00rootroot00000000000000DoctrineBundle-1.8.1/DependencyInjection/Compiler/000077500000000000000000000000001320601477700221245ustar00rootroot00000000000000DoctrineBundle-1.8.1/DependencyInjection/Compiler/DoctrineOrmMappingsPass.php000066400000000000000000000216601320601477700274150ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler; use Symfony\Bridge\Doctrine\DependencyInjection\CompilerPass\RegisterMappingsPass; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; /** * Class for Symfony bundles to configure mappings for model classes not in the * auto-mapped folder. * * NOTE: alias is only supported by Symfony 2.6+ and will be ignored with older versions. * * @author David Buchmann */ class DoctrineOrmMappingsPass extends RegisterMappingsPass { /** * You should not directly instantiate this class but use one of the * factory methods. * * @param Definition|Reference $driver Driver DI definition or reference. * @param array $namespaces List of namespaces handled by $driver. * @param string[] $managerParameters Ordered list of container parameters that * could hold the manager name. * doctrine.default_entity_manager is appended * automatically. * @param string|false $enabledParameter If specified, the compiler pass only executes * if this parameter is defined in the service * container. * @param array $aliasMap Map of alias to namespace. */ public function __construct($driver, array $namespaces, array $managerParameters, $enabledParameter = false, array $aliasMap = array()) { $managerParameters[] = 'doctrine.default_entity_manager'; parent::__construct( $driver, $namespaces, $managerParameters, 'doctrine.orm.%s_metadata_driver', $enabledParameter, 'doctrine.orm.%s_configuration', 'addEntityNamespace', $aliasMap ); } /** * @param array $namespaces Hashmap of directory path to namespace. * @param string[] $managerParameters List of parameters that could which object manager name * your bundle uses. This compiler pass will automatically * append the parameter name for the default entity manager * to this list. * @param string|false $enabledParameter Service container parameter that must be present to * enable the mapping. Set to false to not do any check, * optional. * @param string[] $aliasMap Map of alias to namespace. * * @return self */ public static function createXmlMappingDriver(array $namespaces, array $managerParameters = array(), $enabledParameter = false, array $aliasMap = array()) { $arguments = array($namespaces, '.orm.xml'); $locator = new Definition('Doctrine\Common\Persistence\Mapping\Driver\SymfonyFileLocator', $arguments); $driver = new Definition('Doctrine\ORM\Mapping\Driver\XmlDriver', array($locator)); return new DoctrineOrmMappingsPass($driver, $namespaces, $managerParameters, $enabledParameter, $aliasMap); } /** * @param array $namespaces Hashmap of directory path to namespace * @param string[] $managerParameters List of parameters that could which object manager name * your bundle uses. This compiler pass will automatically * append the parameter name for the default entity manager * to this list. * @param string|false $enabledParameter Service container parameter that must be present to * enable the mapping. Set to false to not do any check, * optional. * @param string[] $aliasMap Map of alias to namespace. * * @return self */ public static function createYamlMappingDriver(array $namespaces, array $managerParameters = array(), $enabledParameter = false, array $aliasMap = array()) { $arguments = array($namespaces, '.orm.yml'); $locator = new Definition('Doctrine\Common\Persistence\Mapping\Driver\SymfonyFileLocator', $arguments); $driver = new Definition('Doctrine\ORM\Mapping\Driver\YamlDriver', array($locator)); return new DoctrineOrmMappingsPass($driver, $namespaces, $managerParameters, $enabledParameter, $aliasMap); } /** * @param array $namespaces Hashmap of directory path to namespace * @param string[] $managerParameters List of parameters that could which object manager name * your bundle uses. This compiler pass will automatically * append the parameter name for the default entity manager * to this list. * @param string $enabledParameter Service container parameter that must be present to * enable the mapping. Set to false to not do any check, * optional. * @param string[] $aliasMap Map of alias to namespace. * * @return self */ public static function createPhpMappingDriver(array $namespaces, array $managerParameters = array(), $enabledParameter = false, array $aliasMap = array()) { $arguments = array($namespaces, '.php'); $locator = new Definition('Doctrine\Common\Persistence\Mapping\Driver\SymfonyFileLocator', $arguments); $driver = new Definition('Doctrine\Common\Persistence\Mapping\Driver\PHPDriver', array($locator)); return new DoctrineOrmMappingsPass($driver, $namespaces, $managerParameters, $enabledParameter, $aliasMap); } /** * @param array $namespaces List of namespaces that are handled with annotation mapping * @param array $directories List of directories to look for annotated classes * @param string[] $managerParameters List of parameters that could which object manager name * your bundle uses. This compiler pass will automatically * append the parameter name for the default entity manager * to this list. * @param string|false $enabledParameter Service container parameter that must be present to * enable the mapping. Set to false to not do any check, * optional. * @param string[] $aliasMap Map of alias to namespace. * * @return self */ public static function createAnnotationMappingDriver(array $namespaces, array $directories, array $managerParameters = array(), $enabledParameter = false, array $aliasMap = array()) { $reader = new Reference('annotation_reader'); $driver = new Definition('Doctrine\ORM\Mapping\Driver\AnnotationDriver', array($reader, $directories)); return new DoctrineOrmMappingsPass($driver, $namespaces, $managerParameters, $enabledParameter, $aliasMap); } /** * @param array $namespaces List of namespaces that are handled with static php mapping * @param array $directories List of directories to look for static php mapping files * @param string[] $managerParameters List of parameters that could which object manager name * your bundle uses. This compiler pass will automatically * append the parameter name for the default entity manager * to this list. * @param string|false $enabledParameter Service container parameter that must be present to * enable the mapping. Set to false to not do any check, * optional. * @param string[] $aliasMap Map of alias to namespace. * * @return self */ public static function createStaticPhpMappingDriver(array $namespaces, array $directories, array $managerParameters = array(), $enabledParameter = false, array $aliasMap = array()) { $driver = new Definition('Doctrine\Common\Persistence\Mapping\Driver\StaticPHPDriver', array($directories)); return new DoctrineOrmMappingsPass($driver, $namespaces, $managerParameters, $enabledParameter, $aliasMap); } } DoctrineBundle-1.8.1/DependencyInjection/Compiler/EntityListenerPass.php000066400000000000000000000076521320601477700264600ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Reference; /** * Class for Symfony bundles to register entity listeners * * @author Sander Marechal */ class EntityListenerPass implements CompilerPassInterface { /** * {@inheritDoc} */ public function process(ContainerBuilder $container) { $resolvers = $container->findTaggedServiceIds('doctrine.orm.entity_listener'); foreach ($resolvers as $id => $tagAttributes) { foreach ($tagAttributes as $attributes) { $name = isset($attributes['entity_manager']) ? $attributes['entity_manager'] : $container->getParameter('doctrine.default_entity_manager'); $entityManager = sprintf('doctrine.orm.%s_entity_manager', $name); if (!$container->hasDefinition($entityManager)) { continue; } $resolverId = sprintf('doctrine.orm.%s_entity_listener_resolver', $name); if (!$container->has($resolverId)) { continue; } $resolver = $container->findDefinition($resolverId); $resolver->setPublic(true); if (isset($attributes['entity']) && isset($attributes['event'])) { $this->attachToListener($container, $name, $id, $attributes); } if (isset($attributes['lazy']) && $attributes['lazy']) { $listener = $container->findDefinition($id); if ($listener->isAbstract()) { throw new InvalidArgumentException(sprintf('The service "%s" must not be abstract as this entity listener is lazy-loaded.', $id)); } $interface = 'Doctrine\\Bundle\\DoctrineBundle\\Mapping\\EntityListenerServiceResolver'; $class = $resolver->getClass(); if (substr($class, 0, 1) === '%') { // resolve container parameter first $class = $container->getParameterBag()->resolveValue($resolver->getClass()); } if (!is_a($class, $interface, true)) { throw new InvalidArgumentException( sprintf('Lazy-loaded entity listeners can only be resolved by a resolver implementing %s.', $interface) ); } $listener->setPublic(true); $resolver->addMethodCall('registerService', array($listener->getClass(), $id)); } else { $resolver->addMethodCall('register', array(new Reference($id))); } } } } private function attachToListener(ContainerBuilder $container, $name, $id, array $attributes) { $listenerId = sprintf('doctrine.orm.%s_listeners.attach_entity_listeners', $name); if (!$container->has($listenerId)) { return; } $serviceDef = $container->getDefinition($id); $args = array( $attributes['entity'], $serviceDef->getClass(), $attributes['event'], ); if (isset($attributes['method'])) { $args[] = $attributes['method']; } $container->findDefinition($listenerId)->addMethodCall('addEntityListener', $args); } } DoctrineBundle-1.8.1/DependencyInjection/Compiler/ServiceRepositoryCompilerPass.php000066400000000000000000000041241320601477700306600ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Exception\RuntimeException; use Symfony\Component\DependencyInjection\Reference; /** * @author Ryan Weaver */ final class ServiceRepositoryCompilerPass implements CompilerPassInterface { const REPOSITORY_SERVICE_TAG = 'doctrine.repository_service'; public function process(ContainerBuilder $container) { // when ORM is not enabled if (!$container->hasDefinition('doctrine.orm.container_repository_factory')) { return; } $locatorDef = $container->getDefinition('doctrine.orm.container_repository_factory'); $repoServiceIds = array_keys($container->findTaggedServiceIds(self::REPOSITORY_SERVICE_TAG)); // Symfony 3.2 and lower sanity check if (!class_exists(ServiceLocatorTagPass::class)) { if (!empty($repoServiceIds)) { throw new RuntimeException(sprintf('The "%s" tag can only be used with Symfony 3.3 or higher. Remove the tag from the following services (%s) or upgrade to Symfony 3.3 or higher.', self::REPOSITORY_SERVICE_TAG, implode(', ', $repoServiceIds))); } return; } $repoReferences = array_map(function ($id) { return new Reference($id); }, $repoServiceIds); $ref = ServiceLocatorTagPass::register($container, array_combine($repoServiceIds, $repoReferences)); $locatorDef->replaceArgument(0, $ref); } } DoctrineBundle-1.8.1/DependencyInjection/Configuration.php000066400000000000000000000712271320601477700237030ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; /** * This class contains the configuration information for the bundle * * This information is solely responsible for how the different configuration * sections are normalized, and merged. * * @author Christophe Coevoet */ class Configuration implements ConfigurationInterface { private $debug; /** * Constructor * * @param Boolean $debug Whether to use the debug mode */ public function __construct($debug) { $this->debug = (Boolean) $debug; } /** * {@inheritDoc} */ public function getConfigTreeBuilder() { $treeBuilder = new TreeBuilder(); $rootNode = $treeBuilder->root('doctrine'); $this->addDbalSection($rootNode); $this->addOrmSection($rootNode); return $treeBuilder; } /** * Add DBAL section to configuration tree * * @param ArrayNodeDefinition $node */ private function addDbalSection(ArrayNodeDefinition $node) { $node ->children() ->arrayNode('dbal') ->beforeNormalization() ->ifTrue(function ($v) { return is_array($v) && !array_key_exists('connections', $v) && !array_key_exists('connection', $v); }) ->then(function ($v) { // Key that should not be rewritten to the connection config $excludedKeys = array('default_connection' => true, 'types' => true, 'type' => true); $connection = array(); foreach ($v as $key => $value) { if (isset($excludedKeys[$key])) { continue; } $connection[$key] = $v[$key]; unset($v[$key]); } $v['default_connection'] = isset($v['default_connection']) ? (string) $v['default_connection'] : 'default'; $v['connections'] = array($v['default_connection'] => $connection); return $v; }) ->end() ->children() ->scalarNode('default_connection')->end() ->end() ->fixXmlConfig('type') ->children() ->arrayNode('types') ->useAttributeAsKey('name') ->prototype('array') ->beforeNormalization() ->ifString() ->then(function ($v) { return array('class' => $v); }) ->end() ->children() ->scalarNode('class')->isRequired()->end() ->booleanNode('commented')->defaultTrue()->end() ->end() ->end() ->end() ->end() ->fixXmlConfig('connection') ->append($this->getDbalConnectionsNode()) ->end() ; } /** * Return the dbal connections node * * @return ArrayNodeDefinition */ private function getDbalConnectionsNode() { $treeBuilder = new TreeBuilder(); $node = $treeBuilder->root('connections'); /** @var $connectionNode ArrayNodeDefinition */ $connectionNode = $node ->requiresAtLeastOneElement() ->useAttributeAsKey('name') ->prototype('array') ; $this->configureDbalDriverNode($connectionNode); $connectionNode ->fixXmlConfig('option') ->fixXmlConfig('mapping_type') ->fixXmlConfig('slave') ->fixXmlConfig('shard') ->fixXmlConfig('default_table_option') ->children() ->scalarNode('driver')->defaultValue('pdo_mysql')->end() ->scalarNode('platform_service')->end() ->booleanNode('auto_commit')->end() ->scalarNode('schema_filter')->end() ->booleanNode('logging')->defaultValue($this->debug)->end() ->booleanNode('profiling')->defaultValue($this->debug)->end() ->scalarNode('server_version')->end() ->scalarNode('driver_class')->end() ->scalarNode('wrapper_class')->end() ->scalarNode('shard_manager_class')->end() ->scalarNode('shard_choser')->end() ->scalarNode('shard_choser_service')->end() ->booleanNode('keep_slave')->end() ->arrayNode('options') ->useAttributeAsKey('key') ->prototype('scalar')->end() ->end() ->arrayNode('mapping_types') ->useAttributeAsKey('name') ->prototype('scalar')->end() ->end() ->arrayNode('default_table_options') ->info("This option is used by the schema-tool and affects generated SQL. Possible keys include 'charset','collate', and 'engine'.") ->useAttributeAsKey('name') ->prototype('scalar')->end() ->end() ->end() ; $slaveNode = $connectionNode ->children() ->arrayNode('slaves') ->useAttributeAsKey('name') ->prototype('array') ; $this->configureDbalDriverNode($slaveNode); $shardNode = $connectionNode ->children() ->arrayNode('shards') ->prototype('array') ->children() ->integerNode('id') ->min(1) ->isRequired() ->end() ->end() ; $this->configureDbalDriverNode($shardNode); return $node; } /** * Adds config keys related to params processed by the DBAL drivers * * These keys are available for slave configurations too. * * @param ArrayNodeDefinition $node */ private function configureDbalDriverNode(ArrayNodeDefinition $node) { $node ->children() ->scalarNode('url')->info('A URL with connection information; any parameter value parsed from this string will override explicitly set parameters')->end() ->scalarNode('dbname')->end() ->scalarNode('host')->defaultValue('localhost')->end() ->scalarNode('port')->defaultNull()->end() ->scalarNode('user')->defaultValue('root')->end() ->scalarNode('password')->defaultNull()->end() ->scalarNode('application_name')->end() ->scalarNode('charset')->end() ->scalarNode('path')->end() ->booleanNode('memory')->end() ->scalarNode('unix_socket')->info('The unix socket to use for MySQL')->end() ->booleanNode('persistent')->info('True to use as persistent connection for the ibm_db2 driver')->end() ->scalarNode('protocol')->info('The protocol to use for the ibm_db2 driver (default to TCPIP if ommited)')->end() ->booleanNode('service') ->info('True to use SERVICE_NAME as connection parameter instead of SID for Oracle') ->end() ->scalarNode('servicename') ->info( 'Overrules dbname parameter if given and used as SERVICE_NAME or SID connection parameter '. 'for Oracle depending on the service parameter.' ) ->end() ->scalarNode('sessionMode') ->info('The session mode to use for the oci8 driver') ->end() ->scalarNode('server') ->info('The name of a running database server to connect to for SQL Anywhere.') ->end() ->scalarNode('sslmode') ->info( 'Determines whether or with what priority a SSL TCP/IP connection will be negotiated with '. 'the server for PostgreSQL.' ) ->end() ->scalarNode('sslrootcert') ->info( 'The name of a file containing SSL certificate authority (CA) certificate(s). '. 'If the file exists, the server\'s certificate will be verified to be signed by one of these authorities.' ) ->end() ->booleanNode('pooled')->info('True to use a pooled server with the oci8/pdo_oracle driver')->end() ->booleanNode('MultipleActiveResultSets')->info('Configuring MultipleActiveResultSets for the pdo_sqlsrv driver')->end() ->booleanNode('use_savepoints')->info('Use savepoints for nested transactions')->end() ->scalarNode('instancename') ->info( 'Optional parameter, complete whether to add the INSTANCE_NAME parameter in the connection.'. ' It is generally used to connect to an Oracle RAC server to select the name'. ' of a particular instance.' ) ->end() ->scalarNode('connectstring') ->info( 'Complete Easy Connect connection descriptor, see https://docs.oracle.com/database/121/NETAG/naming.htm.'. 'When using this option, you will still need to provide the user and password parameters, but the other '. 'parameters will no longer be used. Note that when using this parameter, the getHost and getPort methods'. ' from Doctrine\DBAL\Connection will no longer function as expected.' ) ->end() ->end() ->beforeNormalization() ->ifTrue(function ($v) {return !isset($v['sessionMode']) && isset($v['session_mode']);}) ->then(function ($v) { $v['sessionMode'] = $v['session_mode']; unset($v['session_mode']); return $v; }) ->end() ->beforeNormalization() ->ifTrue(function ($v) {return !isset($v['MultipleActiveResultSets']) && isset($v['multiple_active_result_sets']);}) ->then(function ($v) { $v['MultipleActiveResultSets'] = $v['multiple_active_result_sets']; unset($v['multiple_active_result_sets']); return $v; }) ->end() ; } /** * Add the ORM section to configuration tree * * @param ArrayNodeDefinition $node */ private function addOrmSection(ArrayNodeDefinition $node) { $generationModes = $this->getAutoGenerateModes(); $node ->children() ->arrayNode('orm') ->beforeNormalization() ->ifTrue(function ($v) { return null === $v || (is_array($v) && !array_key_exists('entity_managers', $v) && !array_key_exists('entity_manager', $v)); }) ->then(function ($v) { $v = (array) $v; // Key that should not be rewritten to the connection config $excludedKeys = array( 'default_entity_manager' => true, 'auto_generate_proxy_classes' => true, 'proxy_dir' => true, 'proxy_namespace' => true, 'resolve_target_entities' => true, 'resolve_target_entity' => true, ); $entityManager = array(); foreach ($v as $key => $value) { if (isset($excludedKeys[$key])) { continue; } $entityManager[$key] = $v[$key]; unset($v[$key]); } $v['default_entity_manager'] = isset($v['default_entity_manager']) ? (string) $v['default_entity_manager'] : 'default'; $v['entity_managers'] = array($v['default_entity_manager'] => $entityManager); return $v; }) ->end() ->children() ->scalarNode('default_entity_manager')->end() ->scalarNode('auto_generate_proxy_classes')->defaultValue(false) ->info('Auto generate mode possible values are: "NEVER", "ALWAYS", "FILE_NOT_EXISTS", "EVAL"') ->validate() ->ifTrue(function ($v) use ($generationModes) { if (is_int($v) && in_array($v, $generationModes['values']/*array(0, 1, 2, 3)*/)) { return false; } if (is_bool($v)) { return false; } if (is_string($v)) { if (in_array(strtoupper($v), $generationModes['names']/*array('NEVER', 'ALWAYS', 'FILE_NOT_EXISTS', 'EVAL')*/)) { return false; } } return true; }) ->thenInvalid('Invalid auto generate mode value %s') ->end() ->validate() ->ifString() ->then(function ($v) { return constant('Doctrine\Common\Proxy\AbstractProxyFactory::AUTOGENERATE_'.strtoupper($v)); }) ->end() ->end() ->scalarNode('proxy_dir')->defaultValue('%kernel.cache_dir%/doctrine/orm/Proxies')->end() ->scalarNode('proxy_namespace')->defaultValue('Proxies')->end() ->end() ->fixXmlConfig('entity_manager') ->append($this->getOrmEntityManagersNode()) ->fixXmlConfig('resolve_target_entity', 'resolve_target_entities') ->append($this->getOrmTargetEntityResolverNode()) ->end() ->end() ; } /** * Return ORM target entity resolver node * * @return \Symfony\Component\Config\Definition\Builder\NodeDefinition */ private function getOrmTargetEntityResolverNode() { $treeBuilder = new TreeBuilder(); $node = $treeBuilder->root('resolve_target_entities'); $node ->useAttributeAsKey('interface') ->prototype('scalar') ->cannotBeEmpty() ->end() ; return $node; } /** * Return ORM entity listener node * * @return \Symfony\Component\Config\Definition\Builder\NodeDefinition */ private function getOrmEntityListenersNode() { $builder = new TreeBuilder(); $node = $builder->root('entity_listeners'); $normalizer = function ($mappings) { $entities = array(); foreach ($mappings as $entityClass => $mapping) { $listeners = array(); foreach ($mapping as $listenerClass => $listenerEvent) { $events = array(); foreach ($listenerEvent as $eventType => $eventMapping) { if ($eventMapping === null) { $eventMapping = array(null); } foreach ($eventMapping as $method) { $events[] = array( 'type' => $eventType, 'method' => $method, ); } } $listeners[] = array( 'class' => $listenerClass, 'event' => $events, ); } $entities[] = array( 'class' => $entityClass, 'listener' => $listeners, ); } return array('entities' => $entities); }; $node ->beforeNormalization() // Yaml normalization ->ifTrue(function ($v) { return is_array(reset($v)) && is_string(key(reset($v))); }) ->then($normalizer) ->end() ->fixXmlConfig('entity', 'entities') ->children() ->arrayNode('entities') ->useAttributeAsKey('class') ->prototype('array') ->fixXmlConfig('listener') ->children() ->arrayNode('listeners') ->useAttributeAsKey('class') ->prototype('array') ->fixXmlConfig('event') ->children() ->arrayNode('events') ->prototype('array') ->children() ->scalarNode('type')->end() ->scalarNode('method')->defaultNull()->end() ->end() ->end() ->end() ->end() ->end() ->end() ->end() ->end() ->end() ->end() ; return $node; } /** * Return ORM entity manager node * * @return ArrayNodeDefinition */ private function getOrmEntityManagersNode() { $treeBuilder = new TreeBuilder(); $node = $treeBuilder->root('entity_managers'); $node ->requiresAtLeastOneElement() ->useAttributeAsKey('name') ->prototype('array') ->addDefaultsIfNotSet() ->append($this->getOrmCacheDriverNode('query_cache_driver')) ->append($this->getOrmCacheDriverNode('metadata_cache_driver')) ->append($this->getOrmCacheDriverNode('result_cache_driver')) ->append($this->getOrmEntityListenersNode()) ->children() ->scalarNode('connection')->end() ->scalarNode('class_metadata_factory_name')->defaultValue('Doctrine\ORM\Mapping\ClassMetadataFactory')->end() ->scalarNode('default_repository_class')->defaultValue('Doctrine\ORM\EntityRepository')->end() ->scalarNode('auto_mapping')->defaultFalse()->end() ->scalarNode('naming_strategy')->defaultValue('doctrine.orm.naming_strategy.default')->end() ->scalarNode('quote_strategy')->defaultValue('doctrine.orm.quote_strategy.default')->end() ->scalarNode('entity_listener_resolver')->defaultNull()->end() ->scalarNode('repository_factory')->defaultValue('doctrine.orm.container_repository_factory')->end() ->end() ->children() ->arrayNode('second_level_cache') ->children() ->append($this->getOrmCacheDriverNode('region_cache_driver')) ->scalarNode('region_lock_lifetime')->defaultValue(60)->end() ->booleanNode('log_enabled')->defaultValue($this->debug)->end() ->scalarNode('region_lifetime')->defaultValue(0)->end() ->booleanNode('enabled')->defaultValue(true)->end() ->scalarNode('factory')->end() ->end() ->fixXmlConfig('region') ->children() ->arrayNode('regions') ->useAttributeAsKey('name') ->prototype('array') ->children() ->append($this->getOrmCacheDriverNode('cache_driver')) ->scalarNode('lock_path')->defaultValue('%kernel.cache_dir%/doctrine/orm/slc/filelock')->end() ->scalarNode('lock_lifetime')->defaultValue(60)->end() ->scalarNode('type')->defaultValue('default')->end() ->scalarNode('lifetime')->defaultValue(0)->end() ->scalarNode('service')->end() ->scalarNode('name')->end() ->end() ->end() ->end() ->end() ->fixXmlConfig('logger') ->children() ->arrayNode('loggers') ->useAttributeAsKey('name') ->prototype('array') ->children() ->scalarNode('name')->end() ->scalarNode('service')->end() ->end() ->end() ->end() ->end() ->end() ->end() ->fixXmlConfig('hydrator') ->children() ->arrayNode('hydrators') ->useAttributeAsKey('name') ->prototype('scalar')->end() ->end() ->end() ->fixXmlConfig('mapping') ->children() ->arrayNode('mappings') ->useAttributeAsKey('name') ->prototype('array') ->beforeNormalization() ->ifString() ->then(function ($v) { return array('type' => $v); }) ->end() ->treatNullLike(array()) ->treatFalseLike(array('mapping' => false)) ->performNoDeepMerging() ->children() ->scalarNode('mapping')->defaultValue(true)->end() ->scalarNode('type')->end() ->scalarNode('dir')->end() ->scalarNode('alias')->end() ->scalarNode('prefix')->end() ->booleanNode('is_bundle')->end() ->end() ->end() ->end() ->arrayNode('dql') ->fixXmlConfig('string_function') ->fixXmlConfig('numeric_function') ->fixXmlConfig('datetime_function') ->children() ->arrayNode('string_functions') ->useAttributeAsKey('name') ->prototype('scalar')->end() ->end() ->arrayNode('numeric_functions') ->useAttributeAsKey('name') ->prototype('scalar')->end() ->end() ->arrayNode('datetime_functions') ->useAttributeAsKey('name') ->prototype('scalar')->end() ->end() ->end() ->end() ->end() ->fixXmlConfig('filter') ->children() ->arrayNode('filters') ->info('Register SQL Filters in the entity manager') ->useAttributeAsKey('name') ->prototype('array') ->beforeNormalization() ->ifString() ->then(function ($v) { return array('class' => $v); }) ->end() ->beforeNormalization() // The content of the XML node is returned as the "value" key so we need to rename it ->ifTrue(function ($v) { return is_array($v) && isset($v['value']); }) ->then(function ($v) { $v['class'] = $v['value']; unset($v['value']); return $v; }) ->end() ->fixXmlConfig('parameter') ->children() ->scalarNode('class')->isRequired()->end() ->booleanNode('enabled')->defaultFalse()->end() ->arrayNode('parameters') ->useAttributeAsKey('name') ->prototype('variable')->end() ->end() ->end() ->end() ->end() ->end() ->end() ; return $node; } /** * Return a ORM cache driver node for an given entity manager * * @param string $name * * @return ArrayNodeDefinition */ private function getOrmCacheDriverNode($name) { $treeBuilder = new TreeBuilder(); $node = $treeBuilder->root($name); $node ->addDefaultsIfNotSet() ->beforeNormalization() ->ifString() ->then(function ($v) { return array('type' => $v); }) ->end() ->children() ->scalarNode('type')->defaultValue('array')->end() ->scalarNode('host')->end() ->scalarNode('port')->end() ->scalarNode('database')->end() ->scalarNode('instance_class')->end() ->scalarNode('class')->end() ->scalarNode('id')->end() ->scalarNode('namespace')->defaultNull()->end() ->scalarNode('cache_provider')->defaultNull()->end() ->end() ; return $node; } /** * Find proxy auto generate modes for their names and int values * * @return array */ private function getAutoGenerateModes() { $constPrefix = 'AUTOGENERATE_'; $prefixLen = strlen($constPrefix); $refClass = new \ReflectionClass('Doctrine\Common\Proxy\AbstractProxyFactory'); $constsArray = $refClass->getConstants(); $namesArray = array(); $valuesArray = array(); foreach ($constsArray as $key => $value) { if (strpos($key, $constPrefix) === 0) { $namesArray[] = substr($key, $prefixLen); $valuesArray[] = (int) $value; } } return array( 'names' => $namesArray, 'values' => $valuesArray, ); } } DoctrineBundle-1.8.1/DependencyInjection/DoctrineExtension.php000066400000000000000000001110761320601477700245350ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection; use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\ServiceRepositoryCompilerPass; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepositoryInterface; use Doctrine\ORM\Version; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Alias; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\DefinitionDecorator; use Symfony\Component\DependencyInjection\ChildDefinition; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\ServiceLocator; use Symfony\Component\Form\AbstractType; use Symfony\Bridge\Doctrine\DependencyInjection\AbstractDoctrineExtension; use Symfony\Bridge\Doctrine\Form\Type\DoctrineType; use Symfony\Component\Config\FileLocator; use Doctrine\Bundle\DoctrineCacheBundle\DependencyInjection\SymfonyBridgeAdapter; use Doctrine\Bundle\DoctrineCacheBundle\DependencyInjection\CacheProviderLoader; /** * DoctrineExtension is an extension for the Doctrine DBAL and ORM library. * * @author Jonathan H. Wage * @author Fabien Potencier * @author Benjamin Eberlei * @author Fabio B. Silva * @author Kinn Coelho Julião */ class DoctrineExtension extends AbstractDoctrineExtension { /** * @var string */ private $defaultConnection; /** * @var SymfonyBridgeAdapter */ private $adapter; /** * @param SymfonyBridgeAdapter $adapter */ public function __construct(SymfonyBridgeAdapter $adapter = null) { $this->adapter = $adapter ?: new SymfonyBridgeAdapter(new CacheProviderLoader(), 'doctrine.orm', 'orm'); } /** * {@inheritDoc} */ public function load(array $configs, ContainerBuilder $container) { $configuration = $this->getConfiguration($configs, $container); $config = $this->processConfiguration($configuration, $configs); $this->adapter->loadServicesConfiguration($container); if (!empty($config['dbal'])) { $this->dbalLoad($config['dbal'], $container); } if (!empty($config['orm'])) { if (empty($config['dbal'])) { throw new \LogicException('Configuring the ORM layer requires to configure the DBAL layer as well.'); } if (!class_exists('Doctrine\ORM\Version')) { throw new \LogicException('To configure the ORM layer, you must first install the doctrine/orm package.'); } $this->ormLoad($config['orm'], $container); } } /** * Loads the DBAL configuration. * * Usage example: * * * * @param array $config An array of configuration settings * @param ContainerBuilder $container A ContainerBuilder instance */ protected function dbalLoad(array $config, ContainerBuilder $container) { $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); $loader->load('dbal.xml'); if (empty($config['default_connection'])) { $keys = array_keys($config['connections']); $config['default_connection'] = reset($keys); } $this->defaultConnection = $config['default_connection']; $container->setAlias('database_connection', sprintf('doctrine.dbal.%s_connection', $this->defaultConnection)); $container->getAlias('database_connection')->setPublic(true); $container->setAlias('doctrine.dbal.event_manager', new Alias(sprintf('doctrine.dbal.%s_connection.event_manager', $this->defaultConnection), false)); $container->setParameter('doctrine.dbal.connection_factory.types', $config['types']); $connections = array(); foreach (array_keys($config['connections']) as $name) { $connections[$name] = sprintf('doctrine.dbal.%s_connection', $name); } $container->setParameter('doctrine.connections', $connections); $container->setParameter('doctrine.default_connection', $this->defaultConnection); foreach ($config['connections'] as $name => $connection) { $this->loadDbalConnection($name, $connection, $container); } } /** * Loads a configured DBAL connection. * * @param string $name The name of the connection * @param array $connection A dbal connection configuration. * @param ContainerBuilder $container A ContainerBuilder instance */ protected function loadDbalConnection($name, array $connection, ContainerBuilder $container) { // configuration $definitionClassname = $this->getDefinitionClassname(); $configuration = $container->setDefinition(sprintf('doctrine.dbal.%s_connection.configuration', $name), new $definitionClassname('doctrine.dbal.connection.configuration')); $logger = null; if ($connection['logging']) { $logger = new Reference('doctrine.dbal.logger'); } unset ($connection['logging']); if ($connection['profiling']) { $profilingLoggerId = 'doctrine.dbal.logger.profiling.'.$name; $container->setDefinition($profilingLoggerId, new $definitionClassname('doctrine.dbal.logger.profiling')); $profilingLogger = new Reference($profilingLoggerId); $container->getDefinition('data_collector.doctrine')->addMethodCall('addLogger', array($name, $profilingLogger)); if (null !== $logger) { $chainLogger = new $definitionClassname('doctrine.dbal.logger.chain'); $chainLogger->addMethodCall('addLogger', array($profilingLogger)); $loggerId = 'doctrine.dbal.logger.chain.'.$name; $container->setDefinition($loggerId, $chainLogger); $logger = new Reference($loggerId); } else { $logger = $profilingLogger; } } unset($connection['profiling']); if (isset($connection['auto_commit'])) { $configuration->addMethodCall('setAutoCommit', array($connection['auto_commit'])); } unset($connection['auto_commit']); if (isset($connection['schema_filter']) && $connection['schema_filter']) { $configuration->addMethodCall('setFilterSchemaAssetsExpression', array($connection['schema_filter'])); } unset($connection['schema_filter']); if ($logger) { $configuration->addMethodCall('setSQLLogger', array($logger)); } // event manager $container->setDefinition(sprintf('doctrine.dbal.%s_connection.event_manager', $name), new $definitionClassname('doctrine.dbal.connection.event_manager')); // connection $options = $this->getConnectionOptions($connection); $def = $container ->setDefinition(sprintf('doctrine.dbal.%s_connection', $name), new $definitionClassname('doctrine.dbal.connection')) ->setPublic(true) ->setArguments(array( $options, new Reference(sprintf('doctrine.dbal.%s_connection.configuration', $name)), new Reference(sprintf('doctrine.dbal.%s_connection.event_manager', $name)), $connection['mapping_types'], )) ; // Set class in case "wrapper_class" option was used to assist IDEs if (isset($options['wrapperClass'])) { $def->setClass($options['wrapperClass']); } if (!empty($connection['use_savepoints'])) { $def->addMethodCall('setNestTransactionsWithSavepoints', array($connection['use_savepoints'])); } // Create a shard_manager for this connection if (isset($options['shards'])) { $shardManagerDefinition = new Definition($options['shardManagerClass'], array( new Reference(sprintf('doctrine.dbal.%s_connection', $name)) )); $container->setDefinition(sprintf('doctrine.dbal.%s_shard_manager', $name), $shardManagerDefinition); } } protected function getConnectionOptions($connection) { $options = $connection; if (isset($options['platform_service'])) { $options['platform'] = new Reference($options['platform_service']); unset($options['platform_service']); } unset($options['mapping_types']); if (isset($options['shard_choser_service'])) { $options['shard_choser'] = new Reference($options['shard_choser_service']); unset($options['shard_choser_service']); } foreach (array( 'options' => 'driverOptions', 'driver_class' => 'driverClass', 'wrapper_class' => 'wrapperClass', 'keep_slave' => 'keepSlave', 'shard_choser' => 'shardChoser', 'shard_manager_class' => 'shardManagerClass', 'server_version' => 'serverVersion', 'default_table_options' => 'defaultTableOptions', ) as $old => $new) { if (isset($options[$old])) { $options[$new] = $options[$old]; unset($options[$old]); } } if (!empty($options['slaves']) && !empty($options['shards'])) { throw new InvalidArgumentException('Sharding and master-slave connection cannot be used together'); } if (!empty($options['slaves'])) { $nonRewrittenKeys = array( 'driver' => true, 'driverOptions' => true, 'driverClass' => true, 'wrapperClass' => true, 'keepSlave' => true, 'shardChoser' => true, 'platform' => true, 'slaves' => true, 'master' => true, 'shards' => true, 'serverVersion' => true, // included by safety but should have been unset already 'logging' => true, 'profiling' => true, 'mapping_types' => true, 'platform_service' => true, ); foreach ($options as $key => $value) { if (isset($nonRewrittenKeys[$key])) { continue; } $options['master'][$key] = $value; unset($options[$key]); } if (empty($options['wrapperClass'])) { // Change the wrapper class only if the user does not already forced using a custom one. $options['wrapperClass'] = 'Doctrine\\DBAL\\Connections\\MasterSlaveConnection'; } } else { unset($options['slaves']); } if (!empty($options['shards'])) { $nonRewrittenKeys = array( 'driver' => true, 'driverOptions' => true, 'driverClass' => true, 'wrapperClass' => true, 'keepSlave' => true, 'shardChoser' => true, 'platform' => true, 'slaves' => true, 'global' => true, 'shards' => true, 'serverVersion' => true, // included by safety but should have been unset already 'logging' => true, 'profiling' => true, 'mapping_types' => true, 'platform_service' => true, ); foreach ($options as $key => $value) { if (isset($nonRewrittenKeys[$key])) { continue; } $options['global'][$key] = $value; unset($options[$key]); } if (empty($options['wrapperClass'])) { // Change the wrapper class only if the user does not already forced using a custom one. $options['wrapperClass'] = 'Doctrine\\DBAL\\Sharding\\PoolingShardConnection'; } if (empty($options['shardManagerClass'])) { // Change the shard manager class only if the user does not already forced using a custom one. $options['shardManagerClass'] = 'Doctrine\\DBAL\\Sharding\\PoolingShardManager'; } } else { unset($options['shards']); } return $options; } /** * Loads the Doctrine ORM configuration. * * Usage example: * * * * @param array $config An array of configuration settings * @param ContainerBuilder $container A ContainerBuilder instance */ protected function ormLoad(array $config, ContainerBuilder $container) { $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); $loader->load('orm.xml'); if (class_exists(AbstractType::class) && method_exists(DoctrineType::class, 'reset')) { $container->getDefinition('form.type.entity')->addTag('kernel.reset', array('method' => 'reset')); } $entityManagers = array(); foreach (array_keys($config['entity_managers']) as $name) { $entityManagers[$name] = sprintf('doctrine.orm.%s_entity_manager', $name); } $container->setParameter('doctrine.entity_managers', $entityManagers); if (empty($config['default_entity_manager'])) { $tmp = array_keys($entityManagers); $config['default_entity_manager'] = reset($tmp); } $container->setParameter('doctrine.default_entity_manager', $config['default_entity_manager']); $options = array('auto_generate_proxy_classes', 'proxy_dir', 'proxy_namespace'); foreach ($options as $key) { $container->setParameter('doctrine.orm.'.$key, $config[$key]); } $container->setAlias('doctrine.orm.entity_manager', sprintf('doctrine.orm.%s_entity_manager', $config['default_entity_manager'])); $container->getAlias('doctrine.orm.entity_manager')->setPublic(true); $config['entity_managers'] = $this->fixManagersAutoMappings($config['entity_managers'], $container->getParameter('kernel.bundles')); $loadPropertyInfoExtractor = interface_exists('Symfony\Component\PropertyInfo\PropertyInfoExtractorInterface') && class_exists('Symfony\Bridge\Doctrine\PropertyInfo\DoctrineExtractor'); foreach ($config['entity_managers'] as $name => $entityManager) { $entityManager['name'] = $name; $this->loadOrmEntityManager($entityManager, $container); if ($loadPropertyInfoExtractor) { $this->loadPropertyInfoExtractor($name, $container); } } if ($config['resolve_target_entities']) { $def = $container->findDefinition('doctrine.orm.listeners.resolve_target_entity'); foreach ($config['resolve_target_entities'] as $name => $implementation) { $def->addMethodCall('addResolveTargetEntity', array( $name, $implementation, array(), )); } // BC: ResolveTargetEntityListener implements the subscriber interface since // v2.5.0-beta1 (Commit 437f812) if (version_compare(Version::VERSION, '2.5.0-DEV') < 0) { $def->addTag('doctrine.event_listener', array('event' => 'loadClassMetadata')); } else { $def->addTag('doctrine.event_subscriber'); } } // if is for Symfony 3.2 and lower compat if (method_exists($container, 'registerForAutoconfiguration')) { $container->registerForAutoconfiguration(ServiceEntityRepositoryInterface::class) ->addTag(ServiceRepositoryCompilerPass::REPOSITORY_SERVICE_TAG); } /* * Compatibility for Symfony 3.2 and lower: gives the service a default argument. * When DoctrineBundle requires 3.3 or higher, this can be moved to an anonymous * service in orm.xml. * * This is replaced with a true locator by ServiceRepositoryCompilerPass. * This makes that pass technically optional (good for tests). */ if (class_exists(ServiceLocator::class)) { $container->getDefinition('doctrine.orm.container_repository_factory') ->replaceArgument(0, (new Definition(ServiceLocator::class))->setArgument(0, [])); } } /** * Loads a configured ORM entity manager. * * @param array $entityManager A configured ORM entity manager. * @param ContainerBuilder $container A ContainerBuilder instance */ protected function loadOrmEntityManager(array $entityManager, ContainerBuilder $container) { $definitionClassname = $this->getDefinitionClassname(); $ormConfigDef = $container->setDefinition(sprintf('doctrine.orm.%s_configuration', $entityManager['name']), new $definitionClassname('doctrine.orm.configuration')); $this->loadOrmEntityManagerMappingInformation($entityManager, $ormConfigDef, $container); $this->loadOrmCacheDrivers($entityManager, $container); if (isset($entityManager['entity_listener_resolver']) && $entityManager['entity_listener_resolver']) { $container->setAlias(sprintf('doctrine.orm.%s_entity_listener_resolver', $entityManager['name']), $entityManager['entity_listener_resolver']); } else { $definition = new Definition('%doctrine.orm.entity_listener_resolver.class%'); $definition->addArgument(new Reference('service_container')); $container->setDefinition(sprintf('doctrine.orm.%s_entity_listener_resolver', $entityManager['name']), $definition); } $methods = array( 'setMetadataCacheImpl' => new Reference(sprintf('doctrine.orm.%s_metadata_cache', $entityManager['name'])), 'setQueryCacheImpl' => new Reference(sprintf('doctrine.orm.%s_query_cache', $entityManager['name'])), 'setResultCacheImpl' => new Reference(sprintf('doctrine.orm.%s_result_cache', $entityManager['name'])), 'setMetadataDriverImpl' => new Reference('doctrine.orm.'.$entityManager['name'].'_metadata_driver'), 'setProxyDir' => '%doctrine.orm.proxy_dir%', 'setProxyNamespace' => '%doctrine.orm.proxy_namespace%', 'setAutoGenerateProxyClasses' => '%doctrine.orm.auto_generate_proxy_classes%', 'setClassMetadataFactoryName' => $entityManager['class_metadata_factory_name'], 'setDefaultRepositoryClassName' => $entityManager['default_repository_class'], ); // check for version to keep BC if (version_compare(Version::VERSION, "2.3.0-DEV") >= 0) { $methods = array_merge($methods, array( 'setNamingStrategy' => new Reference($entityManager['naming_strategy']), 'setQuoteStrategy' => new Reference($entityManager['quote_strategy']), )); } if (version_compare(Version::VERSION, "2.4.0-DEV") >= 0) { $methods = array_merge($methods, array( 'setEntityListenerResolver' => new Reference(sprintf('doctrine.orm.%s_entity_listener_resolver', $entityManager['name'])), )); } if (version_compare(Version::VERSION, "2.5.0-DEV") >= 0) { $listenerId = sprintf('doctrine.orm.%s_listeners.attach_entity_listeners', $entityManager['name']); $listenerDef = $container->setDefinition($listenerId, new Definition('%doctrine.orm.listeners.attach_entity_listeners.class%')); $listenerTagParams = array('event' => 'loadClassMetadata'); if (isset($entityManager['connection'])) { $listenerTagParams['connection'] = $entityManager['connection']; } $listenerDef->addTag('doctrine.event_listener', $listenerTagParams); } if (isset($entityManager['second_level_cache'])) { $this->loadOrmSecondLevelCache($entityManager, $ormConfigDef, $container); } if ($entityManager['repository_factory']) { $methods['setRepositoryFactory'] = new Reference($entityManager['repository_factory']); } foreach ($methods as $method => $arg) { $ormConfigDef->addMethodCall($method, array($arg)); } foreach ($entityManager['hydrators'] as $name => $class) { $ormConfigDef->addMethodCall('addCustomHydrationMode', array($name, $class)); } if (!empty($entityManager['dql'])) { foreach ($entityManager['dql']['string_functions'] as $name => $function) { $ormConfigDef->addMethodCall('addCustomStringFunction', array($name, $function)); } foreach ($entityManager['dql']['numeric_functions'] as $name => $function) { $ormConfigDef->addMethodCall('addCustomNumericFunction', array($name, $function)); } foreach ($entityManager['dql']['datetime_functions'] as $name => $function) { $ormConfigDef->addMethodCall('addCustomDatetimeFunction', array($name, $function)); } } $enabledFilters = array(); $filtersParameters = array(); foreach ($entityManager['filters'] as $name => $filter) { $ormConfigDef->addMethodCall('addFilter', array($name, $filter['class'])); if ($filter['enabled']) { $enabledFilters[] = $name; } if ($filter['parameters']) { $filtersParameters[$name] = $filter['parameters']; } } $managerConfiguratorName = sprintf('doctrine.orm.%s_manager_configurator', $entityManager['name']); $container ->setDefinition($managerConfiguratorName, new $definitionClassname('doctrine.orm.manager_configurator.abstract')) ->replaceArgument(0, $enabledFilters) ->replaceArgument(1, $filtersParameters) ; if (!isset($entityManager['connection'])) { $entityManager['connection'] = $this->defaultConnection; } $container ->setDefinition(sprintf('doctrine.orm.%s_entity_manager', $entityManager['name']), new $definitionClassname('doctrine.orm.entity_manager.abstract')) ->setPublic(true) ->setArguments(array( new Reference(sprintf('doctrine.dbal.%s_connection', $entityManager['connection'])), new Reference(sprintf('doctrine.orm.%s_configuration', $entityManager['name'])), )) ->setConfigurator(array(new Reference($managerConfiguratorName), 'configure')) ; $container->setAlias( sprintf('doctrine.orm.%s_entity_manager.event_manager', $entityManager['name']), new Alias(sprintf('doctrine.dbal.%s_connection.event_manager', $entityManager['connection']), false) ); if (isset($entityManager['entity_listeners'])) { if (!isset($listenerDef)) { throw new InvalidArgumentException('Entity listeners configuration requires doctrine-orm 2.5.0 or newer'); } $entities = $entityManager['entity_listeners']['entities']; foreach ($entities as $entityListenerClass => $entity) { foreach ($entity['listeners'] as $listenerClass => $listener) { foreach ($listener['events'] as $listenerEvent) { $listenerEventName = $listenerEvent['type']; $listenerMethod = $listenerEvent['method']; $listenerDef->addMethodCall('addEntityListener', array( $entityListenerClass, $listenerClass, $listenerEventName, $listenerMethod, )); } } } } } /** * Loads an ORM entity managers bundle mapping information. * * There are two distinct configuration possibilities for mapping information: * * 1. Specify a bundle and optionally details where the entity and mapping information reside. * 2. Specify an arbitrary mapping location. * * @example * * doctrine.orm: * mappings: * MyBundle1: ~ * MyBundle2: yml * MyBundle3: { type: annotation, dir: Entities/ } * MyBundle4: { type: xml, dir: Resources/config/doctrine/mapping } * MyBundle5: * type: yml * dir: bundle-mappings/ * alias: BundleAlias * arbitrary_key: * type: xml * dir: %kernel.root_dir%/../src/vendor/DoctrineExtensions/lib/DoctrineExtensions/Entities * prefix: DoctrineExtensions\Entities\ * alias: DExt * * In the case of bundles everything is really optional (which leads to autodetection for this bundle) but * in the mappings key everything except alias is a required argument. * * @param array $entityManager A configured ORM entity manager * @param Definition $ormConfigDef A Definition instance * @param ContainerBuilder $container A ContainerBuilder instance */ protected function loadOrmEntityManagerMappingInformation(array $entityManager, Definition $ormConfigDef, ContainerBuilder $container) { // reset state of drivers and alias map. They are only used by this methods and children. $this->drivers = array(); $this->aliasMap = array(); $this->loadMappingInformation($entityManager, $container); $this->registerMappingDrivers($entityManager, $container); $ormConfigDef->addMethodCall('setEntityNamespaces', array($this->aliasMap)); } /** * Loads an ORM second level cache bundle mapping information. * * @example * entity_managers: * default: * second_level_cache: * region_cache_driver: apc * log_enabled: true * regions: * my_service_region: * type: service * service : "my_service_region" * * my_query_region: * lifetime: 300 * cache_driver: array * type: filelock * * my_entity_region: * lifetime: 600 * cache_driver: * type: apc * * @param array $entityManager A configured ORM entity manager * @param Definition $ormConfigDef A Definition instance * @param ContainerBuilder $container A ContainerBuilder instance */ protected function loadOrmSecondLevelCache(array $entityManager, Definition $ormConfigDef, ContainerBuilder $container) { if (version_compare(Version::VERSION, '2.5.0-DEV') < 0) { throw new \InvalidArgumentException('Second-level cache requires doctrine-orm 2.5.0 or newer'); } $driverId = null; $enabled = $entityManager['second_level_cache']['enabled']; if (isset($entityManager['second_level_cache']['region_cache_driver'])) { $driverName = 'second_level_cache.region_cache_driver'; $driverMap = $entityManager['second_level_cache']['region_cache_driver']; $driverId = $this->loadCacheDriver($driverName, $entityManager['name'], $driverMap, $container); } $configId = sprintf('doctrine.orm.%s_second_level_cache.cache_configuration', $entityManager['name']); $regionsId = sprintf('doctrine.orm.%s_second_level_cache.regions_configuration', $entityManager['name']); $driverId = $driverId ?: sprintf('doctrine.orm.%s_second_level_cache.region_cache_driver', $entityManager['name']); $configDef = $container->setDefinition($configId, new Definition('%doctrine.orm.second_level_cache.cache_configuration.class%')); $regionsDef = $container->setDefinition($regionsId, new Definition('%doctrine.orm.second_level_cache.regions_configuration.class%')); $slcFactoryId = sprintf('doctrine.orm.%s_second_level_cache.default_cache_factory', $entityManager['name']); $factoryClass = isset($entityManager['second_level_cache']['factory']) ? $entityManager['second_level_cache']['factory'] : '%doctrine.orm.second_level_cache.default_cache_factory.class%'; $definition = new Definition($factoryClass, array(new Reference($regionsId), new Reference($driverId))); $slcFactoryDef = $container ->setDefinition($slcFactoryId, $definition); if (isset($entityManager['second_level_cache']['regions'])) { foreach ($entityManager['second_level_cache']['regions'] as $name => $region) { $regionRef = null; $regionType = $region['type']; if ($regionType === 'service') { $regionId = sprintf('doctrine.orm.%s_second_level_cache.region.%s', $entityManager['name'], $name); $regionRef = new Reference($region['service']); $container->setAlias($regionId, new Alias($region['service'], false)); } if ($regionType === 'default' || $regionType === 'filelock') { $regionId = sprintf('doctrine.orm.%s_second_level_cache.region.%s', $entityManager['name'], $name); $driverName = sprintf('second_level_cache.region.%s_driver', $name); $driverMap = $region['cache_driver']; $driverId = $this->loadCacheDriver($driverName, $entityManager['name'], $driverMap, $container); $regionRef = new Reference($regionId); $container ->setDefinition($regionId, new Definition('%doctrine.orm.second_level_cache.default_region.class%')) ->setArguments(array($name, new Reference($driverId), $region['lifetime'])); } if ($regionType === 'filelock') { $regionId = sprintf('doctrine.orm.%s_second_level_cache.region.%s_filelock', $entityManager['name'], $name); $container ->setDefinition($regionId, new Definition('%doctrine.orm.second_level_cache.filelock_region.class%')) ->setArguments(array($regionRef, $region['lock_path'], $region['lock_lifetime'])); $regionRef = new Reference($regionId); $regionsDef->addMethodCall('getLockLifetime', array($name, $region['lock_lifetime'])); } $regionsDef->addMethodCall('setLifetime', array($name, $region['lifetime'])); $slcFactoryDef->addMethodCall('setRegion', array($regionRef)); } } if ($entityManager['second_level_cache']['log_enabled']) { $loggerChainId = sprintf('doctrine.orm.%s_second_level_cache.logger_chain', $entityManager['name']); $loggerStatsId = sprintf('doctrine.orm.%s_second_level_cache.logger_statistics', $entityManager['name']); $loggerChaingDef = $container->setDefinition($loggerChainId, new Definition('%doctrine.orm.second_level_cache.logger_chain.class%')); $loggerStatsDef = $container->setDefinition($loggerStatsId, new Definition('%doctrine.orm.second_level_cache.logger_statistics.class%')); $loggerChaingDef->addMethodCall('setLogger', array('statistics', $loggerStatsDef)); $configDef->addMethodCall('setCacheLogger', array($loggerChaingDef)); foreach ($entityManager['second_level_cache']['loggers'] as $name => $logger) { $loggerId = sprintf('doctrine.orm.%s_second_level_cache.logger.%s', $entityManager['name'], $name); $loggerRef = new Reference($logger['service']); $container->setAlias($loggerId, new Alias($logger['service'], false)); $loggerChaingDef->addMethodCall('setLogger', array($name, $loggerRef)); } } $configDef->addMethodCall('setCacheFactory', array($slcFactoryDef)); $configDef->addMethodCall('setRegionsConfiguration', array($regionsDef)); $ormConfigDef->addMethodCall('setSecondLevelCacheEnabled', array($enabled)); $ormConfigDef->addMethodCall('setSecondLevelCacheConfiguration', array($configDef)); } /** * {@inheritDoc} */ protected function getObjectManagerElementName($name) { return 'doctrine.orm.'.$name; } protected function getMappingObjectDefaultName() { return 'Entity'; } /** * {@inheritDoc} */ protected function getMappingResourceConfigDirectory() { return 'Resources/config/doctrine'; } /** * {@inheritDoc} */ protected function getMappingResourceExtension() { return 'orm'; } /** * {@inheritDoc} */ protected function loadCacheDriver($driverName, $entityManagerName, array $driverMap, ContainerBuilder $container) { if (!empty($driverMap['cache_provider'])) { $aliasId = $this->getObjectManagerElementName(sprintf('%s_%s', $entityManagerName, $driverName)); $serviceId = sprintf('doctrine_cache.providers.%s', $driverMap['cache_provider']); $container->setAlias($aliasId, new Alias($serviceId, false)); return $aliasId; } return $this->adapter->loadCacheDriver($driverName, $entityManagerName, $driverMap, $container); } /** * Loads a configured entity managers cache drivers. * * @param array $entityManager A configured ORM entity manager. * @param ContainerBuilder $container A ContainerBuilder instance */ protected function loadOrmCacheDrivers(array $entityManager, ContainerBuilder $container) { $this->loadCacheDriver('metadata_cache', $entityManager['name'], $entityManager['metadata_cache_driver'], $container); $this->loadCacheDriver('result_cache', $entityManager['name'], $entityManager['result_cache_driver'], $container); $this->loadCacheDriver('query_cache', $entityManager['name'], $entityManager['query_cache_driver'], $container); } /** * Loads a property info extractor for each defined entity manager. * * @param string $entityManagerName * @param ContainerBuilder $container */ private function loadPropertyInfoExtractor($entityManagerName, ContainerBuilder $container) { $metadataFactoryService = sprintf('doctrine.orm.%s_entity_manager.metadata_factory', $entityManagerName); $metadataFactoryDefinition = $container->register($metadataFactoryService, 'Doctrine\Common\Persistence\Mapping\ClassMetadataFactory'); $metadataFactoryDefinition->setFactory(array( new Reference(sprintf('doctrine.orm.%s_entity_manager', $entityManagerName)), 'getMetadataFactory' )); $metadataFactoryDefinition->setPublic(false); $propertyExtractorDefinition = $container->register(sprintf('doctrine.orm.%s_entity_manager.property_info_extractor', $entityManagerName), 'Symfony\Bridge\Doctrine\PropertyInfo\DoctrineExtractor'); $propertyExtractorDefinition->addArgument(new Reference($metadataFactoryService)); $propertyExtractorDefinition->addTag('property_info.list_extractor', array('priority' => -1001)); $propertyExtractorDefinition->addTag('property_info.type_extractor', array('priority' => -999)); } /** * @param array $objectManager * @param ContainerBuilder $container * @param string $cacheName */ public function loadObjectManagerCacheDriver(array $objectManager, ContainerBuilder $container, $cacheName) { $this->loadCacheDriver($cacheName, $objectManager['name'], $objectManager[$cacheName.'_driver'], $container); } /** * {@inheritDoc} */ public function getXsdValidationBasePath() { return __DIR__.'/../Resources/config/schema'; } /** * {@inheritDoc} */ public function getNamespace() { return 'http://symfony.com/schema/dic/doctrine'; } /** * {@inheritDoc} */ public function getConfiguration(array $config, ContainerBuilder $container) { return new Configuration($container->getParameter('kernel.debug')); } /** * @return string */ private function getDefinitionClassname() { return class_exists(ChildDefinition::class) ? ChildDefinition::class : DefinitionDecorator::class; } } DoctrineBundle-1.8.1/DoctrineBundle.php000066400000000000000000000131071320601477700200450ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle; use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\ServiceRepositoryCompilerPass; use Doctrine\Common\Util\ClassUtils; use Doctrine\Bundle\DoctrineBundle\Command\CreateDatabaseDoctrineCommand; use Doctrine\Bundle\DoctrineBundle\Command\DropDatabaseDoctrineCommand; use Doctrine\Bundle\DoctrineBundle\Command\Proxy\ImportDoctrineCommand; use Doctrine\Bundle\DoctrineBundle\Command\Proxy\RunSqlDoctrineCommand; use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\EntityListenerPass; use Doctrine\ORM\Proxy\Autoloader; use Symfony\Component\Console\Application; use Symfony\Component\DependencyInjection\Compiler\PassConfig; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; use Symfony\Bridge\Doctrine\DependencyInjection\CompilerPass\DoctrineValidationPass; use Symfony\Bridge\Doctrine\DependencyInjection\CompilerPass\RegisterEventListenersAndSubscribersPass; use Symfony\Bridge\Doctrine\DependencyInjection\Security\UserProvider\EntityFactory; /** * Bundle. * * @author Fabien Potencier * @author Jonathan H. Wage */ class DoctrineBundle extends Bundle { private $autoloader; /** * {@inheritDoc} */ public function build(ContainerBuilder $container) { parent::build($container); $container->addCompilerPass(new RegisterEventListenersAndSubscribersPass('doctrine.connections', 'doctrine.dbal.%s_connection.event_manager', 'doctrine'), PassConfig::TYPE_BEFORE_OPTIMIZATION); if ($container->hasExtension('security')) { $container->getExtension('security')->addUserProviderFactory(new EntityFactory('entity', 'doctrine.orm.security.user.provider')); } $container->addCompilerPass(new DoctrineValidationPass('orm')); $container->addCompilerPass(new EntityListenerPass()); $container->addCompilerPass(new ServiceRepositoryCompilerPass()); } /** * {@inheritDoc} */ public function boot() { // Register an autoloader for proxies to avoid issues when unserializing them // when the ORM is used. if ($this->container->hasParameter('doctrine.orm.proxy_namespace')) { $namespace = $this->container->getParameter('doctrine.orm.proxy_namespace'); $dir = $this->container->getParameter('doctrine.orm.proxy_dir'); $proxyGenerator = null; if ($this->container->getParameter('doctrine.orm.auto_generate_proxy_classes')) { // See https://github.com/symfony/symfony/pull/3419 for usage of references $container = &$this->container; $proxyGenerator = function ($proxyDir, $proxyNamespace, $class) use (&$container) { $originalClassName = ClassUtils::getRealClass($class); /** @var $registry Registry */ $registry = $container->get('doctrine'); // Tries to auto-generate the proxy file /** @var $em \Doctrine\ORM\EntityManager */ foreach ($registry->getManagers() as $em) { if (!$em->getConfiguration()->getAutoGenerateProxyClasses()) { continue; } $metadataFactory = $em->getMetadataFactory(); if ($metadataFactory->isTransient($originalClassName)) { continue; } $classMetadata = $metadataFactory->getMetadataFor($originalClassName); $em->getProxyFactory()->generateProxyClasses(array($classMetadata)); clearstatcache(true, Autoloader::resolveFile($proxyDir, $proxyNamespace, $class)); break; } }; } $this->autoloader = Autoloader::register($dir, $namespace, $proxyGenerator); } } /** * {@inheritDoc} */ public function shutdown() { if (null !== $this->autoloader) { spl_autoload_unregister($this->autoloader); $this->autoloader = null; } // Clear all entity managers to clear references to entities for GC if ($this->container->hasParameter('doctrine.entity_managers')) { foreach ($this->container->getParameter('doctrine.entity_managers') as $id) { if (!method_exists($this->container, 'initialized') || $this->container->initialized($id)) { $this->container->get($id)->clear(); } } } // Close all connections to avoid reaching too many connections in the process when booting again later (tests) if ($this->container->hasParameter('doctrine.connections')) { foreach ($this->container->getParameter('doctrine.connections') as $id) { if (!method_exists($this->container, 'initialized') || $this->container->initialized($id)) { $this->container->get($id)->close(); } } } } /** * {@inheritDoc} */ public function registerCommands(Application $application) { } } DoctrineBundle-1.8.1/LICENSE000066400000000000000000000020661320601477700154420ustar00rootroot00000000000000Copyright (c) 2011 Fabien Potencier, Doctrine Project Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. DoctrineBundle-1.8.1/ManagerConfigurator.php000066400000000000000000000042321320601477700211000ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle; use Doctrine\ORM\EntityManager; use Doctrine\ORM\Query\Filter\SQLFilter; /** * Configurator for an EntityManager * * @author Christophe Coevoet */ class ManagerConfigurator { private $enabledFilters = array(); private $filtersParameters = array(); public function __construct(array $enabledFilters, array $filtersParameters) { $this->enabledFilters = $enabledFilters; $this->filtersParameters = $filtersParameters; } /** * Create a connection by name. * * @param EntityManager $entityManager */ public function configure(EntityManager $entityManager) { $this->enableFilters($entityManager); } /** * Enables filters for a given entity manager * * @param EntityManager $entityManager */ private function enableFilters(EntityManager $entityManager) { if (empty($this->enabledFilters)) { return; } $filterCollection = $entityManager->getFilters(); foreach ($this->enabledFilters as $filter) { $filterObject = $filterCollection->enable($filter); if (null !== $filterObject) { $this->setFilterParameters($filter, $filterObject); } } } /** * Sets default parameters for a given filter * * @param string $name Filter name * @param SQLFilter $filter Filter object */ private function setFilterParameters($name, SQLFilter $filter) { if (!empty($this->filtersParameters[$name])) { $parameters = $this->filtersParameters[$name]; foreach ($parameters as $paramName => $paramValue) { $filter->setParameter($paramName, $paramValue); } } } } DoctrineBundle-1.8.1/Mapping/000077500000000000000000000000001320601477700160245ustar00rootroot00000000000000DoctrineBundle-1.8.1/Mapping/ClassMetadataCollection.php000066400000000000000000000025211320601477700232570ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Mapping; /** * @author Fabien Potencier */ class ClassMetadataCollection { private $path; private $namespace; private $metadata; /** * Constructor * * @param array $metadata */ public function __construct(array $metadata) { $this->metadata = $metadata; } /** * @return array */ public function getMetadata() { return $this->metadata; } /** * @param string $path */ public function setPath($path) { $this->path = $path; } /** * @return string */ public function getPath() { return $this->path; } /** * @param string $namespace */ public function setNamespace($namespace) { $this->namespace = $namespace; } /** * @return string */ public function getNamespace() { return $this->namespace; } } DoctrineBundle-1.8.1/Mapping/ContainerAwareEntityListenerResolver.php000066400000000000000000000051151320601477700260660ustar00rootroot00000000000000container = $container; } /** * {@inheritdoc} */ public function clear($className = null) { if ($className === null) { $this->instances = array(); return; } $className = $this->normalizeClassName($className); if (isset($this->instances[$className])) { unset($this->instances[$className]); } } /** * {@inheritdoc} */ public function register($object) { if ( ! is_object($object)) { throw new \InvalidArgumentException(sprintf('An object was expected, but got "%s".', gettype($object))); } $className = $this->normalizeClassName(get_class($object)); $this->instances[$className] = $object; } /** * {@inheritdoc} */ public function registerService($className, $serviceId) { $this->serviceIds[$this->normalizeClassName($className)] = $serviceId; } /** * {@inheritdoc} */ public function resolve($className) { $className = $this->normalizeClassName($className); if (!isset($this->instances[$className])) { if (isset($this->serviceIds[$className])) { $this->instances[$className] = $this->resolveService($this->serviceIds[$className]); } else { $this->instances[$className] = new $className(); } } return $this->instances[$className]; } /** * @param string $serviceId * * @return object */ private function resolveService($serviceId) { if (!$this->container->has($serviceId)) { throw new \RuntimeException(sprintf('There is no service named "%s"', $serviceId)); } return $this->container->get($serviceId); } /** * @param $className * * @return string */ private function normalizeClassName($className) { return trim($className, '\\'); } } DoctrineBundle-1.8.1/Mapping/DisconnectedMetadataFactory.php000066400000000000000000000151221320601477700241310ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Mapping; use Doctrine\Common\Persistence\ManagerRegistry; use Doctrine\ORM\Mapping\MappingException; use Doctrine\ORM\Tools\DisconnectedClassMetadataFactory; use Symfony\Component\HttpKernel\Bundle\BundleInterface; /** * This class provides methods to access Doctrine entity class metadata for a * given bundle, namespace or entity class, for generation purposes * * @author Fabien Potencier */ class DisconnectedMetadataFactory { private $registry; /** * Constructor. * * @param ManagerRegistry $registry A ManagerRegistry instance */ public function __construct(ManagerRegistry $registry) { $this->registry = $registry; } /** * Gets the metadata of all classes of a bundle. * * @param BundleInterface $bundle A BundleInterface instance * * @return ClassMetadataCollection A ClassMetadataCollection instance * * @throws \RuntimeException When bundle does not contain mapped entities */ public function getBundleMetadata(BundleInterface $bundle) { $namespace = $bundle->getNamespace(); $metadata = $this->getMetadataForNamespace($namespace); if (!$metadata->getMetadata()) { throw new \RuntimeException(sprintf('Bundle "%s" does not contain any mapped entities.', $bundle->getName())); } $path = $this->getBasePathForClass($bundle->getName(), $bundle->getNamespace(), $bundle->getPath()); $metadata->setPath($path); $metadata->setNamespace($bundle->getNamespace()); return $metadata; } /** * Gets the metadata of a class. * * @param string $class A class name * @param string $path The path where the class is stored (if known) * * @return ClassMetadataCollection A ClassMetadataCollection instance * * @throws MappingException When class is not valid entity or mapped superclass */ public function getClassMetadata($class, $path = null) { $metadata = $this->getMetadataForClass($class); if (!$metadata->getMetadata()) { throw MappingException::classIsNotAValidEntityOrMappedSuperClass($class); } $this->findNamespaceAndPathForMetadata($metadata, $path); return $metadata; } /** * Gets the metadata of all classes of a namespace. * * @param string $namespace A namespace name * @param string $path The path where the class is stored (if known) * * @return ClassMetadataCollection A ClassMetadataCollection instance * * @throws \RuntimeException When namespace not contain mapped entities */ public function getNamespaceMetadata($namespace, $path = null) { $metadata = $this->getMetadataForNamespace($namespace); if (!$metadata->getMetadata()) { throw new \RuntimeException(sprintf('Namespace "%s" does not contain any mapped entities.', $namespace)); } $this->findNamespaceAndPathForMetadata($metadata, $path); return $metadata; } /** * Find and configure path and namespace for the metadata collection. * * @param ClassMetadataCollection $metadata * @param string|null $path * * @throws \RuntimeException When unable to determine the path */ public function findNamespaceAndPathForMetadata(ClassMetadataCollection $metadata, $path = null) { $all = $metadata->getMetadata(); if (class_exists($all[0]->name)) { $r = new \ReflectionClass($all[0]->name); $path = $this->getBasePathForClass($r->getName(), $r->getNamespaceName(), dirname($r->getFilename())); $ns = $r->getNamespaceName(); } elseif ($path) { // Get namespace by removing the last component of the FQCN $nsParts = explode('\\', $all[0]->name); array_pop($nsParts); $ns = implode('\\', $nsParts); } else { throw new \RuntimeException(sprintf('Unable to determine where to save the "%s" class (use the --path option).', $all[0]->name)); } $metadata->setPath($path); $metadata->setNamespace($ns); } /** * Get a base path for a class * * @param string $name class name * @param string $namespace class namespace * @param string $path class path * * @return string * @throws \RuntimeException When base path not found */ private function getBasePathForClass($name, $namespace, $path) { $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 "%s" (path: "%s", destination: "%s").', $name, $path, $destination)); } return $destination; } /** * @param string $namespace * * @return ClassMetadataCollection */ private function getMetadataForNamespace($namespace) { $metadata = array(); foreach ($this->getAllMetadata() as $m) { if (strpos($m->name, $namespace) === 0) { $metadata[] = $m; } } return new ClassMetadataCollection($metadata); } /** * @param string $entity * * @return ClassMetadataCollection */ private function getMetadataForClass($entity) { foreach ($this->registry->getManagers() as $em) { $cmf = new DisconnectedClassMetadataFactory(); $cmf->setEntityManager($em); if (!$cmf->isTransient($entity)) { return new ClassMetadataCollection(array($cmf->getMetadataFor($entity))); } } return new ClassMetadataCollection(array()); } /** * @return array */ private function getAllMetadata() { $metadata = array(); foreach ($this->registry->getManagers() as $em) { $cmf = new DisconnectedClassMetadataFactory(); $cmf->setEntityManager($em); foreach ($cmf->getAllMetadata() as $m) { $metadata[] = $m; } } return $metadata; } } DoctrineBundle-1.8.1/Mapping/EntityListenerServiceResolver.php000066400000000000000000000005041320601477700245610ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle; use Symfony\Component\DependencyInjection\ContainerAwareTrait; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Bridge\Doctrine\RegistryInterface; use Symfony\Bridge\Doctrine\ManagerRegistry; use Doctrine\ORM\ORMException; use Doctrine\ORM\EntityManager; /** * References all Doctrine connections and entity managers in a given Container. * * @author Fabien Potencier */ class Registry extends ManagerRegistry implements RegistryInterface { /** * Construct. * * @param ContainerInterface $container * @param array $connections * @param array $entityManagers * @param string $defaultConnection * @param string $defaultEntityManager */ public function __construct(ContainerInterface $container, array $connections, array $entityManagers, $defaultConnection, $defaultEntityManager) { $parentTraits = class_uses(parent::class); if (isset($parentTraits[ContainerAwareTrait::class])) { // this case should be removed when Symfony 3.4 becomes the lowest supported version // and then also, the constructor should type-hint Psr\Container\ContainerInterface $this->setContainer($container); } else { $this->container = $container; } parent::__construct('ORM', $connections, $entityManagers, $defaultConnection, $defaultEntityManager, 'Doctrine\ORM\Proxy\Proxy'); } /** * Gets the default entity manager name. * * @return string The default entity manager name * * @deprecated */ public function getDefaultEntityManagerName() { @trigger_error('getDefaultEntityManagerName is deprecated since Symfony 2.1. Use getDefaultManagerName instead', E_USER_DEPRECATED); return $this->getDefaultManagerName(); } /** * Gets a named entity manager. * * @param string $name The entity manager name (null for the default one) * * @return EntityManager * * @deprecated */ public function getEntityManager($name = null) { @trigger_error('getEntityManager is deprecated since Symfony 2.1. Use getManager instead', E_USER_DEPRECATED); return $this->getManager($name); } /** * Gets an array of all registered entity managers * * @return EntityManager[] an array of all EntityManager instances * * @deprecated */ public function getEntityManagers() { @trigger_error('getEntityManagers is deprecated since Symfony 2.1. Use getManagers instead', E_USER_DEPRECATED); return $this->getManagers(); } /** * Resets a named entity manager. * * This method is useful when an entity manager has been closed * because of a rollbacked transaction AND when you think that * it makes sense to get a new one to replace the closed one. * * Be warned that you will get a brand new entity manager as * the existing one is not usable anymore. This means that any * other object with a dependency on this entity manager will * hold an obsolete reference. You can inject the registry instead * to avoid this problem. * * @param string $name The entity manager name (null for the default one) * * @return EntityManager * * @deprecated */ public function resetEntityManager($name = null) { @trigger_error('resetEntityManager is deprecated since Symfony 2.1. Use resetManager instead', E_USER_DEPRECATED); $this->resetManager($name); } /** * Resolves a registered namespace alias to the full namespace. * * This method looks for the alias in all registered entity managers. * * @param string $alias The alias * * @return string The full namespace * * @deprecated */ public function getEntityNamespace($alias) { @trigger_error('getEntityNamespace is deprecated since Symfony 2.1. Use getAliasNamespace instead', E_USER_DEPRECATED); return $this->getAliasNamespace($alias); } /** * Resolves a registered namespace alias to the full namespace. * * This method looks for the alias in all registered entity managers. * * @param string $alias The alias * * @return string The full namespace * * @see Configuration::getEntityNamespace */ public function getAliasNamespace($alias) { foreach (array_keys($this->getManagers()) as $name) { try { return $this->getManager($name)->getConfiguration()->getEntityNamespace($alias); } catch (ORMException $e) { } } throw ORMException::unknownEntityNamespace($alias); } /** * Gets all connection names. * * @return array An array of connection names * * @deprecated */ public function getEntityManagerNames() { @trigger_error('getEntityManagerNames is deprecated since Symfony 2.1. Use getManagerNames instead', E_USER_DEPRECATED); return $this->getManagerNames(); } /** * Gets the entity manager associated with a given class. * * @param string $class A Doctrine Entity class name * * @return EntityManager|null * * @deprecated */ public function getEntityManagerForClass($class) { @trigger_error('getEntityManagerForClass is deprecated since Symfony 2.1. Use getManagerForClass instead', E_USER_DEPRECATED); return $this->getManagerForClass($class); } } DoctrineBundle-1.8.1/Repository/000077500000000000000000000000001320601477700166105ustar00rootroot00000000000000DoctrineBundle-1.8.1/Repository/ContainerRepositoryFactory.php000066400000000000000000000111321320601477700246710ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Repository; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Repository\RepositoryFactory; use Psr\Container\ContainerInterface; use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\ServiceRepositoryCompilerPass; use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass; /** * Fetches repositories from the container or falls back to normal creation. * * @author Ryan Weaver */ final class ContainerRepositoryFactory implements RepositoryFactory { private $managedRepositories = []; private $container; /** * @param ContainerInterface $container A service locator containing the repositories */ public function __construct(ContainerInterface $container = null) { // When DoctrineBundle requires Symfony 3.3+, this can be removed // and the $container argument can become required. if (null === $container && class_exists(ServiceLocatorTagPass::class)) { throw new \InvalidArgumentException(sprintf('The first argument of %s::__construct() is required on Symfony 3.3 or higher.', self::class)); } $this->container = $container; } /** * {@inheritdoc} */ public function getRepository(EntityManagerInterface $entityManager, $entityName) { $metadata = $entityManager->getClassMetadata($entityName); $repositoryServiceId = $metadata->customRepositoryClassName; $customRepositoryName = $metadata->customRepositoryClassName; if (null !== $customRepositoryName) { // fetch from the container if ($this->container && $this->container->has($customRepositoryName)) { $repository = $this->container->get($customRepositoryName); if (!$repository instanceof EntityRepository) { throw new \RuntimeException(sprintf('The service "%s" must extend EntityRepository (or a base class, like ServiceEntityRepository).', $repositoryServiceId)); } return $repository; } // if not in the container but the class/id implements the interface, throw an error if (is_a($customRepositoryName, ServiceEntityRepositoryInterface::class, true)) { // can be removed when DoctrineBundle requires Symfony 3.3 if (null === $this->container) { throw new \RuntimeException(sprintf('Support for loading entities from the service container only works for Symfony 3.3 or higher. Upgrade your version of Symfony or make sure your "%s" class does not implement "%s"', $customRepositoryName, ServiceEntityRepositoryInterface::class)); } throw new \RuntimeException(sprintf('The "%s" entity repository implements "%s", but its service could not be found. Make sure the service exists and is tagged with "%s".', $customRepositoryName, ServiceEntityRepositoryInterface::class, ServiceRepositoryCompilerPass::REPOSITORY_SERVICE_TAG)); } if (!class_exists($customRepositoryName)) { throw new \RuntimeException(sprintf('The "%s" entity has a repositoryClass set to "%s", but this is not a valid class. Check your class naming. If this is meant to be a service id, make sure this service exists and is tagged with "%s".', $metadata->name, $customRepositoryName, ServiceRepositoryCompilerPass::REPOSITORY_SERVICE_TAG)); } // allow the repository to be created below } return $this->getOrCreateRepository($entityManager, $metadata); } private function getOrCreateRepository(EntityManagerInterface $entityManager, ClassMetadata $metadata) { $repositoryHash = $metadata->getName().spl_object_hash($entityManager); if (isset($this->managedRepositories[$repositoryHash])) { return $this->managedRepositories[$repositoryHash]; } $repositoryClassName = $metadata->customRepositoryClassName ?: $entityManager->getConfiguration()->getDefaultRepositoryClassName(); return $this->managedRepositories[$repositoryHash] = new $repositoryClassName($entityManager, $metadata); } } DoctrineBundle-1.8.1/Repository/ServiceEntityRepository.php000066400000000000000000000026771320601477700242320ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Repository; use Doctrine\Common\Persistence\ManagerRegistry; use Doctrine\ORM\EntityRepository; /** * Optional EntityRepository base class with a simplified constructor (for autowiring). * * To use in your class, inject the "registry" service and call * the parent constructor. For example: * * class YourEntityRepository extends ServiceEntityRepository * { * public function __construct(RegistryInterface $registry) * { * parent::__construct($registry, YourEntity::class); * } * } * * @author Ryan Weaver */ class ServiceEntityRepository extends EntityRepository implements ServiceEntityRepositoryInterface { /** * @param ManagerRegistry $registry * @param string $entityClass The class name of the entity this repository manages */ public function __construct(ManagerRegistry $registry, $entityClass) { $manager = $registry->getManagerForClass($entityClass); parent::__construct($manager, $manager->getClassMetadata($entityClass)); } } DoctrineBundle-1.8.1/Repository/ServiceEntityRepositoryInterface.php000066400000000000000000000011511320601477700260350ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Repository; /** * This interface signals that your repository should be loaded from the container. * * @author Ryan Weaver */ interface ServiceEntityRepositoryInterface { } DoctrineBundle-1.8.1/Resources/000077500000000000000000000000001320601477700164035ustar00rootroot00000000000000DoctrineBundle-1.8.1/Resources/config/000077500000000000000000000000001320601477700176505ustar00rootroot00000000000000DoctrineBundle-1.8.1/Resources/config/dbal.xml000066400000000000000000000124151320601477700212770ustar00rootroot00000000000000 Doctrine\DBAL\Logging\LoggerChain Doctrine\DBAL\Logging\DebugStack Symfony\Bridge\Doctrine\Logger\DbalLogger Doctrine\DBAL\Configuration Doctrine\Bundle\DoctrineBundle\DataCollector\DoctrineDataCollector Symfony\Bridge\Doctrine\ContainerAwareEventManager Doctrine\Bundle\DoctrineBundle\ConnectionFactory Doctrine\DBAL\Event\Listeners\MysqlSessionInit Doctrine\DBAL\Event\Listeners\OracleSessionInit Doctrine\Bundle\DoctrineBundle\Registry %doctrine.dbal.connection_factory.types% %doctrine.connections% %doctrine.entity_managers% %doctrine.default_connection% %doctrine.default_entity_manager% DoctrineBundle-1.8.1/Resources/config/orm.xml000066400000000000000000000316261320601477700211770ustar00rootroot00000000000000 Doctrine\ORM\Configuration Doctrine\ORM\EntityManager Doctrine\Bundle\DoctrineBundle\ManagerConfigurator Doctrine\Common\Cache\ArrayCache Doctrine\Common\Cache\ApcCache Doctrine\Common\Cache\MemcacheCache localhost 11211 Memcache Doctrine\Common\Cache\MemcachedCache localhost 11211 Memcached Doctrine\Common\Cache\RedisCache localhost 6379 Redis Doctrine\Common\Cache\XcacheCache Doctrine\Common\Cache\WinCacheCache Doctrine\Common\Cache\ZendDataCache Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain Doctrine\ORM\Mapping\Driver\AnnotationDriver Doctrine\ORM\Mapping\Driver\SimplifiedXmlDriver Doctrine\ORM\Mapping\Driver\SimplifiedYamlDriver Doctrine\ORM\Mapping\Driver\PHPDriver Doctrine\ORM\Mapping\Driver\StaticPHPDriver Symfony\Bridge\Doctrine\CacheWarmer\ProxyCacheWarmer Symfony\Bridge\Doctrine\Form\DoctrineOrmTypeGuesser Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator Symfony\Bridge\Doctrine\Validator\DoctrineInitializer Symfony\Bridge\Doctrine\Security\User\EntityUserProvider Doctrine\ORM\Tools\ResolveTargetEntityListener Doctrine\ORM\Tools\AttachEntityListenersListener Doctrine\ORM\Mapping\DefaultNamingStrategy Doctrine\ORM\Mapping\UnderscoreNamingStrategy Doctrine\ORM\Mapping\DefaultQuoteStrategy Doctrine\ORM\Mapping\AnsiQuoteStrategy Doctrine\Bundle\DoctrineBundle\Mapping\ContainerAwareEntityListenerResolver Doctrine\ORM\Cache\DefaultCacheFactory Doctrine\ORM\Cache\Region\DefaultRegion Doctrine\ORM\Cache\Region\FileLockRegion Doctrine\ORM\Cache\Logging\CacheLoggerChain Doctrine\ORM\Cache\Logging\StatisticsCacheLogger Doctrine\ORM\Cache\CacheConfiguration Doctrine\ORM\Cache\RegionsConfiguration null DoctrineBundle-1.8.1/Resources/config/schema/000077500000000000000000000000001320601477700211105ustar00rootroot00000000000000DoctrineBundle-1.8.1/Resources/config/schema/doctrine-1.0.xsd000066400000000000000000000316241320601477700237410ustar00rootroot00000000000000 DoctrineBundle-1.8.1/Resources/views/000077500000000000000000000000001320601477700175405ustar00rootroot00000000000000DoctrineBundle-1.8.1/Resources/views/Collector/000077500000000000000000000000001320601477700214665ustar00rootroot00000000000000DoctrineBundle-1.8.1/Resources/views/Collector/db.html.twig000066400000000000000000000534041320601477700237200ustar00rootroot00000000000000{% extends request.isXmlHttpRequest ? '@WebProfiler/Profiler/ajax_layout.html.twig' : '@WebProfiler/Profiler/layout.html.twig' %} {% import _self as helper %} {% block toolbar %} {% if collector.querycount > 0 or collector.invalidEntityCount > 0 %} {% set profiler_markup_version = profiler_markup_version|default(1) %} {% set icon %} {% if profiler_markup_version == 1 %} Database {{ collector.querycount }} {% if collector.querycount > 0 %} in {{ '%0.2f'|format(collector.time * 1000) }} ms {% endif %} {% if collector.invalidEntityCount > 0 %} {{ collector.invalidEntityCount }} {% endif %} {% else %} {% set status = collector.invalidEntityCount > 0 ? 'red' : collector.querycount > 50 ? 'yellow' %} {{ include('@Doctrine/Collector/icon.svg') }} {% if collector.querycount == 0 and collector.invalidEntityCount > 0 %} {{ collector.invalidEntityCount }} errors {% else %} {{ collector.querycount }} in {{ '%0.2f'|format(collector.time * 1000) }} ms {% endif %} {% endif %} {% endset %} {% set text %}
Database Queries {{ collector.querycount }}
Query time {{ '%0.2f'|format(collector.time * 1000) }} ms
Invalid entities {{ collector.invalidEntityCount }}
{% if collector.cacheEnabled %}
Cache hits {{ collector.cacheHitsCount }}
Cache misses {{ collector.cacheMissesCount }}
Cache puts {{ collector.cachePutsCount }}
{% else %}
Second Level Cache disabled
{% endif %} {% endset %} {{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { link: profiler_url, status: status|default('') }) }} {% endif %} {% endblock %} {% block menu %} {% set profiler_markup_version = profiler_markup_version|default(1) %} {% if profiler_markup_version == 1 %} Doctrine {{ collector.querycount }} {{ '%0.0f'|format(collector.time * 1000) }} ms {% else %} {{ include('@Doctrine/Collector/icon.svg') }} Doctrine {% if collector.invalidEntityCount %} {{ collector.invalidEntityCount }} {% endif %} {% endif %} {% endblock %} {% block panel %} {% set profiler_markup_version = profiler_markup_version|default(1) %} {% if 'explain' == page %} {{ render(controller('DoctrineBundle:Profiler:explain', { token: token, panel: 'db', connectionName: request.query.get('connection'), query: request.query.get('query') })) }} {% else %} {{ block('queries') }} {% endif %} {% endblock %} {% block queries %} {% if profiler_markup_version > 1 %}

Query Metrics

{{ collector.querycount }} Database Queries
{{ collector.groupedQueryCount }} Different statements
{{ '%0.2f'|format(collector.time * 1000) }} ms Query time
{{ collector.invalidEntityCount }} Invalid entities
{% if collector.cacheEnabled %}
{{ collector.cacheHitsCount }} Cache hits
{{ collector.cacheMissesCount }} Cache misses
{{ collector.cachePutsCount }} Cache puts
{% endif %}
{% endif %} {% set group_queries = request.query.getBoolean('group') %} {% if group_queries %}

Grouped Statements

Show all queries

{% else %}

Queries

Group similar statements

{% endif %} {% for connection, queries in collector.queries %} {% if collector.connections|length > 1 %}

{{ connection }} connection

{% endif %} {% if queries is empty %}

No database queries were performed.

{% else %} {% if group_queries %} {% set queries = collector.groupedQueries[connection] %} {% endif %} {% if group_queries %} {% else %} {% endif %} {% for i, query in queries %} {% set i = group_queries ? query.index : i %} {% if group_queries %} {% else %} {% endif %} {% endfor %}
Time Count# TimeInfo
{{ '%0.2f'|format(query.executionMS * 1000) }} ms
({{ '%0.2f'|format(query.executionPercent) }}%)
{{ query.count }}{{ loop.index }} {{ '%0.2f'|format(query.executionMS * 1000) }} ms {{ query.sql|doctrine_pretty_query(highlight_only = true) }}
Parameters: {{ profiler_dump(query.params, 2) }}
View formatted query    View runnable query {% if query.explainable %}    Explain query {% endif %}
{% if query.explainable %}
{% endif %}
{% endif %} {% endfor %}

Database Connections

{% if not collector.connections %}

There are no configured database connections.

{% else %} {{ helper.render_simple_table('Name', 'Service', collector.connections) }} {% endif %}

Entity Managers

{% if not collector.managers %}

There are no configured entity managers.

{% else %} {{ helper.render_simple_table('Name', 'Service', collector.managers) }} {% endif %}

Second Level Cache

{% if not collector.cacheEnabled %}

Second Level Cache is not enabled.

{% else %} {% if not collector.cacheCounts %}

Second level cache information is not available.

{% else %} {% if profiler_markup_version == 1 %} {{ helper.render_simple_table('Key', 'Value', collector.cacheCounts) }} {% else %}
{{ collector.cacheCounts.hits }} Hits
{{ collector.cacheCounts.misses }} Misses
{{ collector.cacheCounts.puts }} Puts
{% endif %} {% if collector.cacheRegions.hits %}

Number of cache hits

{{ helper.render_simple_table('Region', 'Hits', collector.cacheRegions.hits) }} {% endif %} {% if collector.cacheRegions.misses %}

Number of cache misses

{{ helper.render_simple_table('Region', 'Misses', collector.cacheRegions.misses) }} {% endif %} {% if collector.cacheRegions.puts %}

Number of cache puts

{{ helper.render_simple_table('Region', 'Puts', collector.cacheRegions.puts) }} {% endif %} {% endif %} {% endif %}

Entities Mapping

{% for manager, classes in collector.entities %} {% if collector.managers|length > 1 %}

{{ manager }} entity manager

{% endif %} {% if classes is empty %}

No loaded entities.

{% else %} {% for class in classes %} {% set contains_errors = collector.mappingErrors[manager] is defined and collector.mappingErrors[manager][class] is defined %} {% endfor %}
Class Mapping errors
{{ class }} {% if contains_errors %}
    {% for error in collector.mappingErrors[manager][class] %}
  • {{ error }}
  • {% endfor %}
{% else %} No errors. {% endif %}
{% endif %} {% endfor %} {% endblock %} {% macro render_simple_table(label1, label2, data) %} {% for key, value in data %} {% endfor %}
{{ label1 }} {{ label2 }}
{{ key }} {{ value }}
{% endmacro %} DoctrineBundle-1.8.1/Resources/views/Collector/explain.html.twig000066400000000000000000000015651320601477700247740ustar00rootroot00000000000000{% if data[0]|length > 1 %} {# The platform returns a table for the explanation (e.g. MySQL), display all columns #} {% for label in data[0]|keys %} {% endfor %} {% for row in data %} {% for key, item in row %} {% endfor %} {% endfor %}
{{ label }}
{{ item|replace({',': ', '}) }}
{% else %} {# The Platform returns a single column for a textual explanation (e.g. PostgreSQL), display all lines #}
        {%- for row in data -%}
            {{ row|first }}{{ "\n" }}
        {%- endfor -%}
    
{% endif %} DoctrineBundle-1.8.1/Resources/views/Collector/icon.svg000066400000000000000000000012221320601477700231340ustar00rootroot00000000000000 DoctrineBundle-1.8.1/Twig/000077500000000000000000000000001320601477700153435ustar00rootroot00000000000000DoctrineBundle-1.8.1/Twig/DoctrineExtension.php000066400000000000000000000257611320601477700215330ustar00rootroot00000000000000 * (c) Doctrine Project, Benjamin Eberlei * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Doctrine\Bundle\DoctrineBundle\Twig; use Symfony\Component\VarDumper\Cloner\Data; /** * This class contains the needed functions in order to do the query highlighting * * @author Florin Patan * @author Christophe Coevoet */ class DoctrineExtension extends \Twig_Extension { /** * Number of maximum characters that one single line can hold in the interface * * @var int */ private $maxCharWidth = 100; /** * Define our functions * * @return \Twig_SimpleFilter[] */ public function getFilters() { return array( new \Twig_SimpleFilter('doctrine_minify_query', array($this, 'minifyQuery'), array('deprecated' => true)), new \Twig_SimpleFilter('doctrine_pretty_query', array($this, 'formatQuery'), array('is_safe' => array('html'))), new \Twig_SimpleFilter('doctrine_replace_query_parameters', array($this, 'replaceQueryParameters')), ); } /** * Get the possible combinations of elements from the given array * * @param array $elements * @param integer $combinationsLevel * * @return array */ private function getPossibleCombinations(array $elements, $combinationsLevel) { $baseCount = count($elements); $result = array(); if (1 === $combinationsLevel) { foreach ($elements as $element) { $result[] = array($element); } return $result; } $nextLevelElements = $this->getPossibleCombinations($elements, $combinationsLevel - 1); foreach ($nextLevelElements as $nextLevelElement) { $lastElement = $nextLevelElement[$combinationsLevel - 2]; $found = false; foreach ($elements as $key => $element) { if ($element == $lastElement) { $found = true; continue; } if ($found == true && $key < $baseCount) { $tmp = $nextLevelElement; $newCombination = array_slice($tmp, 0); $newCombination[] = $element; $result[] = array_slice($newCombination, 0); } } } return $result; } /** * Shrink the values of parameters from a combination * * @param array $parameters * @param array $combination * * @return string */ private function shrinkParameters(array $parameters, array $combination) { array_shift($parameters); $result = ''; $maxLength = $this->maxCharWidth; $maxLength -= count($parameters) * 5; $maxLength = $maxLength / count($parameters); foreach ($parameters as $key => $value) { $isLarger = false; if (strlen($value) > $maxLength) { $value = wordwrap($value, $maxLength, "\n", true); $value = explode("\n", $value); $value = $value[0]; $isLarger = true; } $value = self::escapeFunction($value); if (!is_numeric($value)) { $value = substr($value, 1, -1); } if ($isLarger) { $value .= ' [...]'; } $result .= ' '.$combination[$key].' '.$value; } return trim($result); } /** * Attempt to compose the best scenario minified query so that a user could find it without expanding it * * @param string $query * @param array $keywords * @param integer $required * * @return string */ private function composeMiniQuery($query, array $keywords, $required) { // Extract the mandatory keywords and consider the rest as optional keywords $mandatoryKeywords = array_splice($keywords, 0, $required); $combinations = array(); $combinationsCount = count($keywords); // Compute all the possible combinations of keywords to match the query for while ($combinationsCount > 0) { $combinations = array_merge($combinations, $this->getPossibleCombinations($keywords, $combinationsCount)); $combinationsCount--; } // Try and match the best case query pattern foreach ($combinations as $combination) { $combination = array_merge($mandatoryKeywords, $combination); $regexp = implode('(.*) ', $combination).' (.*)'; $regexp = '/^'.$regexp.'/is'; if (preg_match($regexp, $query, $matches)) { $result = $this->shrinkParameters($matches, $combination); return $result; } } // Try and match the simplest query form that contains only the mandatory keywords $regexp = implode(' (.*)', $mandatoryKeywords).' (.*)'; $regexp = '/^'.$regexp.'/is'; if (preg_match($regexp, $query, $matches)) { $result = $this->shrinkParameters($matches, $mandatoryKeywords); return $result; } // Fallback in case we didn't managed to find any good match (can we actually have that happen?!) $result = substr($query, 0, $this->maxCharWidth); return $result; } /** * Minify the query * * @param string $query * * @return string */ public function minifyQuery($query) { $result = ''; $keywords = array(); $required = 1; // Check if we can match the query against any of the major types switch (true) { case stripos($query, 'SELECT') !== false: $keywords = array('SELECT', 'FROM', 'WHERE', 'HAVING', 'ORDER BY', 'LIMIT'); $required = 2; break; case stripos($query, 'DELETE') !== false: $keywords = array('DELETE', 'FROM', 'WHERE', 'ORDER BY', 'LIMIT'); $required = 2; break; case stripos($query, 'UPDATE') !== false: $keywords = array('UPDATE', 'SET', 'WHERE', 'ORDER BY', 'LIMIT'); $required = 2; break; case stripos($query, 'INSERT') !== false: $keywords = array('INSERT', 'INTO', 'VALUE', 'VALUES'); $required = 2; break; // If there's no match so far just truncate it to the maximum allowed by the interface default: $result = substr($query, 0, $this->maxCharWidth); } // If we had a match then we should minify it if ($result == '') { $result = $this->composeMiniQuery($query, $keywords, $required); } return $result; } /** * Escape parameters of a SQL query * DON'T USE THIS FUNCTION OUTSIDE ITS INTENDED SCOPE * * @internal * * @param mixed $parameter * * @return string */ public static function escapeFunction($parameter) { $result = $parameter; switch (true) { // Check if result is non-unicode string using PCRE_UTF8 modifier case is_string($result) && !preg_match('//u', $result): $result = '0x'. strtoupper(bin2hex($result)); break; case is_string($result): $result = "'".addslashes($result)."'"; break; case is_array($result): foreach ($result as &$value) { $value = static::escapeFunction($value); } $result = implode(', ', $result); break; case is_object($result): $result = addslashes((string) $result); break; case null === $result: $result = 'NULL'; break; case is_bool($result): $result = $result ? '1' : '0'; break; } return $result; } /** * Return a query with the parameters replaced * * @param string $query * @param array|Data $parameters * * @return string */ public function replaceQueryParameters($query, $parameters) { if ($parameters instanceof Data) { // VarDumper < 3.3 compatibility layer $parameters = method_exists($parameters, 'getValue') ? $parameters->getValue(true) : $parameters->getRawData(); } $i = 0; if (!array_key_exists(0, $parameters) && array_key_exists(1, $parameters)) { $i = 1; } $result = preg_replace_callback( '/\?|((?([^"]*+)<\/pre>/Us', '\1', $html); } else { $html = \SqlFormatter::format($sql); $html = preg_replace('/
([^"]*+)<\/pre>/Us', '
\2
', $html); } return $html; } /** * Get the name of the extension * * @return string */ public function getName() { return 'doctrine_extension'; } } DoctrineBundle-1.8.1/composer.json000066400000000000000000000040041320601477700171510ustar00rootroot00000000000000{ "name": "doctrine/doctrine-bundle", "type": "symfony-bundle", "description": "Symfony DoctrineBundle", "keywords": ["DBAL", "ORM", "Database", "Persistence"], "homepage": "http://www.doctrine-project.org", "license": "MIT", "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" }, { "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, { "name": "Symfony Community", "homepage": "http://symfony.com/contributors" }, { "name": "Doctrine Project", "homepage": "http://www.doctrine-project.org/" } ], "require": { "php": "^5.5.9|^7.0", "symfony/framework-bundle": "~2.7|~3.0|~4.0", "symfony/console": "~2.7|~3.0|~4.0", "symfony/dependency-injection": "~2.7|~3.0|~4.0", "doctrine/dbal": "^2.5.12", "jdorn/sql-formatter": "^1.2.16", "symfony/doctrine-bridge": "~2.7|~3.0|~4.0", "doctrine/doctrine-cache-bundle": "~1.2" }, "require-dev": { "doctrine/orm": "~2.3", "symfony/yaml": "~2.7|~3.0|~4.0", "symfony/validator": "~2.7|~3.0|~4.0", "symfony/property-info": "~2.8|~3.0|~4.0", "symfony/phpunit-bridge": "~2.7|~3.0|~4.0", "twig/twig": "~1.26|~2.0", "satooshi/php-coveralls": "^1.0", "phpunit/phpunit": "^4.8.36|^5.7|^6.4", "symfony/web-profiler-bundle": "~2.7|~3.0|~4.0" }, "conflict": { "symfony/http-foundation": "<2.6" }, "suggest": { "symfony/web-profiler-bundle": "To use the data collector.", "doctrine/orm": "The Doctrine ORM integration is optional in the bundle." }, "autoload": { "psr-4": { "Doctrine\\Bundle\\DoctrineBundle\\": "" } }, "autoload-dev": { "psr-4": { "": "Tests/DependencyInjection" } }, "extra": { "branch-alias": { "dev-master": "1.8.x-dev" } } }