Passed
Push — develop ( 965d29...c5f4e1 )
by Nikolay
06:33
created

SystemManagementProcessor   B

Complexity

Total Complexity 51

Size/Duplication

Total Lines 319
Duplicated Lines 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
wmc 51
eloc 227
c 5
b 0
f 0
dl 0
loc 319
rs 7.92

3 Methods

Rating   Name   Duplication   Size   Complexity  
F callBack() 0 149 33
F restoreDefaultSettings() 0 116 15
A upgradeFromImg() 0 29 3

How to fix   Complexity   

Complex Class

Complex classes like SystemManagementProcessor often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use SystemManagementProcessor, and based on these observations, apply Extract Interface, too.

1
<?php
2
/*
3
 * Copyright © MIKO LLC - All Rights Reserved
4
 * Unauthorized copying of this file, via any medium is strictly prohibited
5
 * Proprietary and confidential
6
 * Written by Alexey Portnov, 9 2020
7
 */
8
9
namespace MikoPBX\PBXCoreREST\Lib;
10
11
12
use MikoPBX\Common\Models\AsteriskManagerUsers;
13
use MikoPBX\Common\Models\CallQueues;
14
use MikoPBX\Common\Models\ConferenceRooms;
15
use MikoPBX\Common\Models\Extensions;
16
use MikoPBX\Common\Models\IncomingRoutingTable;
17
use MikoPBX\Common\Models\IvrMenu;
18
use MikoPBX\Common\Models\OutgoingRoutingTable;
19
use MikoPBX\Common\Models\OutWorkTimes;
20
use MikoPBX\Common\Models\PbxExtensionModules;
21
use MikoPBX\Common\Models\Providers;
22
use MikoPBX\Common\Models\SoundFiles;
23
use MikoPBX\Common\Providers\MessagesProvider;
24
use MikoPBX\Common\Providers\PBXConfModulesProvider;
25
use MikoPBX\Common\Providers\TranslationProvider;
26
use MikoPBX\Core\Asterisk\Configs\VoiceMailConf;
27
use MikoPBX\Core\System\Notifications;
28
use MikoPBX\Core\System\System;
29
use MikoPBX\Core\System\Util;
30
use MikoPBX\Modules\PbxExtensionState;
31
use MikoPBX\Modules\PbxExtensionUtils;
32
use MikoPBX\PBXCoreREST\Workers\WorkerMergeUploadedFile;
33
use Phalcon\Di;
34
use Phalcon\Di\Injectable;
35
36
class SystemManagementProcessor extends Injectable
37
{
38
    /**
39
     * Processes System requests
40
     *
41
     * @param array $request
42
     *
43
     * @return \MikoPBX\PBXCoreREST\Lib\PBXApiResult
44
     *
45
     * @throws \Exception
46
     */
47
    public static function callBack(array $request): PBXApiResult
48
    {
49
        $action         = $request['action'];
50
        $data           = $request['data'];
51
        $res            = new PBXApiResult();
52
        $res->processor = __METHOD__;
53
        switch ($action) {
54
            case 'reboot':
55
                System::rebootSync();
56
                $res->success = true;
57
                break;
58
            case 'shutdown':
59
                System::shutdown();
60
                $res->success = true;
61
                break;
62
            case 'mergeUploadedFile':
63
                $phpPath              = Util::which('php');
64
                $workerDownloaderPath = Util::getFilePathByClassName(WorkerMergeUploadedFile::class);
65
                Util::mwExecBg("{$phpPath} -f {$workerDownloaderPath} '{$data['settings_file']}'");
66
                $res->success = true;
67
                break;
68
            case 'getDate':
69
                $res->success           = true;
70
                $res->data['timestamp'] = time();
71
                break;
72
            case 'setDate':
73
                $res->success = System::setDate($data['timestamp'], $data['userTimeZone']);
74
                break;
75
            case 'updateCoreLanguage':
76
                $di = Di::getDefault();
77
                $di->remove('messages');
78
                $di->remove('translation');
79
                $di->register(new MessagesProvider());
80
                $di->register(new TranslationProvider());
81
                break;
82
            case 'updateMailSettings':
83
                // TODO:
84
                $res->success = true;
85
                break;
86
            case 'sendMail':
87
                if (isset($data['email']) && isset($data['subject']) && isset($data['body'])) {
88
                    if (isset($data['encode']) && $data['encode'] === 'base64') {
89
                        $data['subject'] = base64_decode($data['subject']);
90
                        $data['body']    = base64_decode($data['body']);
91
                    }
92
                    $result = Notifications::sendMail($data['email'], $data['subject'], $data['body']);
93
                    if ($result === true) {
94
                        $res->success = true;
95
                    } else {
96
                        $res->success    = false;
97
                        $res->messages[] = $result;
98
                    }
99
                } else {
100
                    $res->success    = false;
101
                    $res->messages[] = 'Not all query parameters are set';
102
                }
103
                break;
104
            case 'fileReadContent':
105
                $res = FilesManagementProcessor::fileReadContent($data['filename'], $data['needOriginal']);
106
                break;
107
            case 'reloadMsmtp':
108
                $notifications = new Notifications();
109
                $notifications->configure();
110
                $voiceMailConfig = new VoiceMailConf();
111
                $voiceMailConfig->generateConfig();
112
                $asteriskPath = Util::which('asterisk');
113
                Util::mwExec("{$asteriskPath} -rx 'voicemail reload'");
114
                $res->success = true;
115
                break;
116
            case 'unBanIp':
117
                $res = FirewallManagementProcessor::fail2banUnbanAll($data['ip']);
118
                break;
119
            case 'getBanIp':
120
                $res = FirewallManagementProcessor::getBanIp();
121
                break;
122
            case 'downloadNewFirmware':
123
                $res = FilesManagementProcessor::downloadNewFirmware($request['data']);
124
                break;
125
            case 'firmwareDownloadStatus':
126
                $res = FilesManagementProcessor::firmwareDownloadStatus();
127
                break;
128
            case 'upgrade':
129
                $res = SystemManagementProcessor::upgradeFromImg($data['temp_filename']);
130
                break;
131
            case 'removeAudioFile':
132
                $res = FilesManagementProcessor::removeAudioFile($data['filename']);
133
                break;
134
            case 'convertAudioFile':
135
                $mvPath = Util::which('mv');
136
                Util::mwExec("{$mvPath} {$data['temp_filename']} {$data['filename']}");
137
                $res = FilesManagementProcessor::convertAudioFile($data['filename']);
138
                break;
139
            case 'downloadNewModule':
140
                $module = $request['data']['uniqid'];
141
                $url    = $request['data']['url'];
142
                $md5    = $request['data']['md5'];
143
                $res    = FilesManagementProcessor::moduleStartDownload($module, $url, $md5);
144
                break;
145
            case 'moduleDownloadStatus':
146
                $module = $request['data']['uniqid'];
147
                $res    = FilesManagementProcessor::moduleDownloadStatus($module);
148
                break;
149
            case 'installNewModule':
150
                $filePath = $request['data']['filePath'];
151
                $res      = FilesManagementProcessor::installModuleFromFile($filePath);
152
                break;
153
            case 'enableModule':
154
                $moduleUniqueID       = $request['data']['uniqid'];
155
                $moduleStateProcessor = new PbxExtensionState($moduleUniqueID);
156
                if ($moduleStateProcessor->enableModule() === false) {
157
                    $res->success  = false;
158
                    $res->messages = $moduleStateProcessor->getMessages();
159
                } else {
160
                    PBXConfModulesProvider::recreateModulesProvider();
161
                    $res->data                       = $moduleStateProcessor->getMessages();
162
                    $res->data['needRestartWorkers'] = true; //TODO:: Проверить надо ли это
163
                    $res->success                    = true;
164
                }
165
                break;
166
            case 'disableModule':
167
                $moduleUniqueID       = $request['data']['uniqid'];
168
                $moduleStateProcessor = new PbxExtensionState($moduleUniqueID);
169
                if ($moduleStateProcessor->disableModule() === false) {
170
                    $res->success  = false;
171
                    $res->messages = $moduleStateProcessor->getMessages();
172
                } else {
173
                    PBXConfModulesProvider::recreateModulesProvider();
174
                    $res->data                       = $moduleStateProcessor->getMessages();
175
                    $res->data['needRestartWorkers'] = true; //TODO:: Проверить надо ли это
176
                    $res->success                    = true;
177
                }
178
                break;
179
            case 'uninstallModule':
180
                $moduleUniqueID = $request['data']['uniqid'];
181
                $keepSettings   = $request['data']['keepSettings'] === 'true';
182
                $res            = FilesManagementProcessor::uninstallModule($moduleUniqueID, $keepSettings);
183
                break;
184
            case 'restoreDefault':
185
                $res = self::restoreDefaultSettings();
186
                break;
187
            default:
188
                $res             = new PBXApiResult();
189
                $res->processor  = __METHOD__;
190
                $res->messages[] = "Unknown action - {$action} in systemCallBack";
191
        }
192
193
        $res->function = $action;
194
195
        return $res;
196
    }
197
198
    /**
199
     * Upgrade MikoPBX from uploaded IMG file
200
     *
201
     * @param string $tempFilename path to uploaded image
202
     *
203
     * @return PBXApiResult
204
     */
205
    public static function upgradeFromImg(string $tempFilename): PBXApiResult
206
    {
207
        $res                  = new PBXApiResult();
208
        $res->processor       = __METHOD__;
209
        $res->success         = true;
210
        $res->data['message'] = 'In progress...';
211
212
213
        if ( ! file_exists($tempFilename)) {
214
            $res->success    = false;
215
            $res->messages[] = "Update file '{$tempFilename}' not found.";
216
217
            return $res;
218
        }
219
220
        if ( ! file_exists('/var/etc/cfdevice')) {
221
            $res->success    = false;
222
            $res->messages[] = "The system is not installed";
223
224
            return $res;
225
        }
226
        $dev = trim(file_get_contents('/var/etc/cfdevice'));
227
228
        $link = '/tmp/firmware_update.img';
229
        Util::createUpdateSymlink($tempFilename, $link);
230
        $mikopbx_firmwarePath = Util::which('mikopbx_firmware');
231
        Util::mwExecBg("{$mikopbx_firmwarePath} recover_upgrade {$link} /dev/{$dev}");
232
233
        return $res;
234
    }
235
236
    /**
237
     * Deletes all settings and uploaded files
238
     */
239
    private static function restoreDefaultSettings(): PBXApiResult
240
    {
241
        $res                             = new PBXApiResult();
242
        $res->processor                  = __METHOD__;
243
        $res->success                    = true;
244
        $res->data['needRestartWorkers'] = true;
245
        $rm                              = Util::which('rm');
246
247
        // Delete all providers
248
        $records = Providers::find();
249
        if ( ! $records->delete()) {
250
            $res->messages[] = $records->getMessages();
251
            $res->success    = false;
252
        }
253
254
        // Delete routes
255
        $records = OutgoingRoutingTable::find();
256
        if ( ! $records->delete()) {
257
            $res->messages[] = $records->getMessages();
258
            $res->success    = false;
259
        }
260
261
        $records = IncomingRoutingTable::find();
262
        if ( ! $records->delete()) {
263
            $res->messages[] = $records->getMessages();
264
            $res->success    = false;
265
        }
266
267
        // Delete out of work settings
268
        $records = OutWorkTimes::find();
269
        if ( ! $records->delete()) {
270
            $res->messages[] = $records->getMessages();
271
            $res->success    = false;
272
        }
273
274
        // AMI Users
275
        $records = AsteriskManagerUsers::find();
276
        if ( ! $records->delete()) {
277
            $res->messages[] = $records->getMessages();
278
            $res->success    = false;
279
        }
280
281
        // Pre delete some extensions type
282
        // IVR Menu
283
        $records = Extensions::find('type="'.Extensions::TYPE_IVR_MENU.'"');
284
        $records->delete();
285
286
        // CONFERENCE
287
        $records = Extensions::find('type="'.Extensions::TYPE_CONFERENCE.'"');
288
        $records->delete();
289
290
        // QUEUE
291
        $records = Extensions::find('type="'.Extensions::TYPE_QUEUE.'"');
292
        $records->delete();
293
294
295
        // Other extensions
296
        $parameters     = [
297
            'conditions' => 'not number IN ({ids:array})',
298
            'bind'       => [
299
                'ids' => [
300
                    '000063', //Reads back the extension
301
                    '000064', //0000MILLI
302
                    '10003246'//Echo test
303
                ],
304
            ],
305
        ];
306
        $stopDeleting   = false;
307
        $countRecords   = Extensions::count($parameters);
308
        $deleteAttempts = 0;
309
        while ($stopDeleting === false) {
310
            $record = Extensions::findFirst($parameters);
311
            if ($record === null) {
312
                $stopDeleting = true;
313
                continue;
314
            }
315
            if ( ! $record->delete()) {
316
                $deleteAttempts += 1;
317
            }
318
            if ($deleteAttempts > $countRecords * 10) {
319
                $stopDeleting    = true; // Prevent loop
320
                $res->messages[] = $record->getMessages();
321
            }
322
        }
323
324
        // SoundFiles
325
        $parameters = [
326
            'conditions' => 'category = :custom:',
327
            'bind'       => [
328
                'custom' => SoundFiles::CATEGORY_CUSTOM,
329
            ],
330
        ];
331
        $records    = SoundFiles::find($parameters);
332
333
        foreach ($records as $record) {
334
            if (stripos($record->path, '/storage/usbdisk1/mikopbx') !== false) {
335
                Util::mwExec("{$rm} -rf {$record->path}");
336
                if ( ! $record->delete()) {
337
                    $res->messages[] = $record->getMessages();
338
                    $res->success    = false;
339
                }
340
            }
341
        }
342
343
        // PbxExtensions
344
        $records = PbxExtensionModules::find();
345
        foreach ($records as $record) {
346
            $moduleDir = PbxExtensionUtils::getModuleDir($record->uniqid);
347
            Util::mwExec("{$rm} -rf {$moduleDir}");
348
            if ( ! $record->delete()) {
349
                $res->messages[] = $record->getMessages();
350
                $res->success    = false;
351
            }
352
        }
353
354
        return $res;
355
    }
356
357
}