Passed
Push — master ( d15464...d64dd2 )
by Alexey
05:25
created

Modules::createController()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 12
nc 1
nop 2
dl 0
loc 13
ccs 0
cts 13
cp 0
crap 2
rs 9.4285
c 0
b 0
f 0
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 :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a DEFAULT statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in the default statement.

switch ($expr) {
    default : //wrong
        doSomething();
        break;
}

switch ($expr) {
    default: //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
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
        $type = 'modules';
132
133
        $path = INJI_SYSTEM_DIR . '/modules/';
134
        $location = 'modules';
135
136
        $config[$location][] = $module;
137
        if (!empty($info['autoload'])) {
138
            $config['autoloadModules'][] = $module;
139
        }
140
        if (!empty($info['menu'])) {
141
            foreach ($info['menu'] as $appType => $items) {
142
                $this->addInMenu($items, $appType);
143
            }
144
        }
145
        Config::save('app', $config, null, App::$primary);
146 View Code Duplication
        if (file_exists($path . $module . '/install_script.php')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
147
            $installFunction = include $path . $module . '/install_script.php';
148
            $installFunction(1, $params);
149
        }
150
    }
151
152
    public function unInstall($module, $params = []) {
153
        $installed = Module::getInstalled(App::$primary);
154
        if (!in_array($module, $installed)) {
155
            return true;
156
        }
157
        $info = Module::getInfo($module);
158
159
        $config = Config::app();
160
161
        $type = 'modules';
162
163
        $path = INJI_SYSTEM_DIR . '/modules/';
164
        $location = 'modules';
165
166
        foreach ($config[$location] as $key => $moduleName) {
167
            if ($moduleName == $module) {
168
                unset($config[$location][$key]);
169
                break;
170
            }
171
        }
172
        if (!empty($config['autoload'])) {
173
            foreach ($config['autoload'] as $key => $moduleName) {
174
                if ($moduleName == $module) {
175
                    unset($config['autoload'][$key]);
176
                    break;
177
                }
178
            }
179
        }
180
        Config::save('app', $config, null, App::$primary);
181 View Code Duplication
        if (file_exists($path . $module . '/uninstall_script.php')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
182
            $installFunction = include $path . $module . '/uninstall_script.php';
183
            $installFunction(1, $params);
184
        }
185
    }
186
187
    public function addInMenu($items, $appType, $parent = 0) {
188
        foreach ($items as $item) {
189
            $menuItem = new \Menu\Item();
190
            $menuItem->name = $item['name'];
191
            $menuItem->href = $item['href'];
192
            $menuItem->Menu_id = 1;
193
            $menuItem->parent_id = $parent;
194
            $menuItem->save(['appType' => $appType]);
195
            if (!empty($item['childs'])) {
196
                $this->addInMenu($item['childs'], $appType, $menuItem->pk());
197
            }
198
        }
199
    }
200
201
    public function getSelectListModels($module = '') {
202
        $models = [];
203
        if ($module) {
204
            $modelsNames = $this->getModelsList($module);
205
206
            $info = Modules::getInfo($module);
207
            $moduleName = !empty($info['name']) ? $info['name'] : $module;
208 View Code Duplication
            foreach ($modelsNames as $modelName) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
209
                $fullModelName = $module . '\\' . $modelName;
210
                $models[$fullModelName] = $moduleName . ' - ' . ($fullModelName::$objectName ? $fullModelName::$objectName : $modelName);
211
            }
212
        }
213
        foreach (App::$primary->config['modules'] as $configModule) {
214
            if ($module == $configModule) {
215
                continue;
216
            }
217
            $modelsNames = $this->getModelsList($configModule);
218
            $info = Modules::getInfo($configModule);
219
            $moduleName = !empty($info['name']) ? $info['name'] : $configModule;
220 View Code Duplication
            foreach ($modelsNames as $modelName) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
221
                $fullModelName = $configModule . '\\' . $modelName;
222
                Router::loadClass($fullModelName);
223
                $models[$fullModelName] = $moduleName . ' - ' . ($fullModelName::$objectName ? $fullModelName::$objectName : $modelName);
224
            }
225
        }
226
        return $models;
227
    }
228
229
    public function getModelsList($module, $dir = '') {
230
        $modulePath = Module::getModulePath($module);
231
        $path = rtrim($modulePath . '/models/' . $dir, '/');
232
        $models = [];
233
        if (file_exists($path)) {
234
            foreach (array_slice(scandir($path), 2) as $file) {
235
                $modelLastName = pathinfo($file, PATHINFO_FILENAME);
236
                if (is_dir($path . '/' . $file)) {
237
                    $models = array_merge($models, $this->getModelsList($module, $dir . '/' . $modelLastName));
238
                }
239
                $nameSpace = trim(preg_replace('!/' . $modelLastName . '$!', '', $dir), '/');
240
                $models[] = trim(str_replace('/', '\\', $nameSpace) . '\\' . $modelLastName, '\\');
241
            }
242
        }
243
        return $models;
244
    }
245
246
    public function createController($module, $controllerType) {
247
        $modulePath = Module::getModulePath($module);
248
        $path = $modulePath . '/' . $controllerType . '/' . $module . 'Controller.php';
249
        $class = new CodeGenerator\ClassGenerator();
250
        $class->name = $module . 'Controller';
251
        $class->extends = 'Controller';
252
        $controllerCode = "<?php\n\n" . $class->generate();
253
        Tools::createDir(pathinfo($path, PATHINFO_DIRNAME));
254
        file_put_contents($path, $controllerCode);
255
        $config = Config::custom($modulePath . '/generatorHash.php');
256
        $config[$controllerType . '/' . $module . 'Controller.php'] = md5($controllerCode);
257
        Config::save($modulePath . '/generatorHash.php', $config);
258
    }
259
260
    public function addActionToController($module, $type, $controller, $url) {
261
        $modulePath = Module::getModulePath($module);
262
        $path = Modules::getModulePath($module) . '/' . $type . '/' . $controller . '.php';
263
        $class = CodeGenerator::parseClass($path);
264
        $class->addMethod($url . 'Action');
265
        $controllerCode = "<?php\n\n" . $class->generate();
266
        Tools::createDir(pathinfo($path, PATHINFO_DIRNAME));
267
        file_put_contents($path, $controllerCode);
268
        $config = Config::custom($modulePath . '/generatorHash.php');
269
        $config[$type . '/' . $module . 'Controller.php'] = md5($controllerCode);
270
        Config::save($modulePath . '/generatorHash.php', $config);
271
    }
272
}