1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Modules module |
5
|
|
|
* |
6
|
|
|
* @author Alexey Krupskiy <[email protected]> |
7
|
|
|
* @link http://inji.ru/ |
8
|
|
|
* @copyright 2015 Alexey Krupskiy |
9
|
|
|
* @license https://github.com/injitools/cms-Inji/blob/master/LICENSE |
10
|
|
|
*/ |
11
|
|
|
class Modules extends Module { |
12
|
|
|
|
13
|
|
|
public function createBlankModule($name, $codeName) { |
14
|
|
|
$codeName = ucfirst($codeName); |
15
|
|
|
Tools::createDir(App::$primary->path . '/modules/' . $codeName); |
|
|
|
|
16
|
|
|
ob_start(); |
17
|
|
|
include $this->path . '/tpls/BlankModule.php'; |
18
|
|
|
$moduleCode = ob_get_contents(); |
19
|
|
|
ob_end_clean(); |
20
|
|
|
file_put_contents(App::$primary->path . '/modules/' . $codeName . '/' . $codeName . '.php', $moduleCode); |
21
|
|
|
file_put_contents(App::$primary->path . '/modules/' . $codeName . '/info.php', "<?php\nreturn " . CodeGenerator::genArray(['name' => $name])); |
|
|
|
|
22
|
|
|
file_put_contents(App::$primary->path . '/modules/' . $codeName . '/generatorHash.php', "<?php\nreturn " . CodeGenerator::genArray([$codeName . '.php' => md5($moduleCode)])); |
23
|
|
|
} |
24
|
|
|
|
25
|
|
|
public function parseColsForModel($cols = []) { |
26
|
|
|
$modelCols = [ 'labels' => [], 'cols' => [], 'relations' => []]; |
27
|
|
|
foreach ($cols as $col) { |
28
|
|
|
$modelCols['labels'][$col['code']] = $col['label']; |
29
|
|
|
$colType = !empty($col['type']['primary']) ? $col['type']['primary'] : $col['type']; |
30
|
|
|
switch ($colType) { |
31
|
|
|
case 'relation': |
32
|
|
|
$relationName = Tools::randomString(); |
33
|
|
|
$modelCols['cols'][$col['code']] = ['type' => 'select', 'source' => 'relation', 'relation' => $relationName, 'showCol' => 'name']; |
34
|
|
|
$modelCols['relations'][$relationName] = [ |
35
|
|
|
'model' => $col['type']['aditional'], |
36
|
|
|
'col' => $col['code'] |
37
|
|
|
]; |
38
|
|
|
break; |
39
|
|
|
default: |
40
|
|
|
$modelCols['cols'][$col['code']] = ['type' => $colType]; |
41
|
|
|
} |
42
|
|
|
} |
43
|
|
|
return $modelCols; |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
public function parseColsForTable($cols, $colPrefix, $tableName) { |
47
|
|
|
|
48
|
|
|
$colsExist = App::$cur->db->getTableCols($tableName); |
49
|
|
|
$tableCols = []; |
50
|
|
|
if (empty($colsExist[$colPrefix . 'id'])) { |
51
|
|
|
$tableCols[$colPrefix . 'id'] = 'pk'; |
52
|
|
|
} |
53
|
|
|
foreach ($cols as $col) { |
54
|
|
|
if (!empty($colsExist[$colPrefix . $col['code']])) { |
55
|
|
|
continue; |
56
|
|
|
} |
57
|
|
|
$colType = !empty($col['type']['primary']) ? $col['type']['primary'] : $col['type']; |
58
|
|
|
switch ($colType) { |
59
|
|
|
case 'image': |
60
|
|
|
case 'number': |
61
|
|
|
case 'relation': |
62
|
|
|
$tableCols[$colPrefix . $col['code']] = 'int(11) NOT NULL'; |
63
|
|
|
break; |
64
|
|
|
case 'decimal': |
65
|
|
|
$tableCols[$colPrefix . $col['code']] = 'decimal(11,2) NOT NULL'; |
66
|
|
|
break; |
67
|
|
|
case 'dateTime': |
68
|
|
|
$tableCols[$colPrefix . $col['code']] = 'timestamp NOT NULL'; |
69
|
|
|
break; |
70
|
|
|
case 'currentDateTime': |
71
|
|
|
$tableCols[$colPrefix . $col['code']] = 'timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP'; |
72
|
|
|
break; |
73
|
|
|
case 'text': |
74
|
|
|
$tableCols[$colPrefix . $col['code']] = 'varchar(255) NOT NULL'; |
75
|
|
|
break; |
76
|
|
|
case 'textarea': |
77
|
|
|
default: |
78
|
|
|
$tableCols[$colPrefix . $col['code']] = 'text NOT NULL'; |
79
|
|
|
break; |
80
|
|
|
} |
81
|
|
|
} |
82
|
|
|
return $tableCols; |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
public function generateModel($module, $name, $codeName, $options) { |
86
|
|
|
$codeName = ucfirst($codeName); |
87
|
|
|
$class = new CodeGenerator\ClassGenerator(); |
|
|
|
|
88
|
|
|
$class->name = $codeName; |
89
|
|
|
$class->extends = '\Model'; |
90
|
|
|
$modelCols = $this->parseColsForModel(); |
91
|
|
|
if (!empty($options['cols'])) { |
92
|
|
|
$modelCols = $this->parseColsForModel($options['cols']); |
93
|
|
|
$tableName = strtolower($module) . '_' . strtolower($codeName); |
94
|
|
|
$tableCols = $this->parseColsForTable($options['cols'], strtolower($codeName) . '_', $tableName); |
95
|
|
|
if (App::$cur->db->tableExist($tableName)) { |
96
|
|
|
foreach ($tableCols as $colKey => $params) { |
97
|
|
|
App::$cur->db->add_col($tableName, $colKey, $params); |
98
|
|
|
} |
99
|
|
|
} else { |
100
|
|
|
App::$cur->db->createTable($tableName, $tableCols); |
101
|
|
|
} |
102
|
|
|
} |
103
|
|
|
$class->addProperty('objectName', $name, true); |
104
|
|
|
$class->addProperty('cols', $modelCols['cols'], true); |
105
|
|
|
$class->addProperty('labels', $modelCols['labels'], true); |
106
|
|
|
$class->addMethod('relations', 'return ' . CodeGenerator::genArray($modelCols['relations']), [], true); |
107
|
|
|
$modelCode = "<?php \n\nnamespace {$module};\n\n" . $class->generate(); |
108
|
|
|
|
109
|
|
|
$modulePath = Module::getModulePath($module); |
110
|
|
|
Tools::createDir($modulePath . '/models'); |
111
|
|
|
file_put_contents($modulePath . '/models/' . $codeName . '.php', $modelCode); |
112
|
|
|
$config = Config::custom($modulePath . '/generatorHash.php'); |
113
|
|
|
$config['models/' . $codeName . '.php'] = md5($modelCode); |
114
|
|
|
Config::save($modulePath . '/generatorHash.php', $config); |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
public function install($module, $params = []) { |
118
|
|
|
$installed = Module::getInstalled(App::$primary); |
119
|
|
|
if (in_array($module, $installed)) { |
120
|
|
|
return true; |
121
|
|
|
} |
122
|
|
|
$info = Module::getInfo($module); |
123
|
|
|
if (!empty($info['requires'])) { |
124
|
|
|
foreach ($info['requires'] as $requireModuleName) { |
125
|
|
|
$this->install($requireModuleName); |
126
|
|
|
} |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
$config = Config::app(); |
130
|
|
|
|
131
|
|
|
$location = 'modules'; |
132
|
|
|
|
133
|
|
|
$config[$location][] = $module; |
134
|
|
|
if (!empty($info['autoload'])) { |
135
|
|
|
$config['autoloadModules'][] = $module; |
136
|
|
|
} |
137
|
|
|
if (!empty($info['menu'])) { |
138
|
|
|
foreach ($info['menu'] as $appType => $items) { |
139
|
|
|
$this->addInMenu($items, $appType); |
140
|
|
|
} |
141
|
|
|
} |
142
|
|
|
Config::save('app', $config, null, App::$primary); |
143
|
|
|
|
144
|
|
|
$paths = Module::getModulePaths($module); |
145
|
|
|
foreach ($paths as $path) { |
146
|
|
|
if (file_exists($path . '/install_script.php')) { |
147
|
|
|
$installFunction = include $path . '/install_script.php'; |
148
|
|
|
$installFunction(1, $params); |
149
|
|
|
} |
150
|
|
|
} |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
public function unInstall($module, $params = []) { |
154
|
|
|
$installed = Module::getInstalled(App::$primary); |
155
|
|
|
if (!in_array($module, $installed)) { |
156
|
|
|
return true; |
157
|
|
|
} |
158
|
|
|
$info = Module::getInfo($module); |
159
|
|
|
|
160
|
|
|
$config = Config::app(); |
161
|
|
|
|
162
|
|
|
$type = 'modules'; |
163
|
|
|
|
164
|
|
|
$path = INJI_SYSTEM_DIR . '/modules/'; |
165
|
|
|
$location = 'modules'; |
166
|
|
|
|
167
|
|
|
foreach ($config[$location] as $key => $moduleName) { |
168
|
|
|
if ($moduleName == $module) { |
169
|
|
|
unset($config[$location][$key]); |
170
|
|
|
break; |
171
|
|
|
} |
172
|
|
|
} |
173
|
|
|
if (!empty($config['autoload'])) { |
174
|
|
|
foreach ($config['autoload'] as $key => $moduleName) { |
175
|
|
|
if ($moduleName == $module) { |
176
|
|
|
unset($config['autoload'][$key]); |
177
|
|
|
break; |
178
|
|
|
} |
179
|
|
|
} |
180
|
|
|
} |
181
|
|
|
Config::save('app', $config, null, App::$primary); |
182
|
|
|
if (file_exists($path . $module . '/uninstall_script.php')) { |
183
|
|
|
$installFunction = include $path . $module . '/uninstall_script.php'; |
184
|
|
|
$installFunction(1, $params); |
185
|
|
|
} |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
public function addInMenu($items, $appType, $parent = 0) { |
189
|
|
|
foreach ($items as $item) { |
190
|
|
|
$menuItem = new \Menu\Item(); |
191
|
|
|
$menuItem->name = $item['name']; |
192
|
|
|
$menuItem->href = $item['href']; |
193
|
|
|
$menuItem->Menu_id = 1; |
194
|
|
|
$menuItem->parent_id = $parent; |
195
|
|
|
$menuItem->save(['appType' => $appType]); |
196
|
|
|
if (!empty($item['childs'])) { |
197
|
|
|
$this->addInMenu($item['childs'], $appType, $menuItem->pk()); |
198
|
|
|
} |
199
|
|
|
} |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
public function getSelectListModels($module = '') { |
203
|
|
|
$models = []; |
204
|
|
|
if ($module) { |
205
|
|
|
$modelsNames = $this->getModelsList($module); |
206
|
|
|
|
207
|
|
|
$info = Modules::getInfo($module); |
208
|
|
|
$moduleName = !empty($info['name']) ? $info['name'] : $module; |
209
|
|
|
foreach ($modelsNames as $modelName) { |
210
|
|
|
$fullModelName = $module . '\\' . $modelName; |
211
|
|
|
$models[$fullModelName] = $moduleName . ' - ' . ($fullModelName::$objectName ? $fullModelName::$objectName : $modelName); |
|
|
|
|
212
|
|
|
} |
213
|
|
|
} |
214
|
|
|
foreach (App::$primary->config['modules'] as $configModule) { |
215
|
|
|
if ($module == $configModule) { |
216
|
|
|
continue; |
217
|
|
|
} |
218
|
|
|
$modelsNames = $this->getModelsList($configModule); |
219
|
|
|
$info = Modules::getInfo($configModule); |
220
|
|
|
$moduleName = !empty($info['name']) ? $info['name'] : $configModule; |
221
|
|
|
foreach ($modelsNames as $modelName) { |
222
|
|
|
$fullModelName = $configModule . '\\' . $modelName; |
223
|
|
|
Router::loadClass($fullModelName); |
|
|
|
|
224
|
|
|
$models[$fullModelName] = $moduleName . ' - ' . ($fullModelName::$objectName ? $fullModelName::$objectName : $modelName); |
225
|
|
|
} |
226
|
|
|
} |
227
|
|
|
return $models; |
228
|
|
|
} |
229
|
|
|
|
230
|
|
|
public function getModelsList($module, $dir = '') { |
231
|
|
|
$modulePath = Module::getModulePath($module); |
232
|
|
|
$path = rtrim($modulePath . '/models/' . $dir, '/'); |
233
|
|
|
$models = []; |
234
|
|
|
if (file_exists($path)) { |
235
|
|
|
foreach (array_slice(scandir($path), 2) as $file) { |
236
|
|
|
$modelLastName = pathinfo($file, PATHINFO_FILENAME); |
237
|
|
|
if (is_dir($path . '/' . $file)) { |
238
|
|
|
$models = array_merge($models, $this->getModelsList($module, $dir . '/' . $modelLastName)); |
239
|
|
|
} |
240
|
|
|
$nameSpace = trim(preg_replace('!/' . $modelLastName . '$!', '', $dir), '/'); |
241
|
|
|
$models[] = trim(str_replace('/', '\\', $nameSpace) . '\\' . $modelLastName, '\\'); |
242
|
|
|
} |
243
|
|
|
} |
244
|
|
|
return $models; |
245
|
|
|
} |
246
|
|
|
|
247
|
|
|
public function createController($module, $controllerType) { |
248
|
|
|
$modulePath = Module::getModulePath($module); |
249
|
|
|
$path = $modulePath . '/' . $controllerType . '/' . $module . 'Controller.php'; |
250
|
|
|
$class = new CodeGenerator\ClassGenerator(); |
251
|
|
|
$class->name = $module . 'Controller'; |
252
|
|
|
$class->extends = 'Controller'; |
253
|
|
|
$controllerCode = "<?php\n\n" . $class->generate(); |
254
|
|
|
Tools::createDir(pathinfo($path, PATHINFO_DIRNAME)); |
255
|
|
|
file_put_contents($path, $controllerCode); |
256
|
|
|
$config = Config::custom($modulePath . '/generatorHash.php'); |
257
|
|
|
$config[$controllerType . '/' . $module . 'Controller.php'] = md5($controllerCode); |
258
|
|
|
Config::save($modulePath . '/generatorHash.php', $config); |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
public function addActionToController($module, $type, $controller, $url) { |
262
|
|
|
$modulePath = Module::getModulePath($module); |
263
|
|
|
$path = Modules::getModulePath($module) . '/' . $type . '/' . $controller . '.php'; |
264
|
|
|
$class = CodeGenerator::parseClass($path); |
265
|
|
|
$class->addMethod($url . 'Action'); |
266
|
|
|
$controllerCode = "<?php\n\n" . $class->generate(); |
267
|
|
|
Tools::createDir(pathinfo($path, PATHINFO_DIRNAME)); |
268
|
|
|
file_put_contents($path, $controllerCode); |
269
|
|
|
$config = Config::custom($modulePath . '/generatorHash.php'); |
270
|
|
|
$config[$type . '/' . $module . 'Controller.php'] = md5($controllerCode); |
271
|
|
|
Config::save($modulePath . '/generatorHash.php', $config); |
272
|
|
|
} |
273
|
|
|
} |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"]
, you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths