Completed
Push — master ( 9a2dca...f57b4b )
by Andreas
13:53 queued 09:34
created

connection::get_user()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author CONTENT CONTROL http://www.contentcontrol-berlin.de/
4
 * @copyright CONTENT CONTROL http://www.contentcontrol-berlin.de/
5
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License
6
 */
7
8
namespace midgard\portable\storage;
9
10
use midgard\portable\driver;
11
use midgard\portable\classgenerator;
12
use midgard\portable\api\user;
13
use midgard\portable\api\config;
14
use midgard\portable\api\error\exception;
15
use midgard\portable\storage\type\datetime;
16
use Doctrine\ORM\EntityManager;
17
use Doctrine\DBAL\Types\Type;
18
use Doctrine\Common\Cache\ClearableCache;
19
use Monolog\Logger;
20
use Monolog\Handler\StreamHandler;
21
use midgard_connection;
22
23
class connection
24
{
25
    /**
26
     * @var Logger
27
     */
28
    private static $logger;
29
30
    /**
31
     * Loglevel translation table.
32
     *
33
     * The semantics of info and notice/message are unfortunately reversed between Monolog
34
     * and Midgard, so it looks a bit confusing..
35
     *
36
     * @var array
37
     */
38
    private static $loglevels = [
39
        'error' => Logger::ERROR,
40
        'warn' => Logger::WARNING,
41
        'warning' => Logger::WARNING,
42
        'info' => Logger::NOTICE,
43
        'message' => Logger::INFO,
44
        'debug' => Logger::DEBUG
45
    ];
46
47
    /**
48
     * Flag for automatically starting up during initialize
49
     *
50
     * @var boolean
51
     */
52
    private static $autostart = true;
53
54
    /**
55
     * Initialization parameters
56
     *
57
     * @param array
58
     */
59
    private static $parameters = [];
60
61
    private $user;
62
63
    /**
64
     * @var \Doctrine\ORM\EntityManager
65
     */
66
    protected $em;
67
68
    /**
69
     * @var \midgard\portable\storage\connection
70
     */
71
    protected static $instance;
72
73 10
    public function __construct(EntityManager $em)
0 ignored issues
show
Bug introduced by
You have injected the EntityManager via parameter $em. 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...
74
    {
75 10
        $this->em = $em;
76 10
    }
77
78
    /**
79
     * @return \Doctrine\ORM\EntityManager
80
     */
81 165
    public static function get_em()
82
    {
83 165
        if (self::$instance === null) {
84
            throw new \Exception('Not initialized');
85
        }
86 165
        return self::$instance->em;
87
    }
88
89 99
    public static function get_user()
90
    {
91 99
        return self::$instance->user;
92
    }
93
94 8
    public static function set_user(user $user = null)
95
    {
96 8
        if (self::$instance === null) {
97
            throw new \Exception('Not initialized');
98
        }
99 8
        self::$instance->user = $user;
100 8
    }
101
102
    /**
103
     * Generate a new GUID
104
     *
105
     * @return string The generated GUID
106
     */
107 115
    public static function generate_guid()
108
    {
109 115
        $sql = 'SELECT ' . self::get_em()->getConnection()->getDatabasePlatform()->getGuidExpression();
110 115
        return md5(self::get_em()->getConnection()->query($sql)->fetchColumn(0));
111
    }
112
113
    /**
114
     * Invalidate ClassMetadata cache
115
     */
116
    public static function invalidate_cache()
117
    {
118
        $cache = self::get_em()->getConfiguration()->getMetadataCacheImpl();
119
        if ($cache && $cache instanceof ClearableCache) {
120
            $cache->deleteAll();
121
        }
122
    }
123
124
    /**
125
     * Toggle autostart
126
     */
127
    public static function set_autostart($autostart)
128
    {
129
        self::$autostart = $autostart;
130
    }
131
132
    /**
133
     * Initialize Midgard connection
134
     */
135 10
    public static function initialize(driver $driver, array $db_config, $dev_mode = false)
136
    {
137 10
        $vardir = $driver->get_vardir();
138
139 10
        $mgd_config = new config;
140 10
        $mgd_config->vardir = $vardir;
141 10
        $mgd_config->cachedir = $vardir . '/cache';
142 10
        $mgd_config->blobdir = $vardir . '/blobs';
143 10
        $mgd_config->sharedir = $vardir . '/schemas';
144 10
        $mgd_config->logfilename = $vardir . '/log/midgard-portable.log';
145
        // TODO: Set rest of config values from $config and $driver
146
147
        // we open the config before startup to have logfile available
148 10
        midgard_connection::get_instance()->open_config($mgd_config);
149
150 10
        self::$parameters = ['driver' => $driver, 'db_config' => $db_config, 'dev_mode' => $dev_mode];
151 10
        if (self::$autostart) {
152 10
            static::startup();
153 10
        }
154 10
    }
155
156
    public static function get_parameter($name)
157
    {
158
        if (!array_key_exists($name, self::$parameters)) {
159
            throw new \RuntimeException('Parameter "' . $name . '" is not available');
160
        }
161
        return self::$parameters[$name];
162
    }
163
164
    /**
165
     * Start the API emulation layer
166
     */
167 10
    public static function startup()
168
    {
169 10
        if (empty(self::$parameters)) {
170
            throw new \RuntimeError('Not initialized');
171
        }
172 10
        $driver = self::$parameters['driver'];
173 10
        $db_config = self::$parameters['db_config'];
174 10
        $dev_mode = self::$parameters['dev_mode'];
175 10
        $vardir = $driver->get_vardir();
176
        // generate and include entities file if its a fresh namespace
177
        // otherwise it should be included already
178 10
        if ($driver->is_fresh_namespace()) {
179 10
            $entityfile = $vardir . '/mgdschema_classes.php';
180 10
            if ($dev_mode || !file_exists($entityfile)) {
181 10
                $classgenerator = new classgenerator($driver->get_manager(), $entityfile, $dev_mode);
182 10
                $classgenerator->write($driver->get_namespace());
183 10
            }
184 10
            require $entityfile;
185 10
        }
186
187 10
        $config = \Doctrine\ORM\Tools\Setup::createConfiguration($dev_mode, $vardir . '/cache');
188 10
        $config->addFilter('softdelete', 'midgard\\portable\\storage\\filter\\softdelete');
189 10
        $config->setMetadataDriverImpl($driver);
190 10
        $config->addEntityNamespace('midgard', $driver->get_namespace());
191 10
        $config->setClassMetadataFactoryName('\\midgard\\portable\\mapping\\factory');
192
193 10
        if (!array_key_exists('charset', $db_config)) {
194 10
            $db_config['charset'] = 'utf8';
195 10
        }
196
197 10
        $em = \Doctrine\ORM\EntityManager::create($db_config, $config);
198 10
        $em->getFilters()->enable('softdelete');
199 10
        $em->getEventManager()->addEventSubscriber(new subscriber);
200
201 10
        if (!Type::hasType(datetime::TYPE)) {
202
            Type::addType(datetime::TYPE, 'midgard\portable\storage\type\datetime');
203
        }
204
205 10
        $midgard = midgard_connection::get_instance();
206 10
        $level = self::$loglevels[$midgard->get_loglevel()];
207 10
        if ($level === Logger::DEBUG) {
208
            $logger = new Logger('doctrine');
209
            $logger->pushHandler(new StreamHandler($midgard->config->logfilename, $level));
210
211
            $em->getConnection()->getConfiguration()->setSQLLogger(new sqllogger($logger));
212
        }
213
214 10
        self::$instance = new static($em);
215 10
    }
216
217
    /**
218
     * Get Logger instance
219
     *
220
     * @return Logger
221
     */
222 3
    public static function log()
223
    {
224 3
        if (self::$logger === null) {
225 1
            $midgard = midgard_connection::get_instance();
226 1
            if ($midgard->config->logfilename) {
227 1
                $logdir = dirname($midgard->config->logfilename);
228 1
                if (   !is_dir($logdir)
229 1
                    && !mkdir($logdir, 0777, true)) {
230
                    throw exception::user_data('Log directory could not be created');
231
                }
232 1
                self::$logger = new Logger('midgard-portable');
233 1
                self::$logger->pushHandler(new StreamHandler($midgard->config->logfilename, self::$loglevels[$midgard->get_loglevel()]));
234 1
            } else {
235
                throw exception::user_data('log filename not set in config');
236
            }
237 1
        }
238 3
        return self::$logger;
239
    }
240
}
241