1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Koch Framework |
5
|
|
|
* Jens-André Koch © 2005 - onwards. |
6
|
|
|
* |
7
|
|
|
* This file is part of "Koch Framework". |
8
|
|
|
* |
9
|
|
|
* License: GNU/GPL v2 or any later version, see LICENSE file. |
10
|
|
|
* |
11
|
|
|
* This program is free software; you can redistribute it and/or modify |
12
|
|
|
* it under the terms of the GNU General Public License as published by |
13
|
|
|
* the Free Software Foundation; either version 2 of the License, or |
14
|
|
|
* (at your option) any later version. |
15
|
|
|
* |
16
|
|
|
* This program is distributed in the hope that it will be useful, |
17
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
18
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19
|
|
|
* GNU General Public License for more details. |
20
|
|
|
* |
21
|
|
|
* You should have received a copy of the GNU General Public License |
22
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
23
|
|
|
*/ |
24
|
|
|
|
25
|
|
|
namespace Koch\Module; |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* \Koch\Module\ManifestManager. |
29
|
|
|
*/ |
30
|
|
|
class ManifestManager |
|
|
|
|
31
|
|
|
{ |
32
|
|
|
/** |
33
|
|
|
* @var array contains the module informations |
34
|
|
|
*/ |
35
|
|
|
private static $modulesInfo = false; |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* @var array contains the system-wide module registry |
39
|
|
|
*/ |
40
|
|
|
private static $modulesRegistry = false; |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* Setter for module infos. |
44
|
|
|
* |
45
|
|
|
* @param array $module_infos_array |
46
|
|
|
*/ |
47
|
|
|
public static function setModuleInformations($module_infos_array) |
|
|
|
|
48
|
|
|
{ |
49
|
|
|
self::$modulesInfo = $module_infos_array; |
|
|
|
|
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* Setter for modules registry. |
54
|
|
|
* |
55
|
|
|
* @param array $module_registry_array |
56
|
|
|
*/ |
57
|
|
|
public static function setModuleRegistry($module_registry_array) |
|
|
|
|
58
|
|
|
{ |
59
|
|
|
self::$modulesRegistry = $module_registry_array; |
|
|
|
|
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* Reads the CMS Module Registry. |
64
|
|
|
* |
65
|
|
|
* This is the right method if you want to know if |
66
|
|
|
* a module is installed and active or deactivated. |
67
|
|
|
* |
68
|
|
|
* @return array Module Registry Array |
69
|
|
|
*/ |
70
|
|
|
public static function readModuleRegistry() |
71
|
|
|
{ |
72
|
|
|
return \Koch\Config\Config()->read(APPLICATION_PATH . 'configuration/modules.config.php'); |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* Writes the Module Registry. |
77
|
|
|
* |
78
|
|
|
* @param array $array The Module Registry Array to write. |
79
|
|
|
* |
80
|
|
|
* @return bool |
81
|
|
|
*/ |
82
|
|
|
public static function writeModuleRegistry($array) |
|
|
|
|
83
|
|
|
{ |
84
|
|
|
return \Koch\Config\Config()->write(APPLICATION_PATH . 'configuration/modules.config.php'); |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* Returns the module configuration as array. |
89
|
|
|
* |
90
|
|
|
* @param string $modulename |
91
|
|
|
* |
92
|
|
|
* @return array Module Configuration Array |
93
|
|
|
*/ |
94
|
|
|
public static function readModuleConfig($modulename) |
95
|
|
|
{ |
96
|
|
|
return \Koch\Config\Config()->readModuleConfig($modulename); |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* Checks if a modulename belongs to the core modules. |
101
|
|
|
* |
102
|
|
|
* @param string $modulename The modulename |
103
|
|
|
* |
104
|
|
|
* @return bool True if modulename is a core module, false otherwise. |
105
|
|
|
*/ |
106
|
|
|
public static function isCoreModule($modulename) |
107
|
|
|
{ |
108
|
|
|
// hardcoded map with core modules |
109
|
|
|
static $core_modules = ['account', 'categories', 'controlcenter', 'doctrine', 'menu', 'modulemanager', |
110
|
|
|
'users', 'settings', 'systeminfo', 'thememanager', 'templatemanager', ]; |
111
|
|
|
|
112
|
|
|
// @todo extract from module info file if core module or not |
113
|
|
|
return in_array($modulename, $core_modules, true); |
|
|
|
|
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* Get a list of all the module directories. |
118
|
|
|
* |
119
|
|
|
* @return array |
120
|
|
|
*/ |
121
|
|
|
public static function getModuleDirectories() |
122
|
|
|
{ |
123
|
|
|
return glob(APPLICATION_MODULES_PATH . '[a-zA-Z]*', GLOB_ONLYDIR); |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* Get a list of all the module names. |
128
|
|
|
* |
129
|
|
|
* 4 in 1 method, handling the following cases: |
130
|
|
|
* 1. array with module names |
131
|
|
|
* 2. named array with modulenames |
132
|
|
|
* 3. array with module names and paths |
133
|
|
|
* 4. named array with modulenames and paths |
134
|
|
|
* |
135
|
|
|
* @param bool $only_modulenames Toggle between only_names (true) and names+paths. |
136
|
|
|
* @param bool $named_array Toggle between named (true) and unnamed array. |
137
|
|
|
* |
138
|
|
|
* @return array( $modulename => $module_path ) |
|
|
|
|
139
|
|
|
*/ |
140
|
|
|
public static function getModuleNames($named_array = false, $only_modulenames = false) |
|
|
|
|
141
|
|
|
{ |
142
|
|
|
$modules = []; |
143
|
|
|
|
144
|
|
|
$module_dirs = self::getModuleDirectories(); |
|
|
|
|
145
|
|
|
|
146
|
|
|
foreach ($module_dirs as $module_path) { |
|
|
|
|
147
|
|
|
// strip path off |
148
|
|
|
$modulename = str_replace(APPLICATION_MODULES_PATH, '', $module_path); |
|
|
|
|
149
|
|
|
|
150
|
|
|
if ($only_modulenames === true) { |
|
|
|
|
151
|
|
|
if ($named_array === false) { |
|
|
|
|
152
|
|
|
$modules[] = $modulename; |
153
|
|
|
} else { |
154
|
|
|
$modules[] = ['name' => $modulename]; |
155
|
|
|
} |
156
|
|
|
} else { |
157
|
|
|
if ($named_array === false) { |
|
|
|
|
158
|
|
|
$modules[] = [$modulename => $module_path]; |
|
|
|
|
159
|
|
|
} else { |
160
|
|
|
$modules[] = ['name' => $modulename, 'path' => $module_path]; |
|
|
|
|
161
|
|
|
} |
162
|
|
|
} |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
return $modules; |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
/** |
169
|
|
|
* Returns all activated modules. |
170
|
|
|
* |
171
|
|
|
* @return array $activated_modules_array |
172
|
|
|
*/ |
173
|
|
|
public static function getAllActivatedModules() |
174
|
|
|
{ |
175
|
|
|
$activated_modules_array = []; |
|
|
|
|
176
|
|
|
|
177
|
|
|
$modules = self::getModuleNames(true); |
178
|
|
|
|
179
|
|
|
foreach ($modules as $module) { |
180
|
|
|
if (true === self::isModuleActive($module)) { |
181
|
|
|
$activated_modules_array[$module] = self::$modulesRegistry[$module]; |
|
|
|
|
182
|
|
|
} |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
return $activated_modules_array; |
|
|
|
|
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
/** |
189
|
|
|
* Checks if a module is active or deactived. |
190
|
|
|
* |
191
|
|
|
* @param bool $module True if module activated, false otherwise. |
192
|
|
|
*/ |
193
|
|
|
public static function isModuleActive($module) |
194
|
|
|
{ |
195
|
|
|
// load module registry, if not available yet |
196
|
|
|
if (empty(self::$modulesRegistry[$module])) { |
197
|
|
|
self::$modulesRegistry = self::readModuleRegistry(); |
198
|
|
|
} |
199
|
|
|
|
200
|
|
|
// check, if the module is |
201
|
|
|
if (isset(self::$modulesRegistry[$module]['active']) and self::$modulesRegistry[$module]['active'] === true) { |
|
|
|
|
202
|
|
|
return true; |
203
|
|
|
} else { |
204
|
|
|
return false; |
205
|
|
|
} |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
/** |
209
|
|
|
* Fetches all pieces of information of a certain module. |
210
|
|
|
* |
211
|
|
|
* @param string $module |
|
|
|
|
212
|
|
|
* |
213
|
|
|
* @return array Module Informations |
214
|
|
|
*/ |
215
|
|
|
public static function getModuleInformations($module = null) |
216
|
|
|
{ |
217
|
|
|
$modulename = strtolower($module); |
218
|
|
|
|
219
|
|
|
// check if the infos of this specific module were catched before |
220
|
|
|
if (self::$modulesInfo[$modulename] !== null) { |
221
|
|
|
return self::$modulesInfo[$modulename]; |
222
|
|
|
} |
223
|
|
|
|
224
|
|
|
// fetch infos for the requested $module |
225
|
|
|
return self::loadModuleInformations($module); |
226
|
|
|
} |
227
|
|
|
|
228
|
|
|
public static function buildModuleRegistry() |
229
|
|
|
{ |
230
|
|
|
foreach ($module_directories as $module_path) { |
|
|
|
|
231
|
|
|
// strip off path info and get the modulename |
232
|
|
|
$modulename = str_replace(APPLICATION_MODULES_PATH, '', $module_path); |
|
|
|
|
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
self::writeModuleRegistry(); |
|
|
|
|
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
/** |
239
|
|
|
* Gather Module Informations from Manifest Files. |
240
|
|
|
* |
241
|
|
|
* @staticvar array $modulesinfo |
242
|
|
|
* |
243
|
|
|
* @param mixed array|string $module array with modulenames or one modulename |
244
|
|
|
* @param string $module |
|
|
|
|
245
|
|
|
* |
246
|
|
|
* @return moduleinformations (self::$modulesinfo) |
|
|
|
|
247
|
|
|
*/ |
248
|
|
|
public static function loadModuleInformations($module = null) |
249
|
|
|
{ |
250
|
|
|
// Init vars |
251
|
|
|
$module_directories = []; |
|
|
|
|
252
|
|
|
$number_of_modules = 0; |
|
|
|
|
253
|
|
|
|
254
|
|
|
/** |
255
|
|
|
* either fetch the module requested via parameter $module |
256
|
|
|
* fetch all modules. |
257
|
|
|
*/ |
258
|
|
|
if ($module === null) { |
259
|
|
|
$module_directories = self::getModuleDirectories(); |
|
|
|
|
260
|
|
|
} else { |
261
|
|
|
// cast string to array |
262
|
|
|
$module_directories[] = APPLICATION_MODULES_PATH . $module; |
|
|
|
|
263
|
|
|
} |
264
|
|
|
|
265
|
|
|
foreach ($module_directories as $modulepath) { |
|
|
|
|
266
|
|
|
/* |
267
|
|
|
* create array with pieces of information about a module |
268
|
|
|
*/ |
269
|
|
|
|
270
|
|
|
// 1) get the modulename, by stripping off the path info |
271
|
|
|
$modulename = str_replace(APPLICATION_MODULES_PATH, '', $modulepath); |
272
|
|
|
|
273
|
|
|
self::$modulesinfo[$modulename]['name'] = $modulename; |
274
|
|
|
self::$modulesinfo[$modulename]['id'] = $number_of_modules; |
|
|
|
|
275
|
|
|
self::$modulesinfo[$modulename]['path'] = $modulepath; |
276
|
|
|
self::$modulesinfo[$modulename]['core'] = self::isCoreModule($modulename); |
277
|
|
|
|
278
|
|
|
// active - based on /configuration/modules.config.php |
279
|
|
|
self::$modulesinfo[$modulename]['active'] = self::isModuleActive($modulename); |
280
|
|
|
|
281
|
|
|
// hasMenu / ModuleNavigation |
282
|
|
|
self::$modulesinfo[$modulename]['menu'] = is_file($modulepath . '/' . $modulename . '.menu.php'); |
283
|
|
|
|
284
|
|
|
// hasInfo |
285
|
|
|
$module_infofile = $modulepath . '/' . $modulename . '.info.php'; |
|
|
|
|
286
|
|
|
$config = new \Koch\Config\Config(); |
287
|
|
|
|
288
|
|
|
if (is_file($module_infofile)) { |
|
|
|
|
289
|
|
|
#\Koch\Debug\Debug::firebug($module_infofile); |
|
|
|
|
290
|
|
|
|
291
|
|
|
self::$modulesinfo[$modulename]['info'] = $config->read($module_infofile); |
|
|
|
|
292
|
|
|
} else { // create file in DEV MODE |
293
|
|
|
// if the info file for a module does not exists yet, create it |
294
|
|
|
$config->write($module_infofile); |
|
|
|
|
295
|
|
|
} |
296
|
|
|
|
297
|
|
|
// hasRoutes |
298
|
|
|
|
299
|
|
|
// hasConfig |
300
|
|
|
$config = self::readModuleConfig($modulename); |
301
|
|
|
if ($config[$modulename] !== null) { |
302
|
|
|
self::$modulesinfo[$modulename]['config'] = $config[$modulename]; |
303
|
|
|
|
304
|
|
|
// properties |
305
|
|
|
if (isset($config['properties'])) { |
306
|
|
|
self::$modulesinfo[$modulename]['settings'] = $config['properties']; |
307
|
|
|
} |
308
|
|
|
} |
309
|
|
|
/* else { |
|
|
|
|
310
|
|
|
$modules[$modulename]['config'] = $config; |
311
|
|
|
} */ |
312
|
|
|
|
313
|
|
|
// hasLanguages |
314
|
|
|
self::$modulesinfo[$modulename]['languages'] = self::getLanguageInfosForModule($modulepath); |
315
|
|
|
|
316
|
|
|
// take some stats: increase the module counter |
317
|
|
|
self::$modulesinfo['yy_summary']['counter'] = ++$number_of_modules; |
|
|
|
|
318
|
|
|
} |
319
|
|
|
|
320
|
|
|
ksort(self::$modulesinfo); |
321
|
|
|
|
322
|
|
|
#\Koch\Debug\Debug::printR(self::$modulesinfo); |
|
|
|
|
323
|
|
|
|
324
|
|
|
return self::$modulesinfo; |
325
|
|
|
} |
326
|
|
|
|
327
|
|
|
public static function getLanguageInfosForModule($modulepath) |
328
|
|
|
{ |
329
|
|
|
$lang = []; |
330
|
|
|
|
331
|
|
|
// we are looking at the languages folder for the given module path |
332
|
|
|
$moduleLangDir = $modulepath . DIRECTORY_SEPARATOR . 'languages'; |
333
|
|
|
|
334
|
|
|
// return early, if languages directory does not exist |
335
|
|
|
if (false === is_dir($moduleLangDir)) { |
336
|
|
|
return 'No language dir.'; |
337
|
|
|
} |
338
|
|
|
|
339
|
|
|
// lets recurse this directory |
340
|
|
|
$iterator = new \RecursiveIteratorIterator( |
341
|
|
|
new \RecursiveDirectoryIterator($moduleLangDir, \FilesystemIterator::UNIX_PATHS), |
342
|
|
|
\RecursiveIteratorIterator::LEAVES_ONLY |
343
|
|
|
); |
344
|
|
|
|
345
|
|
|
// some leaves found (dirs and files) |
346
|
|
|
foreach ($iterator as $file) { |
347
|
|
|
// proceed with iteration instantly, if file is not a gettext file |
348
|
|
|
if (0 === preg_match('/.(mo|po)$/', $file->getFileName())) { |
349
|
|
|
continue; |
350
|
|
|
} |
351
|
|
|
|
352
|
|
|
// fetch locale from path (en_UK, de_DE) |
353
|
|
|
if (1 === preg_match('/[a-z]{2}_[A-Z]{2}/', $file->getPathName(), $match)) { |
354
|
|
|
$locale = $match[0]; |
355
|
|
|
} |
356
|
|
|
|
357
|
|
|
// fetch file extension (mo|po) |
358
|
|
|
if (version_compare(PHP_VERSION, '5.3.6') >= 0) { |
359
|
|
|
$ext = $file->getExtension(); |
360
|
|
|
} else { // php lower then 5.3.6 |
361
|
|
|
$ext = pathinfo($file->getFilename(), PATHINFO_EXTENSION); |
362
|
|
|
} |
363
|
|
|
|
364
|
|
|
$isReadable = $file->isReadable() ? 'r' : ''; |
365
|
|
|
$isWritable = $file->isWritable() ? 'w' : ''; |
366
|
|
|
|
367
|
|
|
/* |
368
|
|
|
* Add some more pieces of information about the file |
369
|
|
|
*/ |
370
|
|
|
$lang[$locale][$ext]['pathName'] = realpath($file->getPathName()); |
|
|
|
|
371
|
|
|
$lang[$locale][$ext]['fileName'] = $file->getFileName(); |
372
|
|
|
$lang[$locale][$ext]['filePermString'] = self::filePermissions($lang[$locale][$ext]['pathName']); |
373
|
|
|
$lang[$locale][$ext]['fileReadable'] = $file->isReadable(); |
374
|
|
|
$lang[$locale][$ext]['fileWriteable'] = $file->isWritable(); |
375
|
|
|
$lang[$locale][$ext]['timestamp'] = date(DATE_FORMAT, $file->getCTime()); |
376
|
|
|
$lang[$locale][$ext]['cssClass'] = '-' . $isReadable . $isWritable; |
377
|
|
|
} |
378
|
|
|
|
379
|
|
|
/* |
380
|
|
|
* Add some more pieces of information about the locale |
381
|
|
|
*/ |
382
|
|
|
|
383
|
|
|
// if the language definitions are not already loaded, load them |
384
|
|
|
if (empty(self::$l10n_sys_locales)) { |
385
|
|
|
// fetch arrays containing locale data |
386
|
|
|
require __DIR__ . '/../Localization/Locales.php'; |
387
|
|
|
self::$l10n_sys_locales = $l10n_sys_locales; |
|
|
|
|
388
|
|
|
} |
389
|
|
|
|
390
|
|
|
foreach ($lang as $locale => $filedata) { |
391
|
|
|
// get more data about that locale from the locales array |
392
|
|
|
if (isset(self::$l10n_sys_locales[$locale]) === true) { |
393
|
|
|
$lang[$locale]['country_www'] = self::$l10n_sys_locales[$locale]['country-www']; |
394
|
|
|
$lang[$locale]['lang_native'] = self::$l10n_sys_locales[$locale]['lang-native']; |
395
|
|
|
$lang[$locale]['lang_www'] = self::$l10n_sys_locales[$locale]['lang-www']; |
396
|
|
|
$lang[$locale]['lang'] = self::$l10n_sys_locales[$locale]['lang']; |
397
|
|
|
} else { // locale not in locales array |
398
|
|
|
$lang[$locale]['country_www'] = 'unknown'; |
399
|
|
|
$lang[$locale]['lang_native'] = '<em>locale: </em>' . $locale; |
400
|
|
|
$lang[$locale]['lang_www'] = ''; |
401
|
|
|
$lang[$locale]['lang'] = $locale; |
402
|
|
|
} |
403
|
|
|
} |
404
|
|
|
|
405
|
|
|
#\Koch\Debug\Debug::printR($langinfo); |
|
|
|
|
406
|
|
|
|
407
|
|
|
return $lang; |
408
|
|
|
} |
409
|
|
|
|
410
|
|
|
/** |
411
|
|
|
* Returns file permissions as string. |
412
|
|
|
* |
413
|
|
|
* @staticvar array $permissions |
414
|
|
|
* |
415
|
|
|
* @param type $filename |
416
|
|
|
* |
417
|
|
|
* @return string File Permissions as string, e.h. "rwx", "rw-" |
418
|
|
|
*/ |
419
|
|
|
private static function filePermissions($filename) |
420
|
|
|
{ |
421
|
|
|
static $permissions = ['---', '--x', '-w-', '-wx', 'r--', 'r-x', 'rw-', 'rwx']; |
422
|
|
|
$perm_oct = substr(decoct(fileperms($filename)), 3); |
|
|
|
|
423
|
|
|
|
424
|
|
|
$string = '['; |
425
|
|
|
$string .= $permissions[(int) $perm_oct[0]] . '|'; |
|
|
|
|
426
|
|
|
$string .= $permissions[(int) $perm_oct[1]] . '|'; |
|
|
|
|
427
|
|
|
$string .= $permissions[(int) $perm_oct[2]] . ']'; |
|
|
|
|
428
|
|
|
|
429
|
|
|
return $string; |
430
|
|
|
} |
431
|
|
|
} |
432
|
|
|
|
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.