├── .gitignore ├── composer.json ├── library └── Bisna │ ├── Exception │ └── NameNotFoundException.php │ ├── Application │ └── Resource │ │ └── Doctrine.php │ └── Doctrine │ └── Container.php ├── application ├── Bootstrap.php └── configs │ └── application.ini ├── bin └── doctrine.php └── README.markdown /.gitignore: -------------------------------------------------------------------------------- 1 | # ignore eclipse files 2 | .settings 3 | .buildpath 4 | 5 | # ignore third party libs 6 | vendor 7 | 8 | # ignore the composer lock file 9 | composer.lock 10 | 11 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "guilhermeblanco/zendframework1-doctrine2", 3 | "require": { 4 | "zendframework/zendframework1": "~1.9", 5 | "doctrine/orm": "~2.3" 6 | }, 7 | "autoload": { 8 | "psr-0": {"Bisna": "library/"} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /library/Bisna/Exception/NameNotFoundException.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class NameNotFoundException extends \Exception 11 | { 12 | } 13 | -------------------------------------------------------------------------------- /application/Bootstrap.php: -------------------------------------------------------------------------------- 1 | pushAutoloader(array($fmmAutoloader, 'loadClass'), 'Bisna'); 12 | } 13 | 14 | } 15 | 16 | -------------------------------------------------------------------------------- /library/Bisna/Application/Resource/Doctrine.php: -------------------------------------------------------------------------------- 1 | 11 | */ 12 | class Doctrine extends \Zend_Application_Resource_ResourceAbstract 13 | { 14 | /** 15 | * @var Bisna\Doctrine\Container 16 | */ 17 | protected $container; 18 | 19 | /** 20 | * Initializes Doctrine Context. 21 | * 22 | * @return Bisna\Doctrine\Container 23 | */ 24 | public function init() 25 | { 26 | $config = $this->getOptions(); 27 | 28 | // Starting Doctrine container 29 | $this->container = new DoctrineContainer($config); 30 | 31 | // Add to Zend Registry 32 | \Zend_Registry::set('doctrine', $this->container); 33 | 34 | return $this->container; 35 | } 36 | 37 | /** 38 | * Retrieve the Doctrine Container. 39 | * 40 | * @return Bisna\Doctrine\Container 41 | */ 42 | public function getContainer() 43 | { 44 | return $this->container; 45 | } 46 | } -------------------------------------------------------------------------------- /bin/doctrine.php: -------------------------------------------------------------------------------- 1 | bootstrap()->getBootstrap(); 28 | 29 | // Retrieve Doctrine Container resource 30 | $container = $bootstrap->getResource('doctrine'); 31 | 32 | // Console 33 | $cli = new \Symfony\Component\Console\Application( 34 | 'Doctrine Command Line Interface', 35 | \Doctrine\Common\Version::VERSION 36 | ); 37 | 38 | try { 39 | // Bootstrapping Console HelperSet 40 | $helperSet = array(); 41 | 42 | if (($dbal = $container->getConnection(getenv('CONN') ?: $container->defaultConnection)) !== null) { 43 | $helperSet['db'] = new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($dbal); 44 | } 45 | 46 | if (($em = $container->getEntityManager(getenv('EM') ?: $container->defaultEntityManager)) !== null) { 47 | $helperSet['em'] = new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em); 48 | } 49 | } catch (\Exception $e) { 50 | $cli->renderException($e, new \Symfony\Component\Console\Output\ConsoleOutput()); 51 | } 52 | 53 | $cli->setCatchExceptions(true); 54 | $cli->setHelperSet(new \Symfony\Component\Console\Helper\HelperSet($helperSet)); 55 | 56 | $cli->addCommands(array( 57 | // DBAL Commands 58 | new \Doctrine\DBAL\Tools\Console\Command\RunSqlCommand(), 59 | new \Doctrine\DBAL\Tools\Console\Command\ImportCommand(), 60 | 61 | // ORM Commands 62 | new \Doctrine\ORM\Tools\Console\Command\ClearCache\MetadataCommand(), 63 | new \Doctrine\ORM\Tools\Console\Command\ClearCache\ResultCommand(), 64 | new \Doctrine\ORM\Tools\Console\Command\ClearCache\QueryCommand(), 65 | new \Doctrine\ORM\Tools\Console\Command\SchemaTool\CreateCommand(), 66 | new \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand(), 67 | new \Doctrine\ORM\Tools\Console\Command\SchemaTool\DropCommand(), 68 | new \Doctrine\ORM\Tools\Console\Command\EnsureProductionSettingsCommand(), 69 | new \Doctrine\ORM\Tools\Console\Command\ConvertDoctrine1SchemaCommand(), 70 | new \Doctrine\ORM\Tools\Console\Command\GenerateRepositoriesCommand(), 71 | new \Doctrine\ORM\Tools\Console\Command\GenerateEntitiesCommand(), 72 | new \Doctrine\ORM\Tools\Console\Command\GenerateProxiesCommand(), 73 | new \Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand(), 74 | new \Doctrine\ORM\Tools\Console\Command\RunDqlCommand(), 75 | new \Doctrine\ORM\Tools\Console\Command\ValidateSchemaCommand(), 76 | 77 | )); 78 | 79 | $cli->run(); 80 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | # Zend Framework 1.X + Doctrine 2.X integration 2 | 3 | ZF1-D2 is an integration tool to allow you use Doctrine 2 at the top of Zend Framework 1. 4 | 5 | ## Installation 6 | 7 | Install ZF1-D2 using [Composer](http://getcomposer.org) 8 | 9 | ### Create your composer.json file 10 | 11 | { 12 | "require": { 13 | "guilhermeblanco/zendframework1-doctrine2": "master-dev" 14 | }, 15 | "minimum-stability": "dev" 16 | } 17 | 18 | ### Download composer into your application root 19 | 20 | $ curl -s http://getcomposer.org/installer | php 21 | 22 | ### Install your dependencies 23 | 24 | $ php composer.phar install 25 | 26 | ## Configuring 27 | 28 | Doctrine 2 requires different parts of configuration. 29 | 30 | - Cache 31 | - DBAL 32 | - ORM 33 | 34 | ### Configuring Namespaces 35 | 36 | Since parts of Doctrine rely on specific commit pointers of individual Doctrine packages, a class loader is required to allow a customized configuration of Namespaces. 37 | One good example is default Doctrine GIT clone, which points to Doctrine\Common and Doctrine\DBAL packages through git submodules. 38 | To address this different paths issue, Bisna provides an specific class laoder configuration, which allows you to correclty map your environment. 39 | Here is an example of configuration: 40 | 41 | ; Doctrine Common ClassLoader class and file 42 | resources.doctrine.classLoader.loaderClass = "Doctrine\Common\ClassLoader" 43 | resources.doctrine.classLoader.loaderFile = APPLICATION_PATH "/../library/vendor/doctrine/common/lib/Doctrine/Common/ClassLoader.php" 44 | 45 | ; Namespace loader for Doctrine\Common 46 | resources.doctrine.classLoader.loaders.doctrine_common.namespace = "Doctrine\Common" 47 | resources.doctrine.classLoader.loaders.doctrine_common.includePath = APPLICATION_PATH "/../library/vendor/doctrine/common/lib/Doctrine/Common" 48 | 49 | ; Namespace loader for Doctrine\DBAL 50 | resources.doctrine.classLoader.loaders.doctrine_dbal.namespace = "Doctrine\DBAL" 51 | resources.doctrine.classLoader.loaders.doctrine_dbal.includePath = APPLICATION_PATH "/../library/vendor/doctrine/dbal/lib/Doctrine/DBAL" 52 | 53 | ; Namespace loader for Doctrine\ORM 54 | resources.doctrine.classLoader.loaders.doctrine_orm.namespace = "Doctrine\ORM" 55 | resources.doctrine.classLoader.loaders.doctrine_orm.includePath = APPLICATION_PATH "/../library/vendor/doctrine/orm/lib/Doctrine/ORM" 56 | 57 | ; Namespace loader for Symfony\Component\Console 58 | resources.doctrine.classLoader.loaders.symfony_console.namespace = "Symfony\Component\Console" 59 | resources.doctrine.classLoader.loaders.symfony_console.includePath = APPLICATION_PATH "/../library/vendor/symfony/console/Symfony/Component/Console" 60 | 61 | ; Namespace loader for Symfony\Component\Yaml 62 | resources.doctrine.classLoader.loaders.symfony_yaml.namespace = "Symfony\Component\Yaml" 63 | resources.doctrine.classLoader.loaders.symfony_yaml.includePath = APPLICATION_PATH "/../library/vendor/Doctrine/lib/vendor" 64 | 65 | 66 | ### Configuring Cache 67 | 68 | Currently, Doctrine 2 allows you to use the following different Cache drivers: 69 | 70 | - APC 71 | - Array 72 | - Couchbase 73 | - Memcache 74 | - Xcache 75 | 76 | You are allowed to define multiple cache connections. If you attempt to retrieve a cache instance without a name, it will attempt to grab the defaultCacheInstance value as key. The default name of default cache instance is "default". To change it, you can simply alter the default name with the following line: 77 | 78 | resources.doctrine.cache.defaultCacheInstance = my_cache_instance 79 | 80 | All cache instances have a name. Based on this name you are able to correctly configure your cache instance. 81 | Here is a good example of a Memcache driver with multiple servers being used. 82 | 83 | ; Cache Instance configuration for "default" cache 84 | resources.doctrine.cache.instances.default.adapterClass = "Doctrine\Common\Cache\MemcacheCache" 85 | resources.doctrine.cache.instances.default.namespace = "MyApplication_" 86 | 87 | ; Server configuration (index "0") 88 | resources.doctrine.cache.instances.default.options.servers.0.host = localhost 89 | resources.doctrine.cache.instances.default.options.servers.0.port = 11211 90 | resources.doctrine.cache.instances.default.options.servers.0.persistent = true 91 | resources.doctrine.cache.instances.default.options.servers.0.retryInterval = 15 92 | 93 | ; Server configuration (index "1") 94 | resources.doctrine.cache.instances.default.options.servers.1.host = localhost 95 | resources.doctrine.cache.instances.default.options.servers.1.port = 11211 96 | resources.doctrine.cache.instances.default.options.servers.1.persistent = true 97 | resources.doctrine.cache.instances.default.options.servers.1.weight = 1 98 | resources.doctrine.cache.instances.default.options.servers.1.timeout = 1 99 | resources.doctrine.cache.instances.default.options.servers.1.retryInterval = 15 100 | resources.doctrine.cache.instances.default.options.servers.1.status = true 101 | 102 | ### Configuring DBAL 103 | 104 | Doctrine DataBase Abstraction Layer follows the same idea of Cache drivers. 105 | 106 | ; Points to default connection to be used. Optional if only one connection is defined 107 | resources.doctrine.dbal.defaultConnection = default 108 | 109 | ; DBAL Connection configuration for "default" connection 110 | ;resources.doctrine.dbal.connections.default.id = default 111 | ;resources.doctrine.dbal.connections.default.eventManagerClass = "Doctrine\Common\EventManager" 112 | ;resources.doctrine.dbal.connections.default.eventSubscribers[] = "DoctrineExtensions\Sluggable\SluggableSubscriber" 113 | ;resources.doctrine.dbal.connections.default.configurationClass = "Doctrine\DBAL\Configuration" 114 | ;resources.doctrine.dbal.connections.default.sqlLoggerClass = "Doctrine\DBAL\Logging\EchoSQLLogger" 115 | 116 | ; Database configuration 117 | ;resources.doctrine.dbal.connections.default.parameters.wrapperClass = "" 118 | resources.doctrine.dbal.connections.default.parameters.driver = "pdo_mysql" 119 | resources.doctrine.dbal.connections.default.parameters.dbname = "fmm" 120 | resources.doctrine.dbal.connections.default.parameters.host = "localhost" 121 | resources.doctrine.dbal.connections.default.parameters.port = 3306 122 | resources.doctrine.dbal.connections.default.parameters.user = "root" 123 | resources.doctrine.dbal.connections.default.parameters.password = "password" 124 | ;resources.doctrine.dbal.connections.default.parameters.driverOptions.ATTR_USE_BUFFERED_QUERIES = true 125 | 126 | ### Configuring ORM 127 | 128 | TBD 129 | 130 | ## Using 131 | 132 | ### Accessing Doctrine Container 133 | 134 | It is strongly recommended to encapsulate the default Zend_Controller_Action class into our project's one. 135 | By using this encapsulation, it allows you to include your own support without having to hack default Zend implementation. 136 | 137 | A very rudimentary implementation of a possible base class is here: 138 | 139 | 140 | 148 | */ 149 | class Action extends \Zend_Controller_Action 150 | { 151 | /** 152 | * Retrieve the Doctrine Container. 153 | * 154 | * @return Bisna\Doctrine\Container 155 | */ 156 | public function getDoctrineContainer() 157 | { 158 | return $this->getInvokeArg('bootstrap')->getResource('doctrine'); 159 | } 160 | } 161 | 162 | ### Doctrine Container API 163 | 164 | The following API exposes all available Doctrine Container methods to be used by developers: 165 | 166 | 177 | */ 178 | class DoctrineContainer 179 | { 180 | /** 181 | * Retrieve Cache Instance based on its name. If no argument is provided, 182 | * it will attempt to get the default Instance. 183 | * If Cache Instance name could not be found, NameNotFoundException is thrown. 184 | * 185 | * @throws Bisna\Application\Exception\NameNotFoundException 186 | * 187 | * @param string $cacheName Optional Cache Instance name 188 | * 189 | * @return Doctrine\Common\Cache\Cache Cache Instance 190 | */ 191 | public function getCacheInstance($cacheName = null); 192 | 193 | /** 194 | * Retrieve DBAL Connection based on its name. If no argument is provided, 195 | * it will attempt to get the default Connection. 196 | * If DBAL Connection could not be retrieved, NameNotFoundException is thrown. 197 | * 198 | * @throws Bisna\Application\Exception\NameNotFoundException 199 | * 200 | * @param string $connName Optional DBAL Connection name 201 | * 202 | * @return Doctrine\DBAL\Connection DBAL Connection 203 | */ 204 | public function getConnection($connName = null); 205 | 206 | /** 207 | * Retrieve ORM EntityManager based on its name. If no argument provided, 208 | * it will attempt to get the default EntityManager. 209 | * If ORM EntityManager could not be retrieved, NameNotFoundException is thrown. 210 | * 211 | * @throws Bisna\Application\Exception\NameNotFoundException 212 | * 213 | * @param string $emName Optional ORM EntityManager name 214 | * 215 | * @return Doctrine\ORM\EntityManager ORM EntityManager 216 | */ 217 | public function getEntityManager($emName = null); 218 | } -------------------------------------------------------------------------------- /application/configs/application.ini: -------------------------------------------------------------------------------- 1 | [production] 2 | 3 | ; -------------------------- 4 | ; PHP Specific Configuration 5 | ; -------------------------- 6 | phpSettings.display_startup_errors = 0 7 | phpSettings.display_errors = 0 8 | 9 | includePaths.library = APPLICATION_PATH "/../library" 10 | 11 | 12 | ; ---------------------------------------- 13 | ; Zend Framework Application Configuration 14 | ; ---------------------------------------- 15 | bootstrap.path = APPLICATION_PATH "/Bootstrap.php" 16 | bootstrap.class = "Bootstrap" 17 | 18 | pluginPaths.Bisna\Application\Resource\ = "Bisna/Application/Resource" 19 | 20 | autoloaderNamespaces[] = Bisna 21 | autoloaderNamespaces[] = Application\Entity 22 | 23 | appnamespace = "Application" 24 | 25 | 26 | ; ------------------------------ 27 | ; Front Controller Configuration 28 | ; ------------------------------ 29 | 30 | resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers" 31 | resources.frontController.params.displayExceptions = 0 32 | 33 | 34 | ; ------------------------------------------------------------------------------ 35 | ; Doctrine Class Loader Configuration 36 | ; ------------------------------------------------------------------------------ 37 | 38 | resources.doctrine.classLoader.loaderClass = "Doctrine\Common\ClassLoader" 39 | resources.doctrine.classLoader.loaderFile = APPLICATION_PATH "/../library/vendor/doctrine/common/lib/Doctrine/Common/ClassLoader.php" 40 | 41 | resources.doctrine.classLoader.loaders.doctrine_common.namespace = "Doctrine\Common" 42 | resources.doctrine.classLoader.loaders.doctrine_common.includePath = APPLICATION_PATH "/../library/vendor/doctrine/common/lib/Doctrine/Common" 43 | 44 | resources.doctrine.classLoader.loaders.doctrine_dbal.namespace = "Doctrine\DBAL" 45 | resources.doctrine.classLoader.loaders.doctrine_dbal.includePath = APPLICATION_PATH "/../library/vendor/doctrine/dbal/lib/Doctrine/DBAL" 46 | 47 | resources.doctrine.classLoader.loaders.doctrine_orm.namespace = "Doctrine\ORM" 48 | resources.doctrine.classLoader.loaders.doctrine_orm.includePath = APPLICATION_PATH "/../library/vendor/doctrine/orm/lib/Doctrine/ORM" 49 | 50 | resources.doctrine.classLoader.loaders.symfony_console.namespace = "Symfony\Component\Console" 51 | resources.doctrine.classLoader.loaders.symfony_console.includePath = APPLICATION_PATH "/../library/vendor/symfony/console/Symfony/Component/Console" 52 | 53 | resources.doctrine.classLoader.loaders.symfony_yaml.namespace = "Symfony\Component\Yaml" 54 | resources.doctrine.classLoader.loaders.symfony_yaml.includePath = APPLICATION_PATH "/../library/vendor/Doctrine/lib/vendor" 55 | 56 | ; ------------------------------------------------------------------------------ 57 | ; Doctrine Cache Configuration 58 | ; ------------------------------------------------------------------------------ 59 | 60 | ; Points to default cache instance to be used. Optional is only one cache is defined 61 | resources.doctrine.cache.defaultCacheInstance = default 62 | 63 | ; Cache Instance configuration for "default" cache 64 | ;resources.doctrine.cache.instances.default.id = default 65 | resources.doctrine.cache.instances.default.adapterClass = "Doctrine\Common\Cache\MemcacheCache" 66 | resources.doctrine.cache.instances.default.namespace = "Application_" 67 | resources.doctrine.cache.instances.default.options.servers.0.host = localhost 68 | resources.doctrine.cache.instances.default.options.servers.0.port = 11211 69 | ;resources.doctrine.cache.instances.default.options.servers.0.persistent = true 70 | ;resources.doctrine.cache.instances.default.options.servers.0.weight = 1 71 | ;resources.doctrine.cache.instances.default.options.servers.0.timeout = 1 72 | ;resources.doctrine.cache.instances.default.options.servers.0.retryInterval = 15 73 | ;resources.doctrine.cache.instances.default.options.servers.0.status = true 74 | 75 | ; Cache Instance configuration example for "default" FilesystemCache 76 | ;resources.doctrine.cache.instances.default.adapterClass = "Doctrine\Common\Cache\FilesystemCache" 77 | ;resources.doctrine.cache.instances.default.namespace = "Application_" 78 | ;resources.doctrine.cache.instances.default.options.directory = "/tmp/doctrine" 79 | ;resources.doctrine.cache.instances.default.options.extension = ".doctrinecache.data" 80 | 81 | ; ------------------------------------------------------------------------------ 82 | ; Doctrine DBAL Configuration 83 | ; ------------------------------------------------------------------------------ 84 | 85 | ; Points to default connection to be used. Optional if only one connection is defined 86 | resources.doctrine.dbal.defaultConnection = default 87 | 88 | ; DBAL Connection configuration for "default" connection 89 | ;resources.doctrine.dbal.connections.default.id = default 90 | ;resources.doctrine.dbal.connections.default.eventManagerClass = "Doctrine\Common\EventManager" 91 | ;resources.doctrine.dbal.connections.default.eventSubscribers[] = "DoctrineExtensions\Sluggable\SluggableSubscriber" 92 | ;resources.doctrine.dbal.connections.default.configurationClass = "Doctrine\DBAL\Configuration" 93 | ;resources.doctrine.dbal.connections.default.sqlLoggerClass = "Doctrine\DBAL\Logging\EchoSQLLogger" 94 | ;resources.doctrine.dbal.connections.default.sqlLoggerParams = ""; whatever your logger requires 95 | ;resources.doctrine.dbal.connections.default.types.my_type = "Application\DBAL\Type\MyType" 96 | 97 | ; Database configuration 98 | ;resources.doctrine.dbal.connections.default.parameters.wrapperClass = "" 99 | resources.doctrine.dbal.connections.default.parameters.driver = "pdo_mysql" 100 | resources.doctrine.dbal.connections.default.parameters.dbname = "fmm" 101 | resources.doctrine.dbal.connections.default.parameters.host = "localhost" 102 | resources.doctrine.dbal.connections.default.parameters.port = 3306 103 | resources.doctrine.dbal.connections.default.parameters.user = "root" 104 | resources.doctrine.dbal.connections.default.parameters.password = "password" 105 | ;resources.doctrine.dbal.connections.default.parameters.driverOptions.ATTR_USE_BUFFERED_QUERIES = true 106 | 107 | 108 | ; ------------------------------------------------------------------------------ 109 | ; Doctrine ORM Configuration 110 | ; ------------------------------------------------------------------------------ 111 | 112 | ; Points to default EntityManager to be used. Optional if only one EntityManager is defined 113 | resources.doctrine.orm.defaultEntityManager = default 114 | 115 | ; EntityManager configuration for "default" manager 116 | ;resources.doctrine.orm.entityManagers.default.id = default 117 | ;resources.doctrine.orm.entityManagers.default.entityManagerClass = "Doctrine\ORM\EntityManager" 118 | ;resources.doctrine.orm.entityManagers.default.configurationClass = "Doctrine\ORM\Configuration" 119 | ;resources.doctrine.orm.entityManagers.default.defaultRepositoryClass = "Doctrine\ORM\EntityRepository" 120 | ;resources.doctrine.orm.entityManagers.default.entityNamespaces.app = "Application\Entity" 121 | resources.doctrine.orm.entityManagers.default.connection = default 122 | resources.doctrine.orm.entityManagers.default.proxy.autoGenerateClasses = true 123 | resources.doctrine.orm.entityManagers.default.proxy.namespace = "Application\Entity\Proxy" 124 | resources.doctrine.orm.entityManagers.default.proxy.dir = APPLICATION_PATH "/../library/Application/Entity/Proxy" 125 | ;resources.doctrine.orm.entityManagers.default.metadataCache = default 126 | ;resources.doctrine.orm.entityManagers.default.queryCache = default 127 | ;resources.doctrine.orm.entityManagers.default.resultCache = default 128 | ;resources.doctrine.orm.entityManagers.default.DQLFunctions.numeric.PI = "DoctrineExtensions\ORM\Query\Functions\Numeric\PiFunction" 129 | resources.doctrine.orm.entityManagers.default.metadataDrivers.annotationRegistry.annotationFiles[] = APPLICATION_PATH "/../library/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php" 130 | ;resources.doctrine.orm.entityManagers.default.metadataDrivers.annotationRegistry.annotationNamespaces.0.namespace = "Gedmo" 131 | ;resources.doctrine.orm.entityManagers.default.metadataDrivers.annotationRegistry.annotationNamespaces.0.includePath = APPLICATION_PATH "/../library/vendor" 132 | resources.doctrine.orm.entityManagers.default.metadataDrivers.drivers.0.adapterClass = "Doctrine\ORM\Mapping\Driver\AnnotationDriver" 133 | resources.doctrine.orm.entityManagers.default.metadataDrivers.drivers.0.mappingNamespace = "Application\Entity" 134 | resources.doctrine.orm.entityManagers.default.metadataDrivers.drivers.0.mappingDirs[] = APPLICATION_PATH "/../library/Application/Entity" 135 | resources.doctrine.orm.entityManagers.default.metadataDrivers.drivers.0.annotationReaderClass = "Doctrine\Common\Annotations\AnnotationReader" 136 | resources.doctrine.orm.entityManagers.default.metadataDrivers.drivers.0.annotationReaderCache = default 137 | ;resources.doctrine.orm.entityManagers.default.metadataDrivers.drivers.0.annotationReaderNamespaces.App = "Application\DoctrineExtensions\ORM\Mapping" 138 | resources.doctrine.orm.entityManagers.default.secondLevelCache.enabled = TRUE 139 | resources.doctrine.orm.entityManagers.default.secondLevelCache.loggerClass = "Doctrine\ORM\Cache\Logging\StatisticsCacheLogger" 140 | 141 | ; DocumentManager configuration for "default" manager 142 | resources.doctrine.odm.documentManagers.default.documentManagerClass = "Doctrine\ODM\MongoDB\DocumentManager" 143 | resources.doctrine.odm.documentManagers.default.connectionString = "mongodb://localhost" 144 | resources.doctrine.odm.documentManagers.default.type = "MongoDB" 145 | resources.doctrine.odm.documentManagers.default.proxy.autoGenerateClasses = true 146 | resources.doctrine.odm.documentManagers.default.proxy.namespace = "DocumentProxy" 147 | resources.doctrine.odm.documentManagers.default.proxy.dir = APPLICATION_PATH "/data/doctrineDocumentProxies/Proxy" 148 | resources.doctrine.odm.documentManagers.default.hydrator.dir = APPLICATION_PATH "/data/hydrator" 149 | resources.doctrine.odm.documentManagers.default.hydrator.namespace = "Hydrators" 150 | resources.doctrine.odm.documentManagers.default.metadataDrivers.annotationRegistry.annotationFiles[] = "Doctrine/ODM/MongoDB/Mapping/Annotations/DoctrineAnnotations.php" 151 | resources.doctrine.odm.documentManagers.default.metadataDrivers.drivers.0.adapterClass = "Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver" 152 | resources.doctrine.odm.documentManagers.default.metadataDrivers.drivers.0.mappingNamespace = "Application\Document" 153 | resources.doctrine.odm.documentManagers.default.metadataDrivers.drivers.0.mappingDirs[] = APPLICATION_PATH "/../library/Application/Entity" 154 | resources.doctrine.odm.documentManagers.default.metadataDrivers.drivers.0.annotationReaderClass = "Doctrine\Common\Annotations\AnnotationReader" 155 | resources.doctrine.odm.documentManagers.default.metadataDrivers.drivers.0.annotationReaderCache = "annotationCacheODM" 156 | 157 | [staging : production] 158 | 159 | 160 | [testing : production] 161 | phpSettings.display_startup_errors = 1 162 | phpSettings.display_errors = 1 163 | 164 | 165 | [development : production] 166 | phpSettings.display_startup_errors = 1 167 | phpSettings.display_errors = 1 168 | resources.frontController.params.displayExceptions = 1 169 | -------------------------------------------------------------------------------- /library/Bisna/Doctrine/Container.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | class Container 15 | { 16 | /** 17 | * @var string Default DBAL Connection name. 18 | */ 19 | public $defaultConnection = 'default'; 20 | 21 | /** 22 | * @var string Default Cache Instance name. 23 | */ 24 | public $defaultCacheInstance = 'default'; 25 | 26 | /** 27 | * @var string Default ODM DocumentManager name. 28 | */ 29 | public $defaultDocumentManager = 'default'; 30 | 31 | /** 32 | * @var string Default ORM EntityManager name. 33 | */ 34 | public $defaultEntityManager = 'default'; 35 | 36 | /** 37 | * @var array Doctrine Context configuration. 38 | */ 39 | private $configuration = array(); 40 | 41 | /** 42 | * @var array Available DBAL Connections. 43 | */ 44 | private $connections = array(); 45 | 46 | /** 47 | * @var array Available Cache Instances. 48 | */ 49 | private $cacheInstances = array(); 50 | 51 | /** 52 | * @var array Available ODM DocumentManagers. 53 | */ 54 | private $documentManagers = array(); 55 | 56 | /** 57 | * @var array Available ORM EntityManagers. 58 | */ 59 | private $entityManagers = array(); 60 | 61 | 62 | /** 63 | * Constructor. 64 | * 65 | * @param array $config Doctrine Container configuration 66 | */ 67 | public function __construct(array $config = array()) 68 | { 69 | // Registering Class Loaders 70 | if (isset($config['classLoader'])) { 71 | $this->registerClassLoaders($config['classLoader']); 72 | } 73 | 74 | // Defining DBAL configuration 75 | $dbalConfig = $this->prepareDBALConfiguration($config); 76 | 77 | // Defining default DBAL Connection name 78 | $this->defaultConnection = $dbalConfig['defaultConnection']; 79 | 80 | // Defining Cache configuration 81 | $cacheConfig = array(); 82 | 83 | if (isset($config['cache'])) { 84 | $cacheConfig = $this->prepareCacheInstanceConfiguration($config); 85 | 86 | // Defining default Cache instance 87 | $this->defaultCacheInstance = $cacheConfig['defaultCacheInstance']; 88 | } 89 | 90 | // Defining ORM configuration 91 | $ormConfig = array(); 92 | 93 | if (isset($config['orm'])) { 94 | $ormConfig = $this->prepareORMConfiguration($config); 95 | 96 | // Defining default ORM EntityManager 97 | $this->defaultEntityManager = $ormConfig['defaultEntityManager']; 98 | } 99 | 100 | // Defining ODM configuration 101 | if (isset($config['odm'])) { 102 | $odmConfig = $this->prepareODMConfiguration($config); 103 | 104 | // Defining default ORM EntityManager 105 | $this->defaultDocumentManager = $odmConfig['defaultDocumentManager']; 106 | } 107 | 108 | // Defining Doctrine Context configuration 109 | $this->configuration = array( 110 | 'dbal' => $dbalConfig['connections'], 111 | 'cache' => $cacheConfig['instances'], 112 | 'orm' => $ormConfig['entityManagers'] 113 | ); 114 | 115 | // In case a ODM configuration is available, add it to the main configuration 116 | if (isset($odmConfig['documentManagers'])) { 117 | $this->configuration['odm'] = $odmConfig['documentManagers']; 118 | } 119 | } 120 | 121 | /** 122 | * Register Doctrine Class Loaders 123 | * 124 | * @param array $config Doctrine Class Loader configuration 125 | */ 126 | private function registerClassLoaders(array $config = array()) 127 | { 128 | $classLoaderClass = $config['loaderClass']; 129 | $classLoaderFile = $config['loaderFile']; 130 | 131 | require_once $classLoaderFile; 132 | 133 | foreach ($config['loaders'] as $loaderItem) { 134 | if (! isset($loaderItem['includePath'])) { 135 | $loaderItem['includePath'] = null; 136 | } 137 | 138 | $classLoader = new $classLoaderClass($loaderItem['namespace'], $loaderItem['includePath']); 139 | $classLoader->register(); 140 | } 141 | } 142 | 143 | /** 144 | * Prepare DBAL Connections configurations. 145 | * 146 | * @param array $config Doctrine Container configuration 147 | * 148 | * @return array 149 | */ 150 | private function prepareDBALConfiguration(array $config = array()) 151 | { 152 | $dbalConfig = $config['dbal']; 153 | $defaultConnectionName = isset($dbalConfig['defaultConnection']) 154 | ? $dbalConfig['defaultConnection'] : $this->defaultConnection; 155 | 156 | unset($dbalConfig['defaultConnection']); 157 | 158 | $defaultConnection = array( 159 | 'eventManagerClass' => 'Doctrine\Common\EventManager', 160 | 'eventSubscribers' => array(), 161 | 'configurationClass' => 'Doctrine\DBAL\Configuration', 162 | 'sqlLoggerClass' => null, 163 | 'sqlLoggerParams' => null, 164 | 'types' => array(), 165 | 'parameters' => array( 166 | 'wrapperClass' => null, 167 | 'driver' => 'pdo_mysql', 168 | 'host' => 'localhost', 169 | 'user' => 'root', 170 | 'password' => null, 171 | 'port' => null, 172 | 'driverOptions' => array() 173 | ) 174 | ); 175 | 176 | $connections = array(); 177 | 178 | if (isset($dbalConfig['connections'])) { 179 | $configConnections = $dbalConfig['connections']; 180 | 181 | foreach ($configConnections as $name => $connection) { 182 | $name = isset($connection['id']) ? $connection['id'] : $name; 183 | $connections[$name] = array_replace_recursive($defaultConnection, $connection); 184 | } 185 | } else { 186 | $connections = array( 187 | $defaultConnectionName => array_replace_recursive($defaultConnection, $dbalConfig) 188 | ); 189 | } 190 | 191 | return array( 192 | 'defaultConnection' => $defaultConnectionName, 193 | 'connections' => $connections 194 | ); 195 | } 196 | 197 | /** 198 | * Prepare Cache Instances configurations. 199 | * 200 | * @param array $config Doctrine Container configuration 201 | * 202 | * @return array 203 | */ 204 | private function prepareCacheInstanceConfiguration(array $config = array()) 205 | { 206 | $cacheConfig = $config['cache']; 207 | $defaultCacheInstanceName = isset($cacheConfig['defaultCacheInstance']) 208 | ? $cacheConfig['defaultCacheInstance'] : $this->defaultCacheInstance; 209 | 210 | unset($cacheConfig['defaultCacheInstance']); 211 | 212 | $defaultCacheInstance = array( 213 | 'adapterClass' => 'Doctrine\Common\Cache\ArrayCache', 214 | 'namespace' => '', 215 | 'options' => array() 216 | ); 217 | 218 | $instances = array(); 219 | 220 | if (isset($cacheConfig['instances'])) { 221 | $configInstances = $cacheConfig['instances']; 222 | 223 | foreach ($configInstances as $name => $instance) { 224 | $name = isset($instance['id']) ? $instance['id'] : $name; 225 | $instances[$name] = array_replace_recursive($defaultCacheInstance, $instance); 226 | } 227 | } else { 228 | $instances = array( 229 | $defaultCacheInstanceName => array_replace_recursive($defaultCacheInstance, $cacheConfig) 230 | ); 231 | } 232 | 233 | return array( 234 | 'defaultCacheInstance' => $defaultCacheInstanceName, 235 | 'instances' => $instances 236 | ); 237 | } 238 | 239 | /** 240 | * Prepare ODM EntityManagers configurations. 241 | * 242 | * @param array $config Doctrine Container configuration 243 | * 244 | * @return array 245 | */ 246 | private function prepareODMConfiguration(array $config = array()) 247 | { 248 | $odmConfig = $config['odm']; 249 | $defaultDocumentManagerName = isset($odmConfig['defaultDocumentManager']) 250 | ? $odmConfig['defaultDocumentManager'] 251 | : $this->defaultDocumentManager; 252 | 253 | unset($odmConfig['defaultDocumentManager']); 254 | 255 | $defaultDocumentManager = array( 256 | 'documentManagerClass' => 'Doctrine\ODM\MongoDB\DocumentManager', 257 | 'configurationClass' => 'Doctrine\ODM\MongoDB\Configuration', 258 | 'documentNamespaces' => array(), 259 | 'connection' => $this->defaultConnection, 260 | 'proxy' => array( 261 | 'autoGenerateClasses' => true, 262 | 'namespace' => 'Proxy', 263 | 'dir' => APPLICATION_PATH . '/../library/Proxy' 264 | ), 265 | 'hydrator' => array( 266 | 'namespace' => 'Hydrators', 267 | 'dir' => APPLICATION_PATH . '/../cache' 268 | ), 269 | 'queryCache' => $this->defaultCacheInstance, 270 | 'resultCache' => $this->defaultCacheInstance, 271 | 'metadataCache' => $this->defaultCacheInstance, 272 | 'metadataDrivers' => array(), 273 | 'connectionString' => '' 274 | ); 275 | 276 | $documentManagers = array(); 277 | 278 | if (isset($odmConfig['documentManagers'])) { 279 | $configDocumentManagers = $odmConfig['documentManagers']; 280 | 281 | foreach ($configDocumentManagers as $name => $documentManager) { 282 | $name = isset($documentManager['id']) ? $documentManager['id'] : $name; 283 | $documentManagers[$name] = array_replace_recursive($defaultDocumentManager, $documentManager); 284 | } 285 | } else { 286 | $documentManagers = array( 287 | $this->defaultConnection => array_replace_recursive($defaultDocumentManager, $odmConfig) 288 | ); 289 | } 290 | 291 | return array( 292 | 'defaultDocumentManager' => $defaultDocumentManagerName, 293 | 'documentManagers' => $documentManagers 294 | ); 295 | } 296 | 297 | /** 298 | * Prepare ORM EntityManagers configurations. 299 | * 300 | * @param array $config Doctrine Container configuration 301 | * 302 | * @return array 303 | */ 304 | private function prepareORMConfiguration(array $config = array()) 305 | { 306 | $ormConfig = $config['orm']; 307 | $defaultEntityManagerName = isset($ormConfig['defaultEntityManager']) 308 | ? $ormConfig['defaultEntityManager'] : $this->defaultEntityManager; 309 | 310 | unset($ormConfig['defaultEntityManager']); 311 | 312 | $defaultEntityManager = array( 313 | 'entityManagerClass' => 'Doctrine\ORM\EntityManager', 314 | 'configurationClass' => 'Doctrine\ORM\Configuration', 315 | 'entityNamespaces' => array(), 316 | 'connection' => $this->defaultConnection, 317 | 'proxy' => array( 318 | 'autoGenerateClasses' => true, 319 | 'namespace' => 'Proxy', 320 | 'dir' => APPLICATION_PATH . '/../library/Proxy' 321 | ), 322 | 'queryCache' => $this->defaultCacheInstance, 323 | 'resultCache' => $this->defaultCacheInstance, 324 | 'metadataCache' => $this->defaultCacheInstance, 325 | 'secondLevelCache' => array( 326 | 'enabled' => false, 327 | 'cache' => $this->defaultCacheInstance, 328 | 'cacheFactoryClass' => 'Doctrine\ORM\Cache\DefaultCacheFactory', 329 | 'regionsConfigurationClass' => 'Doctrine\ORM\Cache\RegionsConfiguration' 330 | ), 331 | 'metadataDrivers' => array(), 332 | 'namingStrategyClass' => 'Doctrine\ORM\Mapping\DefaultNamingStrategy', 333 | 'DQLFunctions' => array( 334 | 'numeric' => array(), 335 | 'datetime' => array(), 336 | 'string' => array() 337 | ) 338 | ); 339 | 340 | $entityManagers = array(); 341 | 342 | if (isset($ormConfig['entityManagers'])) { 343 | $configEntityManagers = $ormConfig['entityManagers']; 344 | 345 | foreach ($configEntityManagers as $name => $entityManager) { 346 | $name = isset($entityManager['id']) ? $entityManager['id'] : $name; 347 | $entityManagers[$name] = array_replace_recursive($defaultEntityManager, $entityManager); 348 | } 349 | } else { 350 | $entityManagers = array( 351 | $this->defaultConnection => array_replace_recursive($defaultEntityManager, $ormConfig) 352 | ); 353 | } 354 | 355 | return array( 356 | 'defaultEntityManager' => $defaultEntityManagerName, 357 | 'entityManagers' => $entityManagers 358 | ); 359 | } 360 | 361 | /** 362 | * Retrieve DBAL Connection based on its name. If no argument is provided, 363 | * it will attempt to get the default Connection. 364 | * If DBAL Connection name could not be found, NameNotFoundException is thrown. 365 | * 366 | * @throws \Bisna\Exception\NameNotFoundException 367 | * 368 | * @param string $connName Optional DBAL Connection name 369 | * 370 | * @return \Doctrine\DBAL\Connection DBAL Connection 371 | */ 372 | public function getConnection($connName = null) 373 | { 374 | $connName = $connName ?: $this->defaultConnection; 375 | 376 | // Check if DBAL Connection has not yet been initialized 377 | if ( ! isset($this->connections[$connName])) { 378 | // Check if DBAL Connection is configured 379 | if ( ! isset($this->configuration['dbal'][$connName])) { 380 | throw new Exception\NameNotFoundException("Unable to find Doctrine DBAL Connection '{$connName}'."); 381 | } 382 | 383 | $this->connections[$connName] = $this->startDBALConnection($this->configuration['dbal'][$connName]); 384 | 385 | unset($this->configuration['dbal'][$connName]); 386 | } 387 | 388 | return $this->connections[$connName]; 389 | } 390 | 391 | /** 392 | * Retrieves a list of names for all Connections configured and/or loaded 393 | * 394 | * @return array 395 | */ 396 | public function getConnectionNames() 397 | { 398 | $configuredConnections = array_keys($this->configuration['dbal']); 399 | $loadedConnections = array_keys($this->connections); 400 | 401 | return array_merge($configuredConnections, $loadedConnections); 402 | } 403 | 404 | /** 405 | * Retrieve Cache Instance based on its name. If no argument is provided, 406 | * it will attempt to get the default Instance. 407 | * If Cache Instance name could not be found, NameNotFoundException is thrown. 408 | * 409 | * @throws \Bisna\Exception\NameNotFoundException 410 | * 411 | * @param string $cacheName Optional Cache Instance name 412 | * 413 | * @return \Doctrine\Common\Cache\Cache Cache Instance 414 | */ 415 | public function getCacheInstance($cacheName = null) 416 | { 417 | $cacheName = $cacheName ?: $this->defaultCacheInstance; 418 | 419 | // Check if Cache Instance has not yet been initialized 420 | if ( ! isset($this->cacheInstances[$cacheName])) { 421 | // Check if Cache Instance is configured 422 | if ( ! isset($this->configuration['cache'][$cacheName])) { 423 | throw new Exception\NameNotFoundException("Unable to find Doctrine Cache Instance '{$cacheName}'."); 424 | } 425 | 426 | $this->cacheInstances[$cacheName] = $this->startCacheInstance($this->configuration['cache'][$cacheName]); 427 | 428 | unset($this->configuration['cache'][$cacheName]); 429 | } 430 | 431 | return $this->cacheInstances[$cacheName]; 432 | } 433 | 434 | /** 435 | * Retrieves a list of names for all cache instances configured 436 | * 437 | * @return array 438 | */ 439 | public function getCacheInstanceNames() 440 | { 441 | $configuredInstances = array_keys($this->configuration['cache']); 442 | $loadedInstances = array_keys($this->cacheInstances); 443 | 444 | return array_merge($configuredInstances, $loadedInstances); 445 | } 446 | 447 | /** 448 | * Retrieve ODM DocumentManager based on its name. If no argument provided, 449 | * it will attempt to get the default DocumentManager. 450 | * If ODM DocumentManager name could not be found, NameNotFoundException is thrown. 451 | * 452 | * @throws \Core\Application\Exception\NameNotFoundException 453 | * @param string $dmName Optional ODM DocumentManager name 454 | * @return \Doctrine\ODM\MongoDB\DocumentManager 455 | */ 456 | public function getDocumentManager($dmName = null) 457 | { 458 | $dmName = $dmName ?: $this->defaultDocumentManager; 459 | 460 | // Check if ORM Entity Manager has not yet been initialized 461 | if ( ! isset($this->documentManagers[$dmName])) { 462 | // Check if ORM EntityManager is configured 463 | if ( ! isset($this->configuration['odm'][$dmName])) { 464 | throw new \Core\Application\Exception\NameNotFoundException("Unable to find Doctrine ODM DocumentManager '{$dmName}'."); 465 | } 466 | 467 | $this->documentManagers[$dmName] = $this->startODMDocumentManager($this->configuration['odm'][$dmName]); 468 | 469 | unset($this->configuration['odm'][$dmName]); 470 | } 471 | 472 | return $this->documentManagers[$dmName]; 473 | } 474 | 475 | /** 476 | * Retrieve ORM EntityManager based on its name. If no argument provided, 477 | * it will attempt to get the default EntityManager. 478 | * If ORM EntityManager name could not be found, NameNotFoundException is thrown. 479 | * 480 | * @throws \Bisna\Exception\NameNotFoundException 481 | * 482 | * @param string $emName Optional ORM EntityManager name 483 | * 484 | * @return \Doctrine\ORM\EntityManager ORM EntityManager 485 | */ 486 | public function getEntityManager($emName = null) 487 | { 488 | $emName = $emName ?: $this->defaultEntityManager; 489 | 490 | // Check if ORM Entity Manager has not yet been initialized 491 | if ( ! isset($this->entityManagers[$emName])) { 492 | // Check if ORM EntityManager is configured 493 | if ( ! isset($this->configuration['orm'][$emName])) { 494 | throw new Exception\NameNotFoundException("Unable to find Doctrine ORM EntityManager '{$emName}'."); 495 | } 496 | 497 | $this->entityManagers[$emName] = $this->startORMEntityManager($this->configuration['orm'][$emName]); 498 | 499 | unset($this->configuration['orm'][$emName]); 500 | } 501 | 502 | return $this->entityManagers[$emName]; 503 | } 504 | 505 | /** 506 | * Retrieves a list of names for all Entity Managers configured and/or loaded 507 | * 508 | * @return array 509 | */ 510 | public function getEntityManagerNames() 511 | { 512 | $configuredEMs = array_keys($this->configuration['orm']); 513 | $loadedEMs = array_keys($this->entityManagers); 514 | 515 | return array_merge($configuredEMs, $loadedEMs); 516 | } 517 | 518 | /** 519 | * Initialize the DBAL Connection. 520 | * 521 | * @param array $config DBAL Connection configuration. 522 | * 523 | * @return \Doctrine\DBAL\Connection 524 | */ 525 | private function startDBALConnection(array $config = array()) 526 | { 527 | $connection = \Doctrine\DBAL\DriverManager::getConnection( 528 | $config['parameters'], 529 | $this->startDBALConfiguration($config), 530 | $this->startDBALEventManager($config) 531 | ); 532 | 533 | // Type mappings 534 | if (isset($config['typeMapping'])) { 535 | foreach ($config['typeMapping'] as $dbType => $doctrineType) { 536 | $connection->getDatabasePlatform()->registerDoctrineTypeMapping($dbType, $doctrineType); 537 | } 538 | } 539 | 540 | return $connection; 541 | } 542 | 543 | /** 544 | * Initialize the DBAL Configuration. 545 | * 546 | * @param array $config DBAL Connection configuration. 547 | * 548 | * @return \Doctrine\DBAL\Configuration 549 | */ 550 | private function startDBALConfiguration(array $config = array()) 551 | { 552 | $configClass = $config['configurationClass']; 553 | $configuration = new $configClass(); 554 | 555 | // SQL Logger configuration 556 | if ( ! empty($config['sqlLoggerClass'])) { 557 | $sqlLoggerClass = $config['sqlLoggerClass']; 558 | if ( !empty($config['sqlLoggerParams']) ) { 559 | $configuration->setSQLLogger(new $sqlLoggerClass($config['sqlLoggerParams'])); 560 | } else { 561 | $configuration->setSQLLogger(new $sqlLoggerClass()); 562 | } 563 | } 564 | 565 | //DBAL Types configuration 566 | $types = $config['types']; 567 | 568 | foreach ($types as $name => $className) { 569 | if (Type::hasType($name)) { 570 | Type::overrideType($name, $className); 571 | } else { 572 | Type::addType($name, $className); 573 | } 574 | } 575 | 576 | return $configuration; 577 | } 578 | 579 | /** 580 | * Initialize the EventManager. 581 | * 582 | * @param array $config DBAL Connection configuration. 583 | * 584 | * @return \Doctrine\Common\EventManager 585 | */ 586 | private function startDBALEventManager(array $config = array()) 587 | { 588 | $eventManagerClass = $config['eventManagerClass']; 589 | $eventManager = new $eventManagerClass(); 590 | 591 | // Event Subscribers configuration 592 | foreach ($config['eventSubscribers'] as $subscriber) { 593 | if ($subscriber) { 594 | $eventManager->addEventSubscriber(new $subscriber()); 595 | } 596 | } 597 | 598 | return $eventManager; 599 | } 600 | 601 | /** 602 | * Initialize Cache Instance. 603 | * 604 | * @param array $config Cache Instance configuration. 605 | * 606 | * @return \Doctrine\Common\Cache\Cache 607 | */ 608 | private function startCacheInstance(array $config = array()) 609 | { 610 | $adapterClass = $config['adapterClass']; 611 | 612 | // FilesystemCache (extending abstract FileCache class) expects the directory as a parameter in the constructor 613 | if( $adapterClass == 'Doctrine\Common\Cache\FilesystemCache') { 614 | $directory = isset($config['options']['directory']) ? $config['options']['directory'] : '/tmp/doctrine'; 615 | $extension = isset($config['options']['extension']) ? $config['options']['extension'] : null; 616 | $adapter = new $adapterClass($directory, $extension); 617 | } else { 618 | $adapter = new $adapterClass(); 619 | } 620 | 621 | // Define namespace for cache 622 | if (isset($config['namespace']) && ! empty($config['namespace'])) { 623 | $adapter->setNamespace($config['namespace']); 624 | } 625 | 626 | if (method_exists($adapter, 'initialize')) { 627 | $adapter->initialize($config); 628 | } else if ($adapter instanceof \Doctrine\Common\Cache\CouchbaseCache) { 629 | 630 | // Couchbase configuration 631 | $hosts = isset($config['options']['hosts']) ? $config['options']['hosts'] : array('localhost'); 632 | $user = isset($config['options']['user']) ? $config['options']['user'] : ''; 633 | $password = isset($config['options']['password']) ? $config['options']['password'] : ''; 634 | $bucket = isset($config['options']['bucket']) ? $config['options']['bucket'] : 'default'; 635 | $persistent = isset($config['options']['persistent']) ? $config['options']['persistent'] : true; 636 | 637 | // Prevent stupid PHP error of missing extension (if other driver is being used) 638 | $couchbaseClassName = 'Couchbase'; 639 | $couchbase = new $couchbaseClassName($hosts, $user, $password, $bucket, $persistent); 640 | 641 | $adapter->setCouchbase($couchbase); 642 | } else if ($adapter instanceof \Doctrine\Common\Cache\MemcacheCache) { 643 | // Prevent stupid PHP error of missing extension (if other driver is being used) 644 | $memcacheClassName = 'Memcache'; 645 | $memcache = new $memcacheClassName(); 646 | 647 | // Default server configuration 648 | $defaultServer = array( 649 | 'host' => 'localhost', 650 | 'port' => 11211, 651 | 'persistent' => true, 652 | 'weight' => 1, 653 | 'timeout' => 1, 654 | 'retryInterval' => 15, 655 | 'status' => true 656 | ); 657 | 658 | if (isset($config['options']['servers'])) { 659 | foreach ($config['options']['servers'] as $server) { 660 | $server = array_replace_recursive($defaultServer, $server); 661 | 662 | $memcache->addServer( 663 | $server['host'], 664 | $server['port'], 665 | $server['persistent'], 666 | $server['weight'], 667 | $server['timeout'], 668 | $server['retryInterval'], 669 | $server['status'] 670 | ); 671 | } 672 | } 673 | 674 | $adapter->setMemcache($memcache); 675 | } else if ($adapter instanceof \Doctrine\Common\Cache\MemcachedCache) { 676 | // Prevent stupid PHP error of missing extension (if other driver is being used) 677 | $memcacheClassName = 'Memcached'; 678 | $memcache = new $memcacheClassName(); 679 | 680 | // Default server configuration 681 | $defaultServer = array( 682 | 'host' => 'localhost', 683 | 'port' => 11211, 684 | 'weight' => 1, 685 | ); 686 | 687 | if (isset($config['options']['servers'])) { 688 | foreach ($config['options']['servers'] as $server) { 689 | $server = array_replace_recursive($defaultServer, $server); 690 | 691 | $memcache->addServer( 692 | $server['host'], 693 | $server['port'], 694 | $server['weight'] 695 | ); 696 | } 697 | } 698 | 699 | $adapter->setMemcached($memcache); 700 | } else if ($adapter instanceof \Doctrine\Common\Cache\RedisCache) { 701 | // Prevent stupid PHP error of missing extension (if other driver is being used) 702 | $redisClassName = 'Redis'; 703 | $redis = new $redisClassName(); 704 | 705 | // Default server configuration 706 | $defaultServer = array( 707 | 'host' => 'localhost', 708 | 'port' => 6379, 709 | 'timeout' => 0, 710 | 'persistent' => false, 711 | 'persistentId' => null, 712 | 'prefix' => null, 713 | 'password' => null, 714 | 'database' => 0, 715 | ); 716 | 717 | $server = isset($config['options']) 718 | ? array_replace_recursive($defaultServer, $config['options']) 719 | : $defaultServer; 720 | 721 | if (isset($server['persistent']) && $server['persistent']) { 722 | $redis->pconnect( 723 | $server['host'], 724 | $server['port'], 725 | $server['timeout'], 726 | isset($server['persistentId']) ? $server['persistentId'] : null 727 | ); 728 | } else { 729 | $redis->connect( 730 | $server['host'], 731 | $server['port'], 732 | $server['timeout'] 733 | ); 734 | } 735 | 736 | if (isset($server['password'])) { 737 | $redis->auth($server['password']); 738 | } 739 | 740 | if (isset($server['prefix'])) { 741 | $redis->setOption(\Redis::OPT_PREFIX, $server['prefix']); 742 | } 743 | 744 | $redis->select($server['database']); 745 | 746 | $adapter->setRedis($redis); 747 | } 748 | 749 | return $adapter; 750 | } 751 | 752 | /** 753 | * Initialize the ODM Document Manager 754 | * 755 | * @param array $config 756 | * @return \Doctrine\ODM\MongoDB\DocumentManager 757 | */ 758 | private function startODMDocumentManager(array $config = array()) 759 | { 760 | return \Doctrine\ODM\MongoDB\DocumentManager::create( 761 | new \Doctrine\MongoDB\Connection($config['connectionString']), 762 | $this->startODMConfiguration($config) 763 | ); 764 | } 765 | 766 | /** 767 | * Initialize ORM EntityManager. 768 | * 769 | * @param array $config ORM EntityManager configuration. 770 | * 771 | * @return \Doctrine\ORM\EntityManager 772 | */ 773 | private function startORMEntityManager(array $config = array()) 774 | { 775 | if (isset($config['entityManagerClass'])) { 776 | $entityManagerClass = $config['entityManagerClass']; 777 | } else { 778 | $entityManagerClass = '\Doctrine\ORM\EntityManager'; 779 | } 780 | return $entityManagerClass::create( 781 | $this->getConnection($config['connection']), 782 | $this->startORMConfiguration($config) 783 | ); 784 | } 785 | 786 | /** 787 | * Initialize ODM Configuration. 788 | * 789 | * @param array $config ODM DocumentManager configuration. 790 | * @return \Doctrine\ODM\MongoDB\Configuration 791 | */ 792 | private function startODMConfiguration(array $config = array()) 793 | { 794 | $configClass = $config['configurationClass']; 795 | $configuration = new $configClass(); 796 | 797 | $configuration = new \Doctrine\ODM\MongoDB\Configuration(); 798 | 799 | // Entity Namespaces configuration 800 | foreach ($config['documentNamespaces'] as $alias => $namespace) { 801 | $configuration->addDocumentNamespace($alias, $namespace); 802 | } 803 | 804 | // Proxy configuration 805 | $configuration->setAutoGenerateProxyClasses( 806 | $config['proxy']['autoGenerateClasses'] === true || 807 | ! in_array($config['proxy']['autoGenerateClasses'], array("0", "false", false)) 808 | ); 809 | $configuration->setProxyNamespace($config['proxy']['namespace']); 810 | $configuration->setProxyDir($config['proxy']['dir']); 811 | 812 | $configuration->setHydratorDir($config['hydrator']['dir']); 813 | $configuration->setHydratorNamespace($config['hydrator']['namespace']); 814 | 815 | // Cache configuration 816 | $configuration->setMetadataCacheImpl($this->getCacheInstance($config['metadataCache'])); 817 | 818 | // Metadata configuration 819 | $configuration->setMetadataDriverImpl($this->startODMMetadata($config['metadataDrivers'])); 820 | 821 | if (isset($config['defaultDb'])) { 822 | $configuration->setDefaultDB($config['defaultDb']); 823 | } 824 | 825 | if (isset($config['environment'])) { 826 | $configuration->setDefaultDB($config['environment']); 827 | } 828 | 829 | return $configuration; 830 | } 831 | 832 | /** 833 | * Initialize ORM Configuration. 834 | * 835 | * @param array $config ORM EntityManager configuration. 836 | * 837 | * @return \Doctrine\ORM\Configuration 838 | */ 839 | private function startORMConfiguration(array $config = array()) 840 | { 841 | $configClass = $config['configurationClass']; 842 | $configuration = new $configClass(); 843 | 844 | $configuration = new \Doctrine\ORM\Configuration(); 845 | 846 | // Entity Namespaces configuration 847 | foreach ($config['entityNamespaces'] as $alias => $namespace) { 848 | $configuration->addEntityNamespace($alias, $namespace); 849 | } 850 | 851 | // Proxy configuration 852 | $configuration->setAutoGenerateProxyClasses( 853 | $config['proxy']['autoGenerateClasses'] === true || 854 | ! in_array($config['proxy']['autoGenerateClasses'], array("0", "false", false)) 855 | ); 856 | $configuration->setProxyNamespace($config['proxy']['namespace']); 857 | $configuration->setProxyDir($config['proxy']['dir']); 858 | 859 | // Cache configuration 860 | $configuration->setMetadataCacheImpl($this->getCacheInstance($config['metadataCache'])); 861 | $configuration->setResultCacheImpl($this->getCacheInstance($config['resultCache'])); 862 | $configuration->setQueryCacheImpl($this->getCacheInstance($config['queryCache'])); 863 | 864 | // SecondLevelCache configuration 865 | if(isset($config['secondLevelCache']) && method_exists($configuration, 'setSecondLevelCacheEnabled')) { 866 | $configuration->setSecondLevelCacheEnabled( 867 | $config['secondLevelCache']['enabled'] === true || 868 | !in_array($config['secondLevelCache']['enabled'], array("0", "false", false)) 869 | ); 870 | if ($configuration->isSecondLevelCacheEnabled()) { 871 | $regionsConfigurationClass = $config['secondLevelCache']['regionsConfigurationClass']; 872 | $factoryClass = $config['secondLevelCache']['cacheFactoryClass']; 873 | $factory = new $factoryClass(new $regionsConfigurationClass(), $this->getCacheInstance($config['secondLevelCache']['cache'])); 874 | $configuration->getSecondLevelCacheConfiguration()->setCacheFactory($factory); 875 | if (isset($config['secondLevelCache']['loggerClass'])) { 876 | $loggerClass = $config['secondLevelCache']['loggerClass']; 877 | $configuration->getSecondLevelCacheConfiguration()->setCacheLogger(new $loggerClass()); 878 | } 879 | } 880 | } 881 | 882 | // Metadata configuration 883 | $configuration->setMetadataDriverImpl($this->startORMMetadata($config['metadataDrivers'])); 884 | 885 | //Filters http://doctrine-orm.readthedocs.org/en/latest/reference/filters.html#configuration 886 | if(isset($config['filters'])){ 887 | foreach ($config['filters'] as $name => $className) { 888 | $configuration->addFilter($name, $className); 889 | } 890 | } 891 | 892 | // DQL Functions configuration 893 | $dqlFunctions = $config['DQLFunctions']; 894 | 895 | foreach ($dqlFunctions['datetime'] as $name => $className) { 896 | $configuration->addCustomDatetimeFunction($name, $className); 897 | } 898 | 899 | foreach ($dqlFunctions['numeric'] as $name => $className) { 900 | $configuration->addCustomNumericFunction($name, $className); 901 | } 902 | 903 | foreach ($dqlFunctions['string'] as $name => $className) { 904 | $configuration->addCustomStringFunction($name, $className); 905 | } 906 | 907 | // Repository Class configuration 908 | if (isset($config['defaultRepositoryClass'])) { 909 | $configuration->setDefaultRepositoryClassName($config['defaultRepositoryClass']); 910 | } 911 | 912 | // Naming strategy for ORM 913 | $configuration->setNamingStrategy(new $config['namingStrategyClass']); 914 | 915 | return $configuration; 916 | } 917 | 918 | /** 919 | * Initialize ODM Metadata drivers. 920 | * 921 | * @param array $config ODM Mapping drivers. 922 | * @return \Doctrine\ODM\MongoDB\Mapping\Driver\DriverChain 923 | */ 924 | private function startODMMetadata(array $config = array()) 925 | { 926 | $metadataDriver = new \Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain(); 927 | 928 | // Default metadata driver configuration 929 | $defaultMetadataDriver = array( 930 | 'adapterClass' => 'Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver', 931 | 'mappingNamespace' => '', 932 | 'mappingDirs' => array(), 933 | 'annotationReaderClass' => 'Doctrine\Common\Annotations\AnnotationReader', 934 | 'annotationReaderCache' => $this->defaultCacheInstance, 935 | 'annotationReaderNamespaces' => array() 936 | ); 937 | 938 | // Setup ODM AnnotationRegistry 939 | if (isset($config['annotationRegistry'])) { 940 | $this->startAnnotationRegistry($config['annotationRegistry']); 941 | } 942 | 943 | foreach ($config['drivers'] as $driver) { 944 | $driver = array_replace_recursive($defaultMetadataDriver, $driver); 945 | 946 | if (method_exists($driver['adapterClass'], 'registerAnnotationClasses')) { 947 | $driver['adapterClass']::registerAnnotationClasses(); 948 | } 949 | 950 | $reflClass = new \ReflectionClass($driver['adapterClass']); 951 | $nestedDriver = null; 952 | 953 | if ( 954 | $reflClass->getName() == 'Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver' || 955 | $reflClass->isSubclassOf('Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver') 956 | ) { 957 | $annotationReaderClass = $driver['annotationReaderClass']; 958 | $annotationReader = new $annotationReaderClass(); 959 | if (method_exists($annotationReader, 'setDefaultAnnotationNamespace')) { 960 | $annotationReader->setDefaultAnnotationNamespace('Doctrine\ODM\MongoDB\Mapping\\'); 961 | } 962 | 963 | if (method_exists($annotationReader, 'setAnnotationNamespaceAlias')) { 964 | $driver['annotationReaderNamespaces']['ODM'] = 'Doctrine\ODM\MongoDB\Mapping\\'; 965 | 966 | foreach ($driver['annotationReaderNamespaces'] as $alias => $namespace) { 967 | $annotationReader->setAnnotationNamespaceAlias($namespace, $alias); 968 | } 969 | } 970 | 971 | $indexedReader = new \Doctrine\Common\Annotations\CachedReader( 972 | new \Doctrine\Common\Annotations\IndexedReader($annotationReader), 973 | $this->getCacheInstance($driver['annotationReaderCache']) 974 | ); 975 | 976 | $nestedDriver = $reflClass->newInstance($indexedReader, $driver['mappingDirs']); 977 | } else { 978 | $nestedDriver = $reflClass->newInstance($driver['mappingDirs']); 979 | } 980 | 981 | $metadataDriver->addDriver($nestedDriver, $driver['mappingNamespace']); 982 | } 983 | 984 | if (($drivers = $metadataDriver->getDrivers()) && count($drivers) == 1) { 985 | reset($drivers); 986 | $metadataDriver = $drivers[key($drivers)]; 987 | } 988 | 989 | return $metadataDriver; 990 | } 991 | 992 | /** 993 | * Initialize ORM Metadata drivers. 994 | * 995 | * @param array $config ORM Mapping drivers. 996 | * 997 | * @return \Doctrine\ORM\Mapping\Driver\DriverChain 998 | */ 999 | private function startORMMetadata(array $config = array()) 1000 | { 1001 | $metadataDriver = new \Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain(); 1002 | 1003 | // Default metadata driver configuration 1004 | $defaultMetadataDriver = array( 1005 | 'adapterClass' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver', 1006 | 'mappingNamespace' => '', 1007 | 'mappingDirs' => array(), 1008 | 'annotationReaderClass' => 'Doctrine\Common\Annotations\AnnotationReader', 1009 | 'annotationReaderCache' => $this->defaultCacheInstance, 1010 | 'annotationReaderNamespaces' => array() 1011 | ); 1012 | 1013 | 1014 | // Setup AnnotationRegistry 1015 | if (isset($config['annotationRegistry'])) { 1016 | $this->startAnnotationRegistry($config['annotationRegistry']); 1017 | } 1018 | 1019 | foreach ($config['drivers'] as $driver) { 1020 | $driver = array_replace_recursive($defaultMetadataDriver, $driver); 1021 | 1022 | $reflClass = new \ReflectionClass($driver['adapterClass']); 1023 | $nestedDriver = null; 1024 | 1025 | if ( 1026 | $reflClass->getName() == 'Doctrine\ORM\Mapping\Driver\AnnotationDriver' || 1027 | $reflClass->isSubclassOf('Doctrine\ORM\Mapping\Driver\AnnotationDriver') 1028 | ) { 1029 | $annotationReaderClass = $driver['annotationReaderClass']; 1030 | $annotationReader = new $annotationReaderClass(); 1031 | 1032 | // For Doctrine >= 2.2 1033 | if (method_exists($annotationReader, 'addNamespace')) { 1034 | $annotationReader->addNamespace('Doctrine\ORM\Mapping'); 1035 | } 1036 | 1037 | if (method_exists($annotationReader, 'setDefaultAnnotationNamespace')) { 1038 | $annotationReader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\'); 1039 | } 1040 | 1041 | if (method_exists($annotationReader, 'setAnnotationNamespaceAlias')) { 1042 | $driver['annotationReaderNamespaces']['ORM'] = 'Doctrine\ORM\Mapping\\'; 1043 | 1044 | foreach ($driver['annotationReaderNamespaces'] as $alias => $namespace) { 1045 | $annotationReader->setAnnotationNamespaceAlias($namespace, $alias); 1046 | } 1047 | } 1048 | 1049 | $indexedReader = new \Doctrine\Common\Annotations\CachedReader( 1050 | new \Doctrine\Common\Annotations\IndexedReader($annotationReader), 1051 | $this->getCacheInstance($driver['annotationReaderCache']) 1052 | ); 1053 | 1054 | $nestedDriver = $reflClass->newInstance($indexedReader, $driver['mappingDirs']); 1055 | } else { 1056 | $nestedDriver = $reflClass->newInstance($driver['mappingDirs']); 1057 | } 1058 | 1059 | $metadataDriver->addDriver($nestedDriver, $driver['mappingNamespace']); 1060 | } 1061 | 1062 | if (($drivers = $metadataDriver->getDrivers()) && count($drivers) == 1) { 1063 | reset($drivers); 1064 | $metadataDriver = $drivers[key($drivers)]; 1065 | } 1066 | 1067 | return $metadataDriver; 1068 | } 1069 | 1070 | /** 1071 | * Initialize ORM Metadata Annotation Registry driver 1072 | * 1073 | * @param array $config ORM Annotation Registry configuration. 1074 | */ 1075 | private function startAnnotationRegistry($config) 1076 | { 1077 | // Load annotations from Files 1078 | if (isset($config['annotationFiles']) && is_array($config['annotationFiles'])) { 1079 | foreach($config['annotationFiles'] as $file) { 1080 | AnnotationRegistry::registerFile($file); 1081 | } 1082 | } 1083 | 1084 | // Load annotation namespaces 1085 | if (isset($config['annotationNamespaces']) && is_array($config['annotationNamespaces'])) { 1086 | foreach($config['annotationNamespaces'] as $annotationNamespace) { 1087 | AnnotationRegistry::registerAutoloadNamespace( 1088 | $annotationNamespace['namespace'] 1089 | , isset($annotationNamespace['includePath']) ? $annotationNamespace['includePath'] : null 1090 | ); 1091 | } 1092 | 1093 | } 1094 | } 1095 | } 1096 | --------------------------------------------------------------------------------