Completed
Pull Request — master (#1103)
by Tim
07:25
created

EntityManagerFactory::getApplication()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * \AppserverIo\Appserver\PersistenceContainer\Doctrine\V2\EntityManagerFactory
5
 *
6
 * NOTICE OF LICENSE
7
 *
8
 * This source file is subject to the Open Software License (OSL 3.0)
9
 * that is available through the world-wide-web at this URL:
10
 * http://opensource.org/licenses/osl-3.0.php
11
 *
12
 * PHP version 5
13
 *
14
 * @author    Tim Wagner <[email protected]>
15
 * @copyright 2015 TechDivision GmbH <[email protected]>
16
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
 * @link      https://github.com/appserver-io/appserver
18
 * @link      http://www.appserver.io
19
 */
20
21
namespace AppserverIo\Appserver\PersistenceContainer\Doctrine\V2;
22
23
use Doctrine\ORM\Configuration;
24
use Doctrine\ORM\EntityManager;
25
use Doctrine\Common\Annotations\AnnotationReader;
26
use AppserverIo\Psr\Application\ApplicationInterface;
27
use AppserverIo\Appserver\Doctrine\Utils\ConnectionUtil;
28
use AppserverIo\Appserver\PersistenceContainer\Doctrine\V2\DriverFactories\DriverKeys;
29
use AppserverIo\Appserver\PersistenceContainer\Doctrine\DoctrineEntityManagerDecorator;
30
use AppserverIo\Description\Configuration\CacheConfigurationInterface;
31
use AppserverIo\Description\Configuration\MetadataConfigurationInterface;
32
use AppserverIo\Description\Configuration\PersistenceUnitConfigurationInterface;
33
34
/**
35
 * Factory implementation for a Doctrin EntityManager instance.
36
 *
37
 * @author    Tim Wagner <[email protected]>
38
 * @copyright 2015 TechDivision GmbH <[email protected]>
39
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
40
 * @link      https://github.com/appserver-io/appserver
41
 * @link      http://www.appserver.io
42
 */
43
class EntityManagerFactory
44
{
45
46
    /**
47
     * The application instance.
48
     *
49
     * @var \AppserverIo\Psr\Application\ApplicationInterface
50
     */
51
    protected $application;
52
53
    /**
54
     * The persistence unit configuration instance.
55
     *
56
     *  @var \AppserverIo\Description\Configuration\PersistenceUnitConfigurationInterface
57
     */
58
    protected $persistenceUnitNode;
59
60
    /**
61
     *
62
     * @param \AppserverIo\Psr\Application\ApplicationInterface                            $application         The application instance
63
     * @param \AppserverIo\Description\Configuration\PersistenceUnitConfigurationInterface $persistenceUnitNode The persistence unit configuration node
64
     */
65
    public function __construct(
66
        ApplicationInterface $application,
67
        PersistenceUnitConfigurationInterface $persistenceUnitNode
68
    ) {
69
        $this->application = $application;
70
        $this->persistenceUnitNode = $persistenceUnitNode;
71
    }
72
73
    /**
74
     * Return's the application instance.
75
     *
76
     * @return \AppserverIo\Psr\Application\ApplicationInterface The application instance
77
     */
78
    protected function getApplication()
79
    {
80
        return $this->application;
81
    }
82
83
    /**
84
     * Return's the persistence unit configuration instance.
85
     *
86
     * @return \AppserverIo\Description\Configuration\PersistenceUnitConfigurationInterface The configuration instance
87
     */
88
    protected function getPersistenceUnitNode()
89
    {
90
        return $this->persistenceUnitNode;
91
    }
92
93
    /**
94
     * Factory method to create a new cache instance from the passed configuration.
95
     *
96
     * @param \AppserverIo\Description\Configuration\CacheConfigurationInterface $cacheConfiguration The cache configuration
97
     *
98
     * @return \Doctrine\Common\Cache\CacheProvider The cache instance
99
     */
100
    protected function getCacheImpl(CacheConfigurationInterface $cacheConfiguration)
101
    {
102
103
        // load the factory class
104
        $factory = $cacheConfiguration->getFactory();
105
106
        // create a cache instance
107
        $cache = $factory::get($cacheConfiguration->getParams());
108
        $cache->setNamespace(sprintf('dc2_%s_', md5($this->getPersistenceUnitNode()->getName())));
109
110
        // return the cache instance
111
        return $cache;
112
    }
113
114
    /**
115
     * Create's and return's a new Doctrine ORM configuration instance.
116
     *
117
     * @return \Doctrine\ORM\Configuration The configuration instance
118
     */
119
    protected function createConfiguration()
120
    {
121
122
        // load the persistence unit configuration
123
        $persistenceUnitNode = $this->getPersistenceUnitNode();
124
125
        // load the metadata configuration
126
        $metadataConfiguration = $persistenceUnitNode->getMetadataConfiguration();
127
128
        // prepare the setup properties
129
        $absolutePaths = $metadataConfiguration->getDirectoriesAsArray();
0 ignored issues
show
Bug introduced by
The method getDirectoriesAsArray() does not seem to exist on object<AppserverIo\Descr...ConfigurationInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
130
        $proxyDir = $metadataConfiguration->getParam(MetadataConfigurationInterface::PARAM_PROXY_DIR);
0 ignored issues
show
Bug introduced by
The method getParam() does not seem to exist on object<AppserverIo\Descr...ConfigurationInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
131
        $proxyNamespace = $metadataConfiguration->getParam(MetadataConfigurationInterface::PARAM_PROXY_NAMESPACE);
0 ignored issues
show
Bug introduced by
The method getParam() does not seem to exist on object<AppserverIo\Descr...ConfigurationInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
132
        $autoGenerateProxyClasses = $metadataConfiguration->getParam(MetadataConfigurationInterface::PARAM_AUTO_GENERATE_PROXY_CLASSES);
0 ignored issues
show
Bug introduced by
The method getParam() does not seem to exist on object<AppserverIo\Descr...ConfigurationInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
133
        $useSimpleAnnotationReader = $metadataConfiguration->getParam(MetadataConfigurationInterface::PARAM_USE_SIMPLE_ANNOTATION_READER);
0 ignored issues
show
Bug introduced by
The method getParam() does not seem to exist on object<AppserverIo\Descr...ConfigurationInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
134
135
        // load the metadata driver factory class name
136
        $metadataDriverFactory = $metadataConfiguration->getFactory();
137
138
        // initialize the params to be passed to the factory
139
        $metadataDriverParams = array(DriverKeys::USE_SIMPLE_ANNOTATION_READER => $useSimpleAnnotationReader);
140
141
        // create the Doctrine ORM configuration
142
        $configuration = new Configuration();
143
        $configuration->setMetadataDriverImpl($metadataDriverFactory::get($configuration, $absolutePaths, $metadataDriverParams));
144
145
        // initialize the metadata cache configuration
146
        $metadataCacheConfiguration = $persistenceUnitNode->getMetadataCacheConfiguration();
147
        $configuration->setMetadataCacheImpl($this->getCacheImpl($metadataCacheConfiguration));
148
149
        // initialize the query cache configuration
150
        $queryCacheConfiguration = $persistenceUnitNode->getQueryCacheConfiguration();
151
        $configuration->setQueryCacheImpl($this->getCacheImpl($queryCacheConfiguration));
0 ignored issues
show
Documentation introduced by
$queryCacheConfiguration is of type object<AppserverIo\Descr...ConfigurationInterface>, but the function expects a object<AppserverIo\Descr...ConfigurationInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
152
153
        // initialize the result cache configuration
154
        $resultCacheConfiguration = $persistenceUnitNode->getResultCacheConfiguration();
155
        $configuration->setResultCacheImpl($this->getCacheImpl($resultCacheConfiguration));
0 ignored issues
show
Documentation introduced by
$resultCacheConfiguration is of type object<AppserverIo\Descr...ConfigurationInterface>, but the function expects a object<AppserverIo\Descr...ConfigurationInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
156
157
        // proxy configuration
158
        $configuration->setProxyDir($proxyDir = $proxyDir ?: sys_get_temp_dir());
159
        $configuration->setProxyNamespace($proxyNamespace = $proxyNamespace ?: 'Doctrine\Proxy');
160
        $configuration->setAutoGenerateProxyClasses($autoGenerateProxyClasses = $autoGenerateProxyClasses ?: true);
161
162
        // repository configuration
163
        $configuration->setDefaultRepositoryClassName($persistenceUnitNode->getDefaultRepositoryClassName());
164
        $configuration->setRepositoryFactory($this->getApplication()->search($persistenceUnitNode->getRepositoryFactory()));
165
166
        // return the configuration instance
167
        return $configuration;
168
    }
169
170
    /**
171
     * Register's additional annotation registries defined in the configuration.
172
     *
173
     * @return void
174
     */
175
    protected function registerAnnotationRegistries()
176
    {
177
178
        // load the persistence unit configuration
179
        $persistenceUnitNode = $this->getPersistenceUnitNode();
180
181
        // register additional annotation libraries
182
        foreach ($persistenceUnitNode->getAnnotationRegistries() as $annotationRegistry) {
183
            // register the annotations specified by the annotation registery
184
            $annotationRegistryType = $annotationRegistry->getType();
185
            $registry = new $annotationRegistryType();
186
            $registry->register($annotationRegistry);
187
        }
188
    }
189
190
    /**
191
     * Creates a new entity manager instance based on the given configuration.
192
     *
193
     * @return \Doctrine\ORM\EntityManagerInterface The entity manager instance
194
     */
195
    public function factory()
196
    {
197
198
        // load the application and persistence unit configuration
199
        $application = $this->getApplication();
200
        $persistenceUnitNode = $this->getPersistenceUnitNode();
201
202
        // register additional annotation libraries
203
        $this->registerAnnotationRegistries();
204
205
        // create a new Doctrine ORM configuration instance
206
        $configuration = $this->createConfiguration();
207
208
        // query whether or not an initialize EM configuration is available
209
        if ($application->hasAttribute($persistenceUnitNode->getName()) === false) {
210
            // globally ignore configured annotations to ignore
211
            foreach ($persistenceUnitNode->getIgnoredAnnotations() as $ignoredAnnotation) {
212
                AnnotationReader::addGlobalIgnoredName($ignoredAnnotation->getNodeValue()->__toString());
213
            }
214
215
            // load the datasource node
216
            $datasourceNode = null;
217
            foreach ($application->getInitialContext()->getSystemConfiguration()->getDatasources() as $datasourceNode) {
218
                if ($datasourceNode->getName() === $persistenceUnitNode->getDatasource()->getName()) {
219
                    break;
220
                }
221
            }
222
223
            // throw a exception if the configured datasource is NOT available
224
            if ($datasourceNode == null) {
225
                throw new \Exception(sprintf('Can\'t find a datasource node for persistence unit %s', $persistenceUnitNode->getName()));
226
            }
227
228
            // load the database node
229
            $databaseNode = $datasourceNode->getDatabase();
230
231
            // throw an exception if the configured database is NOT available
232
            if ($databaseNode == null) {
233
                throw new \Exception(sprintf('Can\'t find database node for persistence unit %s', $persistenceUnitNode->getName()));
234
            }
235
236
            // load the driver node
237
            $driverNode = $databaseNode->getDriver();
238
239
            // throw an exception if the configured driver is NOT available
240
            if ($driverNode == null) {
241
                throw new \Exception(sprintf('Can\'t find driver node for persistence unit %s', $persistenceUnitNode->getName()));
242
            }
243
244
            // load the connection parameters
245
            $connectionParameters = ConnectionUtil::get($application)->fromDatabaseNode($databaseNode);
246
247
            // append the initialized EM configuration to the application
248
            $application->setAttribute($persistenceUnitNode->getName(), array($connectionParameters, $configuration));
249
        }
250
251
        // load the initialized EM configuration from the application
252
        list ($connectionParameters, $configuration) = $application->getAttribute($persistenceUnitNode->getName());
253
254
        // initialize and return a entity manager decorator instance
255
        return new DoctrineEntityManagerDecorator(EntityManager::create($connectionParameters, $configuration));
256
    }
257
}
258