1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* YAWIK |
5
|
|
|
* |
6
|
|
|
* @filesource |
7
|
|
|
* @copyright (c) 2013 - 2018 Cross Solution (http://cross-solution.de) |
8
|
|
|
* @license MIT |
9
|
|
|
*/ |
10
|
|
|
|
11
|
|
|
namespace Core; |
12
|
|
|
|
13
|
|
|
use Core\Service\ClearCacheService; |
14
|
|
|
use Symfony\Component\Dotenv\Dotenv; |
15
|
|
|
use Zend\Config\Exception\InvalidArgumentException; |
16
|
|
|
use Zend\ModuleManager\Listener\ListenerOptions; |
17
|
|
|
use Zend\Mvc\Application as BaseApplication; |
18
|
|
|
use Zend\Stdlib\ArrayUtils; |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* Yawik Custom MVC Application |
22
|
|
|
* |
23
|
|
|
* @package Core |
24
|
|
|
* @author Anthonius Munthi <[email protected]> |
25
|
|
|
* @since 0.32 |
26
|
|
|
*/ |
27
|
|
|
class Application extends BaseApplication |
|
|
|
|
28
|
|
|
{ |
29
|
|
|
const VERSION = '0.32-dev'; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* Current yawik revision |
33
|
|
|
* @var string |
34
|
|
|
*/ |
35
|
|
|
public static $revision; |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* Current yawik environment |
39
|
|
|
* @var string |
40
|
|
|
*/ |
41
|
|
|
public static $env; |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* Current yawik config directory |
45
|
|
|
* @var string |
46
|
|
|
*/ |
47
|
|
|
private static $configDir; |
48
|
|
|
|
49
|
|
|
public static function getCompleteVersion() |
50
|
|
|
{ |
51
|
|
|
//@TODO: provide better way to handle git versioning |
52
|
|
|
//$isVendor = strpos(__FILE__, 'modules')!==false || strpos(__FILE__, 'vendor') !== false; |
53
|
|
|
//$version = getenv('TRAVIS') || $isVendor ? "undefined":exec('git describe'); |
54
|
|
|
//$branch = getenv('TRAVIS') || $isVendor ? "undefined":exec('git rev-parse --abbrev-ref HEAD', $output, $retVal); |
55
|
|
|
//static::$revision = $version.'['.$branch.']'; |
56
|
|
|
return static::VERSION; |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* Get required modules for Yawik |
61
|
|
|
* |
62
|
|
|
* @return array |
63
|
|
|
*/ |
64
|
|
View Code Duplication |
public static function getRequiredModules() |
|
|
|
|
65
|
|
|
{ |
66
|
|
|
return array( |
67
|
|
|
'Zend\ServiceManager\Di', |
68
|
|
|
'Zend\Session', |
69
|
|
|
'Zend\Router', |
70
|
|
|
'Zend\Navigation', |
71
|
|
|
'Zend\I18n', |
72
|
|
|
'Zend\Filter', |
73
|
|
|
'Zend\InputFilter', |
74
|
|
|
'Zend\Form', |
75
|
|
|
'Zend\Validator', |
76
|
|
|
'Zend\Log', |
77
|
|
|
'Zend\Mvc\Plugin\Prg', |
78
|
|
|
'Zend\Mvc\Plugin\Identity', |
79
|
|
|
'Zend\Mvc\Plugin\FlashMessenger', |
80
|
|
|
'Zend\Mvc\I18n', |
81
|
|
|
'Zend\Mvc\Console', |
82
|
|
|
'Zend\Hydrator', |
83
|
|
|
'Zend\Serializer', |
84
|
|
|
'DoctrineModule', |
85
|
|
|
'DoctrineMongoODMModule', |
86
|
|
|
); |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* Generate modules to be loaded for Yawik application |
91
|
|
|
* |
92
|
|
|
* @param array $loadModules |
93
|
|
|
* @return array |
94
|
|
|
*/ |
95
|
|
|
public static function generateModuleConfiguration($loadModules=[]) |
96
|
|
|
{ |
97
|
|
|
$modules = array_merge( |
98
|
|
|
static::getRequiredModules(), |
99
|
|
|
$loadModules, |
100
|
|
|
static::scanAdditionalModule() |
|
|
|
|
101
|
|
|
); |
102
|
|
|
return $modules; |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
/** |
106
|
|
|
* Get config directory location |
107
|
|
|
* |
108
|
|
|
* @return string Configuration directory |
109
|
|
|
*/ |
110
|
|
|
public static function getConfigDir() |
111
|
|
|
{ |
112
|
|
|
if (is_null(static::$configDir)) { |
|
|
|
|
113
|
|
|
$dir = ''; |
114
|
|
|
if (is_string($test = getenv('APP_CONFIG_DIR'))) { |
115
|
|
|
if (!is_dir($test)) { |
116
|
|
|
throw new InvalidArgumentException('Directory in environment variable APP_CONFIG_DIR is not exists.'); |
117
|
|
|
} |
118
|
|
|
$dir = realpath($test); |
119
|
|
|
} elseif (is_dir($test = getcwd().'/test/sandbox/config')) { |
120
|
|
|
// module development |
121
|
|
|
$dir = $test; |
122
|
|
|
} elseif (is_dir($test = getcwd().'/config')) { |
123
|
|
|
$dir = $test; |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
if (!is_dir($dir)) { |
127
|
|
|
throw new InvalidArgumentException('Can not determine which config directory to be used.'); |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
static::$configDir = $dir; |
|
|
|
|
131
|
|
|
} |
132
|
|
|
return static::$configDir; |
|
|
|
|
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* @inheritdoc |
137
|
|
|
*/ |
138
|
|
|
public static function init($configuration = []) |
139
|
|
|
{ |
140
|
|
View Code Duplication |
if (!version_compare(PHP_VERSION, '5.6.0', 'ge')) { |
|
|
|
|
141
|
|
|
echo sprintf('<p>Sorry, YAWIK requires at least PHP 5.6.0 to run, but this server currently provides PHP %s</p>', PHP_VERSION); |
142
|
|
|
echo '<p>Please ask your servers\' administrator to install the proper PHP version.</p>'; |
143
|
|
|
exit; |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
ini_set('display_errors', true); |
147
|
|
|
ini_set('error_reporting', E_ALL | E_STRICT); |
148
|
|
|
|
149
|
|
|
static::loadDotEnv(); |
150
|
|
|
|
151
|
|
|
$configuration = static::loadConfig($configuration); |
152
|
|
|
static::checkCache($configuration); |
|
|
|
|
153
|
|
|
return parent::init($configuration); |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
/** |
157
|
|
|
* Check current cache status |
158
|
|
|
* @param array $configuration |
159
|
|
|
*/ |
160
|
|
|
private static function checkCache(array $configuration) |
161
|
|
|
{ |
162
|
|
|
$config = $configuration['module_listener_options']; |
163
|
|
|
$options = new ListenerOptions($config); |
164
|
|
|
$cache = new ClearCacheService($options); |
165
|
|
|
$cache->checkCache(); |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
/** |
169
|
|
|
* Scan additional module in config/autoload/*.module.php files |
170
|
|
|
* return array Module lists |
171
|
|
|
*/ |
172
|
|
|
private static function scanAdditionalModule() |
173
|
|
|
{ |
174
|
|
|
$modules = []; |
175
|
|
|
$configDir = static::getConfigDir(); |
176
|
|
|
foreach (glob($configDir. '/autoload/*.module.php') as $moduleFile) { |
177
|
|
|
$addModules = require $moduleFile; |
178
|
|
|
foreach ($addModules as $addModule) { |
179
|
|
|
if (strpos($addModule, '-') === 0) { |
180
|
|
|
$remove = substr($addModule, 1); |
181
|
|
|
$modules = array_filter($modules, function ($elem) use ($remove) { |
182
|
|
|
return strcasecmp($elem, $remove); |
183
|
|
|
}); |
184
|
|
|
} else { |
185
|
|
|
if (!in_array($addModule, $modules)) { |
186
|
|
|
$modules[] = $addModule; |
187
|
|
|
} |
188
|
|
|
} |
189
|
|
|
} |
190
|
|
|
} |
191
|
|
|
return $modules; |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
/** |
195
|
|
|
* Setup php server |
196
|
|
|
* @return bool |
|
|
|
|
197
|
|
|
* @codeCoverageIgnore |
198
|
|
|
*/ |
199
|
|
|
public static function setupCliServerEnv() |
200
|
|
|
{ |
201
|
|
|
$parseUrl = parse_url(substr($_SERVER["REQUEST_URI"], 1)); |
202
|
|
|
$route = isset($parseUrl['path']) ? $parseUrl['path']:null; |
203
|
|
View Code Duplication |
if (is_file(__DIR__ . '/' . $route)) { |
|
|
|
|
204
|
|
|
if (substr($route, -4) == ".php") { |
205
|
|
|
require __DIR__ . '/' . $route; // Include requested script files |
206
|
|
|
exit; |
207
|
|
|
} |
208
|
|
|
return false; // Serve file as is |
209
|
|
|
} else { // Fallback to index.php |
210
|
|
|
$_GET["q"] = $route; // Try to emulate the behaviour of a .htaccess here. |
211
|
|
|
} |
212
|
|
|
return true; |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
/** |
216
|
|
|
* Load environment variables from .env files |
217
|
|
|
*/ |
218
|
|
|
public static function loadDotEnv() |
219
|
|
|
{ |
220
|
|
|
static $isLoaded=false; |
221
|
|
|
if ($isLoaded) { |
222
|
|
|
return; |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
$dotenv = new Dotenv(); |
226
|
|
|
$dotenv->load(getcwd().'/.env.dist'); |
227
|
|
|
if (is_file($file = getcwd().'/.env')) { |
228
|
|
|
$dotenv->load($file); |
229
|
|
|
} |
230
|
|
|
|
231
|
|
|
if (!is_string(getenv('TIMEZONE'))) { |
232
|
|
|
putenv('TIMEZONE=Europe/Berlin'); |
233
|
|
|
} |
234
|
|
|
date_default_timezone_set(getenv('TIMEZONE')); |
235
|
|
|
$isLoaded = true; |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
/** |
239
|
|
|
* Load Application configuration |
240
|
|
|
* @param array $configuration |
241
|
|
|
* @return array |
242
|
|
|
*/ |
243
|
|
|
public static function loadConfig($configuration = []) |
244
|
|
|
{ |
245
|
|
|
$configDir = static::getConfigDir(); |
246
|
|
|
if (empty($configuration)) { |
247
|
|
|
$configFile = $configDir.'/config.php'; |
248
|
|
|
if (!is_file($configFile)) { |
249
|
|
|
throw new InvalidArgumentException(sprintf( |
250
|
|
|
'Can not load config file "%s". Please be sure that this file exists and readable', |
251
|
|
|
$configFile |
252
|
|
|
)); |
253
|
|
|
} |
254
|
|
|
$configuration = include $configFile; |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
|
258
|
|
|
$isCli = php_sapi_name() === 'cli'; |
259
|
|
|
|
260
|
|
|
// load modules |
261
|
|
|
$modules = $configuration['modules']; |
262
|
|
|
$modules = static::generateModuleConfiguration($modules); |
263
|
|
|
|
264
|
|
|
$yawikConfig = $configDir.'/autoload/yawik.config.global.php'; |
265
|
|
|
$installMode = false; |
266
|
|
|
if (!$isCli && !file_exists($yawikConfig)) { |
267
|
|
|
$modules = ['Install']; |
268
|
|
|
$installMode = true; |
269
|
|
|
} elseif (in_array('Install', $modules)) { |
270
|
|
|
$modules = array_diff($modules, ['Install']); |
271
|
|
|
} |
272
|
|
|
|
273
|
|
|
static::$env = $env = getenv('APPLICATION_ENV') ?: 'production'; |
274
|
|
|
$defaults = [ |
275
|
|
|
'module_listener_options' => [ |
276
|
|
|
'module_paths' => [ |
277
|
|
|
'./module', |
278
|
|
|
'./vendor', |
279
|
|
|
'./modules' |
280
|
|
|
], |
281
|
|
|
// What configuration files should be autoloaded |
282
|
|
|
'config_glob_paths' => [ |
283
|
|
|
sprintf($configDir.'/autoload/{,*.}{global,%s,local}.php', $env) |
284
|
|
|
], |
285
|
|
|
|
286
|
|
|
// Use the $env value to determine the state of the flag |
287
|
|
|
// caching disabled during install mode |
288
|
|
|
'config_cache_enabled' => ($env == 'production'), |
289
|
|
|
|
290
|
|
|
|
291
|
|
|
// Use the $env value to determine the state of the flag |
292
|
|
|
'module_map_cache_enabled' => ($env == 'production'), |
293
|
|
|
|
294
|
|
|
'module_map_cache_key' => 'module_map', |
295
|
|
|
|
296
|
|
|
// Use the $env value to determine the state of the flag |
297
|
|
|
'check_dependencies' => ($env != 'production'), |
298
|
|
|
|
299
|
|
|
'cache_dir' => getcwd()."/var/cache", |
300
|
|
|
], |
301
|
|
|
]; |
302
|
|
|
|
303
|
|
|
$envConfig = []; |
304
|
|
|
$envConfigFile = $configDir.'/config.'.$env.'.php'; |
305
|
|
|
if (file_exists($envConfigFile)) { |
306
|
|
|
if (is_readable($envConfigFile)) { |
307
|
|
|
$envConfig = include $envConfigFile; |
308
|
|
|
} else { |
309
|
|
|
\trigger_error( |
310
|
|
|
sprintf('Environment config file "%s" is not readable.', $envConfigFile), |
311
|
|
|
E_USER_NOTICE |
312
|
|
|
); |
313
|
|
|
} |
314
|
|
|
} |
315
|
|
|
|
316
|
|
|
// configuration file always win |
317
|
|
|
$configuration = ArrayUtils::merge($defaults, $configuration); |
318
|
|
|
// environment config always win |
319
|
|
|
$configuration = ArrayUtils::merge($configuration, $envConfig); |
320
|
|
|
|
321
|
|
|
// force override modules to load only install module in installation mode |
322
|
|
|
$modules = static::generateModuleConfiguration($modules); |
323
|
|
|
$configuration['modules'] = $modules; |
324
|
|
|
|
325
|
|
|
// force disabled cache when in install mode |
326
|
|
|
if ($installMode) { |
327
|
|
|
$configuration['module_listener_options']['config_cache_enabled'] = false; |
328
|
|
|
$configuration['module_listener_options']['module_map_cache_enabled'] = false; |
329
|
|
|
} |
330
|
|
|
|
331
|
|
|
// setup docker environment |
332
|
|
|
if (getenv('DOCKER_ENV')=='yes') { |
333
|
|
|
$configuration = ArrayUtils::merge($configuration, static::getDockerEnv($configuration)); |
|
|
|
|
334
|
|
|
} |
335
|
|
|
return $configuration; |
336
|
|
|
} |
337
|
|
|
|
338
|
|
|
/** |
339
|
|
|
* Override configuration in docker environment |
340
|
|
|
* @param $configuration |
341
|
|
|
* @return array |
342
|
|
|
*/ |
343
|
|
|
private static function getDockerEnv($configuration) |
344
|
|
|
{ |
345
|
|
|
$cacheDir = $configuration['module_listener_options']['cache_dir'].'/docker'; |
346
|
|
|
$configDir = static::getConfigDir(); |
347
|
|
|
return [ |
348
|
|
|
'module_listener_options' => [ |
349
|
|
|
'cache_dir' => $cacheDir, |
350
|
|
|
'config_glob_paths' => [ |
351
|
|
|
$configDir.'/autoload/*.docker.php', |
352
|
|
|
] |
353
|
|
|
] |
354
|
|
|
]; |
355
|
|
|
} |
356
|
|
|
} |
357
|
|
|
|
This check examines a number of code elements and verifies that they conform to the given naming conventions.
You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.