Issues (1519)

system/modules/Modules/Modules.php (12 issues)

1
<?php
2
namespace Inji;
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);
0 ignored issues
show
The method getTableCols() does not exist on Inji\Module. It seems like you code against a sub-type of Inji\Module such as Inji\Db. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

48
        /** @scrutinizer ignore-call */ 
49
        $colsExist = App::$cur->db->getTableCols($tableName);
Loading history...
Bug Best Practice introduced by
The property db does not exist on Inji\App. Since you implemented __get, consider adding a @property annotation.
Loading history...
The method getTableCols() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

48
        /** @scrutinizer ignore-call */ 
49
        $colsExist = App::$cur->db->getTableCols($tableName);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
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)) {
0 ignored issues
show
The method tableExist() does not exist on Inji\Module. It seems like you code against a sub-type of Inji\Module such as Inji\Db. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

95
            if (App::$cur->db->/** @scrutinizer ignore-call */ tableExist($tableName)) {
Loading history...
Bug Best Practice introduced by
The property db does not exist on Inji\App. Since you implemented __get, consider adding a @property annotation.
Loading history...
96
                foreach ($tableCols as $colKey => $params) {
97
                    App::$cur->db->add_col($tableName, $colKey, $params);
0 ignored issues
show
The method add_col() does not exist on Inji\Module. It seems like you code against a sub-type of Inji\Module such as Inji\Db. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

97
                    App::$cur->db->/** @scrutinizer ignore-call */ 
98
                                   add_col($tableName, $colKey, $params);
Loading history...
98
                }
99
            } else {
100
                App::$cur->db->createTable($tableName, $tableCols);
0 ignored issues
show
The method createTable() does not exist on Inji\Module. It seems like you code against a sub-type of Inji\Module such as Inji\Db. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

100
                App::$cur->db->/** @scrutinizer ignore-call */ 
101
                               createTable($tableName, $tableCols);
Loading history...
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 \Inji\Menu\Item();
191
            $menuItem->name = $item['name'];
0 ignored issues
show
Bug Best Practice introduced by
The property name does not exist on Inji\Menu\Item. Since you implemented __set, consider adding a @property annotation.
Loading history...
192
            $menuItem->href = $item['href'];
0 ignored issues
show
Bug Best Practice introduced by
The property href does not exist on Inji\Menu\Item. Since you implemented __set, consider adding a @property annotation.
Loading history...
193
            $menuItem->Menu_id = 1;
0 ignored issues
show
Bug Best Practice introduced by
The property Menu_id does not exist on Inji\Menu\Item. Since you implemented __set, consider adding a @property annotation.
Loading history...
194
            $menuItem->parent_id = $parent;
0 ignored issues
show
Bug Best Practice introduced by
The property parent_id does not exist on Inji\Menu\Item. Since you implemented __set, consider adding a @property annotation.
Loading history...
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);
0 ignored issues
show
The property objectName does not exist on string.
Loading history...
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
}