Completed
Push — master ( 6184d4...cbb068 )
by Andreas
03:15
created

connection   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 210
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 15

Test Coverage

Coverage 79.35%

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 210
ccs 73
cts 92
cp 0.7935
rs 9.1666
wmc 26
lcom 1
cbo 15

10 Methods

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