Completed
Push — 2.0 ( dbbe01...d43752 )
by Marco
11:55
created

Database::getProxiesFolder()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 1
1
<?php namespace Comodojo\Extender\Components;
2
3
use \Comodojo\Foundation\Base\Configuration;
4
use \Comodojo\Foundation\Base\ConfigurationTrait;
5
use \Doctrine\ORM\Tools\Setup;
6
use \Doctrine\ORM\Tools\SchemaValidator;
7
use \Doctrine\ORM\EntityManager;
8
use \Doctrine\DBAL\DriverManager;
9
use \Doctrine\DBAL\Configuration as DoctrineConfiguration;
10
use \Doctrine\ORM\Query\ResultSetMappingBuilder;
11
use \Doctrine\Common\Cache\ApcCache;
12
13
/**
14
* @package     Comodojo Extender
15
* @author      Marco Giovinazzi <[email protected]>
16
* @license     MIT
17
*
18
* LICENSE:
19
*
20
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26
* THE SOFTWARE.
27
 */
28
29
class Database {
30
31
    use ConfigurationTrait;
32
33
    protected $entity_manager;
34
35
    public function __construct(Configuration $configuration) {
36
37
        $this->setConfiguration($configuration);
38
39
    }
40
41
    public function getConnection() {
42
43
        $configuration = $this->getConfiguration();
44
        $connection_params = self::getConnectionParameters($configuration);
45
        $driverConfig = new DoctrineConfiguration();
46
47
        $devmode = $configuration->get('database-devmode') === true ? true : false;
48
49
        // currently only ApcCache driver is supported
50
        if ( empty($devmode) ) {
51
52
            $cache = new ApcCache();
0 ignored issues
show
Deprecated Code introduced by
The class Doctrine\Common\Cache\ApcCache has been deprecated with message: since version 1.6, use ApcuCache instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
53
            $driverConfig->setResultCacheImpl($cache);
54
55
        }
56
57
        return DriverManager::getConnection($connection_params, $driverConfig);
58
59
    }
60
61
    public function getEntityManager() {
62
63
        if ( $this->entity_manager === null ) {
64
65
            $configuration = $this->getConfiguration();
66
67
            $base_folder = $configuration->get('base-path');
68
69
            $connection_params = self::getConnectionParameters($configuration);
70
71
            $entity_repositories = self::getEntityRepositories($configuration);
72
73
            $proxies_folder = self::getProxiesFolder($configuration);
74
75
            $devmode = $configuration->get('database-devmode') === true ? true : false;
76
77
            $metadata_mode = $configuration->get('database-metadata');
78
79
            $config_args = [
80
                $entity_repositories,
81
                $devmode,
82
                "$base_folder/$proxies_folder",
83
                null,
84
                false
85
            ];
86
87
            switch (strtoupper($metadata_mode)) {
88
89
                case 'YAML':
90
                    $db_config = Setup::createYAMLMetadataConfiguration(...$config_args);
91
                    break;
92
93
                case 'XML':
94
                    $db_config = Setup::createXMLMetadataConfiguration(...$config_args);
95
                    break;
96
97
                case 'ANNOTATIONS':
98
                default:
99
                    $db_config = Setup::createAnnotationMetadataConfiguration(...$config_args);
100
                    break;
101
            }
102
103
            if ( $devmode ) {
104
105
                $db_config->setAutoGenerateProxyClasses(true);
106
107
            } else {
108
109
                $cache = new ApcCache();
0 ignored issues
show
Deprecated Code introduced by
The class Doctrine\Common\Cache\ApcCache has been deprecated with message: since version 1.6, use ApcuCache instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
110
                $db_config->setAutoGenerateProxyClasses(false);
111
                $db_config->setQueryCacheImpl($cache);
112
                $db_config->setResultCacheImpl($cache);
113
                $db_config->setMetadataCacheImpl($cache);
114
115
            }
116
117
            $this->entity_manager = EntityManager::create($connection_params, $db_config);
118
119
        } else {
120
121
            $this->entity_manager->clear();
122
123
        }
124
125
        return $this->entity_manager;
126
127
    }
128
129
    public function setEntityManager(EntityManager $manager) {
0 ignored issues
show
Bug introduced by
You have injected the EntityManager via parameter $manager. This is generally not recommended as it might get closed and become unusable. Instead, it is recommended to inject the ManagerRegistry and retrieve the EntityManager via getManager() each time you need it.

The EntityManager might become unusable for example if a transaction is rolled back and it gets closed. Let’s assume that somewhere in your application, or in a third-party library, there is code such as the following:

function someFunction(ManagerRegistry $registry) {
    $em = $registry->getManager();
    $em->getConnection()->beginTransaction();
    try {
        // Do something.
        $em->getConnection()->commit();
    } catch (\Exception $ex) {
        $em->getConnection()->rollback();
        $em->close();

        throw $ex;
    }
}

If that code throws an exception and the EntityManager is closed. Any other code which depends on the same instance of the EntityManager during this request will fail.

On the other hand, if you instead inject the ManagerRegistry, the getManager() method guarantees that you will always get a usable manager instance.

Loading history...
130
131
        $this->entity_manager = $manager;
132
133
        return $this;
134
135
    }
136
137
    public static function init(Configuration $configuration) {
138
139
        return new Database($configuration);
140
141
    }
142
143
    public static function validate(Configuration $configuration) {
144
145
        $db = new Database($configuration);
146
147
        $em = $db->getEntityManager();
148
        $validator = new SchemaValidator($em);
149
150
        $result = [
151
            'MAPPING' => empty($validator->validateMapping()),
152
            'SYNC' => $validator->schemaInSyncWithMetadata()
153
        ];
154
        
155
        unset($validator);
156
        $em->getConnection()->close();
157
        $em->close();
158
        unset($db);
159
160
        return $result;
161
162
    }
163
164
    protected static function getConnectionParameters(Configuration $configuration) {
165
166
        $connection_params = $configuration->get('database-params');
167
        $base_folder = $configuration->get('base-path');
168
169
        if ( isset($connection_params['path']) ) $connection_params['path'] = $base_folder."/".$connection_params['path'];
170
171
        return $connection_params;
172
173
    }
174
175
    protected static function getEntityRepositories(Configuration $configuration) {
176
177
        $base_folder = $configuration->get('base-path');
178
        $repos = $configuration->get('database-repositories');
179
180
        return array_map(function($repo) use ($base_folder) {
181
            return substr($repo, 0, 1 ) === "/" ? $repo : "$base_folder/$repo";
182
        }, $repos);
183
184
    }
185
186
    protected static function getProxiesFolder(Configuration $configuration) {
187
188
        $base_folder = $configuration->get('base-path');
189
        $folder = $configuration->get('database-proxies');
190
191
        return substr($folder, 0, 1 ) === "/" ? $folder : "$base_folder/$folder";
192
193
    }
194
195
}
196