Completed
Push — master ( 64feaf...8ef41a )
by Joschi
06:56
created

App::getConfig()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4.0961

Importance

Changes 0
Metric Value
dl 0
loc 15
ccs 9
cts 11
cp 0.8182
rs 9.2
c 0
b 0
f 0
cc 4
eloc 10
nc 4
nop 1
crap 4.0961
1
<?php
2
3
/**
4
 * Toggl Dashboard
5
 *
6
 * @category    Tollwerk
7
 * @package     Tollwerk\Admin
8
 * @subpackage  Tollwerk\Admin\Ports
9
 * @author      Joschi Kuphal <[email protected]> / @jkphl
10
 * @copyright   Copyright © 2016 Joschi Kuphal <[email protected]> / @jkphl
11
 * @license     http://opensource.org/licenses/MIT The MIT License (MIT)
12
 */
13
14
/***********************************************************************************
15
 *  The MIT License (MIT)
16
 *
17
 *  Copyright © 2016 Joschi Kuphal <[email protected]> / @jkphl
18
 *
19
 *  Permission is hereby granted, free of charge, to any person obtaining a copy of
20
 *  this software and associated documentation files (the "Software"), to deal in
21
 *  the Software without restriction, including without limitation the rights to
22
 *  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
23
 *  the Software, and to permit persons to whom the Software is furnished to do so,
24
 *  subject to the following conditions:
25
 *
26
 *  The above copyright notice and this permission notice shall be included in all
27
 *  copies or substantial portions of the Software.
28
 *
29
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
31
 *  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
32
 *  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
33
 *  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
34
 *  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35
 ***********************************************************************************/
36
37
namespace Tollwerk\Admin\Infrastructure;
38
39
use Doctrine\DBAL\Types\Type;
40
use Doctrine\ORM\EntityManager;
41
use Doctrine\ORM\Tools\Setup;
42
use Psr\Log\LogLevel;
43
use Symfony\Component\Yaml\Yaml;
44
use Tollwerk\Admin\Application\Contract\PersistenceAdapterFactoryInterface;
45
use Tollwerk\Admin\Application\Contract\PersistenceServiceInterface;
46
use Tollwerk\Admin\Application\Contract\ServiceServiceInterface;
47
use Tollwerk\Admin\Application\Contract\StorageAdapterStrategyInterface;
48
use Tollwerk\Admin\Application\Service\AccountService;
49
use Tollwerk\Admin\Application\Service\DomainService;
50
use Tollwerk\Admin\Application\Service\VirtualHostService;
51
use Tollwerk\Admin\Infrastructure\Doctrine\EnumVhosttypeType;
52
use Tollwerk\Admin\Infrastructure\Factory\PersistenceAdapterFactory;
53
use Tollwerk\Admin\Infrastructure\Service\PersistenceService;
54
use Tollwerk\Admin\Infrastructure\Service\ServiceService;
55
use Tollwerk\Admin\Infrastructure\Strategy\DoctrineStorageAdapterStrategy;
56
57
/**
58
 * App
59
 *
60
 * @package Tollwerk\Admin
61
 * @subpackage Tollwerk\Admin\Ports
62
 */
63
class App
64
{
65
    /**
66
     * Configuration
67
     *
68
     * @var array
69
     */
70
    protected static $config;
71
    /**
72
     * Root directory
73
     *
74
     * @var string
75
     */
76
    protected static $rootDirectory;
77
    /**
78
     * Entity manager
79
     *
80
     * @var EntityManager
81
     */
82
    protected static $entityManager;
83
    /**
84
     * Developer mode
85
     *
86
     * @var boolean
87
     */
88
    protected static $devMode;
89
    /**
90
     * Account service
91
     *
92
     * @var AccountService
93
     */
94
    protected static $accountService = null;
95
    /**
96
     * Virtual host service
97
     *
98
     * @var VirtualHostService
99
     */
100
    protected static $vhostService = null;
101
    /**
102
     * Domain service
103
     *
104
     * @var DomainService
105
     */
106
    protected static $domainService = null;
107
    /**
108
     * Active Storage adapter
109
     *
110
     * @var StorageAdapterStrategyInterface
111
     */
112
    protected static $storageAdapter;
113
    /**
114
     * Persistence adapter factory
115
     *
116
     * @var PersistenceAdapterFactoryInterface
117
     */
118
    protected static $persistenceAdapterFactory;
119
    /**
120
     * Persistence service
121
     *
122
     * @var PersistenceServiceInterface
123
     */
124
    protected static $persistenceService;
125
    /**
126
     * Service service
127
     *
128
     * @var ServiceServiceInterface
129
     */
130
    protected static $serviceService;
131
    /**
132
     * Application level messages
133
     *
134
     * @var array
135
     */
136
    protected static $messages = [];
137
    /**
138
     * App domain
139
     *
140
     * @var string
141
     */
142
    const DOMAIN = 'admin';
143
144
    /**
145
     * Bootstrap
146
     *
147
     * @see https://github.com/toggl/toggl_api_docs/blob/master/reports.md
148
     * @see http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/configuration.html
149
     *
150
     * @param bool $devMode Developer mode
151
     */
152
    public static function bootstrap($devMode = false)
153
    {
154
        self::$devMode = !!$devMode;
155
        self::$rootDirectory = dirname(dirname(dirname(__DIR__))).DIRECTORY_SEPARATOR;
156
157
        // Initialize the configuration
158
        $config = file_get_contents(self::$rootDirectory.'config'.DIRECTORY_SEPARATOR.'config.yml');
159
        self::$config = Yaml::parse($config);
160
161
        // Initialize doctrine
162
        self::initializeDoctrine();
163
164
        // Register the Doctrine storage adapter and persistence adapter factory
165
        self::$storageAdapter = new DoctrineStorageAdapterStrategy();
166
        self::$persistenceAdapterFactory = new PersistenceAdapterFactory();
167
        self::$serviceService = new ServiceService();
168
        self::$persistenceService = new PersistenceService(self::$persistenceAdapterFactory, self::$serviceService);
169
    }
170
171
    /**
172
     * Initialize Doctrine
173
     */
174
    protected static function initializeDoctrine()
175
    {
176
        // If the Doctrine parameters don't exist
177
        if (empty(self::$config['doctrine'])
178
            || !is_array(self::$config['doctrine'])
179
            || empty(self::$config['doctrine']['dbparams'])
180
        ) {
181
            throw new \InvalidArgumentException('Invalid Doctrine database parameters', 1466175889);
182
        }
183
184
        $modelPaths = [
185
            self::$rootDirectory.'src'.DIRECTORY_SEPARATOR.'Admin'
186
            .DIRECTORY_SEPARATOR.'Infrastructure'.DIRECTORY_SEPARATOR.'Model'
187
        ];
188
        $dbParams = self::$config['doctrine']['dbparams'];
189
        $config = Setup::createAnnotationMetadataConfiguration($modelPaths, self::$devMode);
190
191
        self::$entityManager = EntityManager::create($dbParams, $config);
192
        $platform = self::$entityManager->getConnection()->getDatabasePlatform();
193
        $platform->registerDoctrineTypeMapping('enum', 'string');
194
195
        // Register the virtual host type declaration
196
        Type::addType(EnumVhosttypeType::ENUM_TYPE, EnumVhosttypeType::class);
197
198
        // Set the locale
199
        $locale = self::getConfig('general.locale');
200
        putenv('LC_ALL='.$locale);
201
        setlocale(LC_ALL, $locale);
202
203
        \bindtextdomain(self::DOMAIN, self::$rootDirectory.'src'.DIRECTORY_SEPARATOR.'Admin'
204
            .DIRECTORY_SEPARATOR.'Infrastructure'.DIRECTORY_SEPARATOR.'Lang');
205
        \bind_textdomain_codeset(self::DOMAIN, 'UTF-8');
206
        \textdomain(self::DOMAIN);
207
    }
208
209
    /**
210
     * Return the entity manager
211
     *
212
     * @return EntityManager
213
     */
214
    public static function getEntityManager()
215
    {
216
        return self::$entityManager;
217
    }
218
219
    /**
220
     * Get a configuration value
221
     *
222
     * @param null $key Optional: config value key
223
     * @return mixed Configuration value(s)
224
     */
225 3
    public static function getConfig($key = null)
226
    {
227 3
        if ($key === null) {
228
            return self::$config;
229
        }
230 3
        $keyParts = explode('.', $key);
231 3
        $config =& self::$config;
232 3
        foreach ($keyParts as $keyPart) {
233 3
            if (!array_key_exists($keyPart, $config)) {
234
                throw new \InvalidArgumentException(sprintf('Invalid config key "%s"', $key), 1466179561);
235
            }
236 3
            $config =& $config[$keyPart];
237 3
        }
238 3
        return $config;
239
    }
240
241
    /**
242
     * Return the contents of a particular template
243
     *
244
     * @param string $template Template name
245
     * @param bool $useDefault Use a default template
246
     * @return string template contents
247
     */
248
    public static function getTemplate($template, $useDefault = false)
249
    {
250
        $templateFile = self::$rootDirectory;
251
        $templateFile .= $useDefault ? 'config' :
252
            'src'.DIRECTORY_SEPARATOR.'Admin'.DIRECTORY_SEPARATOR.'Infrastructure'.DIRECTORY_SEPARATOR.'Templates';
253
        $templateFile .= DIRECTORY_SEPARATOR.$template;
254
        if (!file_exists($templateFile)) {
255
            throw new \RuntimeException(
256
                sprintf('Unknown '.($useDefault ? 'default ' : '').'template "%s"', $template),
257
                1475503926
258
            );
259
        }
260
        return file_get_contents($templateFile);
261
    }
262
263
    /**
264
     * Return the account service
265
     *
266
     * @return AccountService Account service
267
     */
268
    public static function getAccountService()
269
    {
270
        if (self::$accountService === null) {
271
            self::$accountService = new AccountService(self::$storageAdapter, self::$persistenceService);
272
        }
273
274
        return self::$accountService;
275
    }
276
277
    /**
278
     * Return the virtual host service
279
     *
280
     * @return VirtualHostService Virtual host service
281
     */
282
    public static function getVirtualHostService()
283
    {
284
        if (self::$vhostService === null) {
285
            self::$vhostService = new VirtualHostService(self::$storageAdapter, self::$persistenceService);
286
        }
287
288
        return self::$vhostService;
289
    }
290
291
    /**
292
     * Return the domain service
293
     *
294
     * @return DomainService Domain service
295
     */
296
    public static function getDomainService()
297
    {
298
        if (self::$domainService === null) {
299
            self::$domainService = new DomainService(self::$storageAdapter, self::$persistenceService);
300
        }
301
302
        return self::$domainService;
303
    }
304
305
    /**
306
     * Return the shell service service
307
     *
308
     * @return ServiceServiceInterface Service service
309
     */
310
    public static function getServiceService()
311
    {
312
        return self::$serviceService;
313
    }
314
315
    /**
316
     * Add an application level message
317
     *
318
     * @param string $message Message
319
     * @param string $level Log level
320
     */
321
    public static function addMessage($message, $level = LogLevel::INFO)
322
    {
323
        $message = trim($message);
324
        if (strlen($message)) {
325
            self::$messages[] = [$message, $level];
326
        }
327
    }
328
329
    /**
330
     * Return all application level messages
331
     *
332
     * @return array Messages
333
     */
334
    public static function getMessages()
335
    {
336
        return self::$messages;
337
    }
338
}
339