Passed
Push — develop ( c1253e...f72558 )
by Nikolay
12:51
created

RestoreDefaultSettings::main()   B

Complexity

Conditions 8
Paths 25

Size

Total Lines 82
Code Lines 58

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 58
c 1
b 0
f 0
dl 0
loc 82
rs 7.6719
cc 8
nc 25
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/*
3
 * MikoPBX - free phone system for small business
4
 * Copyright © 2017-2023 Alexey Portnov and Nikolay Beketov
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with this program.
17
 * If not, see <https://www.gnu.org/licenses/>.
18
 */
19
20
namespace MikoPBX\PBXCoreREST\Lib\System;
21
22
use MikoPBX\Common\Models\AsteriskManagerUsers;
23
use MikoPBX\Common\Models\CallQueueMembers;
24
use MikoPBX\Common\Models\CallQueues;
25
use MikoPBX\Common\Models\CustomFiles;
26
use MikoPBX\Common\Models\ExtensionForwardingRights;
27
use MikoPBX\Common\Models\Extensions;
28
use MikoPBX\Common\Models\FirewallRules;
29
use MikoPBX\Common\Models\Iax;
30
use MikoPBX\Common\Models\IncomingRoutingTable;
31
use MikoPBX\Common\Models\IvrMenu;
32
use MikoPBX\Common\Models\IvrMenuActions;
33
use MikoPBX\Common\Models\NetworkFilters;
34
use MikoPBX\Common\Models\OutgoingRoutingTable;
35
use MikoPBX\Common\Models\OutWorkTimes;
36
use MikoPBX\Common\Models\PbxExtensionModules;
37
use MikoPBX\Common\Models\PbxSettings;
38
use MikoPBX\Common\Models\Sip;
39
use MikoPBX\Common\Models\SoundFiles;
40
use MikoPBX\Common\Models\Users;
41
use MikoPBX\Core\Asterisk\CdrDb;
42
use MikoPBX\Core\System\PBX;
43
use MikoPBX\Core\System\Processes;
44
use MikoPBX\Core\System\Upgrade\UpdateDatabase;
45
use MikoPBX\Core\System\Util;
46
use MikoPBX\Modules\PbxExtensionUtils;
47
use MikoPBX\PBXCoreREST\Lib\PBXApiResult;
48
use Phalcon\Di;
49
50
/**
51
 * Returns MikoPBX into default settings stage without any extensions, providers, cdr and sound files
52
 *
53
 * @package MikoPBX\PBXCoreREST\Lib\System
54
 */
55
class RestoreDefaultSettings extends \Phalcon\Di\Injectable
56
{
57
    /**
58
     * Restore default system settings.
59
     *
60
     * @return PBXApiResult An object containing the result of the API call.
61
     */
62
    public static function main(): PBXApiResult
63
    {
64
        $res            = new PBXApiResult();
65
        $res->processor = __METHOD__;
66
        $di             = DI::getDefault();
67
        if ($di === null) {
68
            $res->messages[] = 'Error on DI initialize';
69
            return $res;
70
        }
71
        $rm     = Util::which('rm');
72
        $res->success = true;
73
74
        // Change incoming rule to default action
75
        IncomingRoutingTable::resetDefaultRoute();
76
        self::preCleaning($res);
77
78
        self::cleaningMainTables($res);
79
        self::cleaningOtherExtensions($res);
80
        self::cleaningSoundFiles($res);
81
        self::cleaningBackups();
82
83
        // Delete PbxExtensions modules
84
        $records = PbxExtensionModules::find();
85
        foreach ($records as $record) {
86
            $moduleDir = PbxExtensionUtils::getModuleDir($record->uniqid);
87
            Processes::mwExec("{$rm} -rf {$moduleDir}");
88
            if ( ! $record->delete()) {
89
                $res->messages[] = $record->getMessages();
90
                $res->success    = false;
91
            }
92
        }
93
94
        // Reset PBXSettings
95
        $defaultValues = PbxSettings::getDefaultArrayValues();
96
        $fixedKeys = [
97
            'Name',
98
            'Description',
99
            'SSHPassword',
100
            'SSHRsaKey',
101
            'SSHDssKey',
102
            'SSHAuthorizedKeys',
103
            'SSHecdsaKey',
104
            'SSHLanguage',
105
            'WEBHTTPSPublicKey',
106
            'WEBHTTPSPrivateKey',
107
            'RedirectToHttps',
108
            'PBXLanguage',
109
            'PBXVersion',
110
            'WebAdminLogin',
111
            'WebAdminPassword',
112
            'WebAdminLanguage',
113
        ];
114
        foreach ($defaultValues as $key=>$defaultValue){
115
            if (in_array($key, $fixedKeys, true)){
116
                continue;
117
            }
118
            $record = PbxSettings::findFirstByKey($key);
119
            if ($record===null){
120
                $record = new PbxSettings();
121
                $record->key = $key;
122
            }
123
            $record->value = $defaultValue;
124
        }
125
126
        // Delete CallRecords from database
127
        $cdr = CdrDb::getPathToDB();
128
        Processes::mwExec("{$rm} -rf {$cdr}*");
129
        $dbUpdater = new UpdateDatabase();
130
        $dbUpdater->updateDatabaseStructure();
131
132
        // Delete CallRecords sound files
133
        $callRecordsPath = $di->getShared('config')->path('asterisk.monitordir');
134
        if (stripos($callRecordsPath, '/storage/usbdisk1/mikopbx') !== false) {
135
            Processes::mwExec("{$rm} -rf {$callRecordsPath}/*");
136
        }
137
138
        // Restart PBX
139
        $pbxConsole = Util::which('pbx-console');
140
        shell_exec("$pbxConsole services restart-all");
141
        PBX::coreRestart();
142
143
        return $res;
144
    }
145
146
    /**
147
     * Perform pre-cleaning operations on specific columns of certain models.
148
     *
149
     * @param PBXApiResult $res The result object to store any error messages.
150
     *
151
     * @return void
152
     */
153
    public static function preCleaning(PBXApiResult &$res):void
154
    {
155
        $preCleaning = [
156
            CallQueues::class => [
157
                'redirect_to_extension_if_empty',
158
                'redirect_to_extension_if_unanswered',
159
                'redirect_to_extension_if_repeat_exceeded'
160
            ],
161
            IvrMenu::class => [
162
                'timeout_extension'
163
            ]
164
        ];
165
        foreach ($preCleaning as $class => $columns) {
166
            $records = call_user_func([$class, 'find']);
167
            foreach ($records as $record){
168
                foreach ($columns as $column){
169
                    $record->$column = '';
170
                }
171
                if ( ! $record->save()) {
172
                    $res->messages[] = $record->getMessages();
173
                    $res->success    = false;
174
                }
175
            }
176
        }
177
    }
178
179
    /**
180
     * Perform cleaning operations on main tables.
181
     *
182
     * @param PBXApiResult $res The result object to store any error messages.
183
     *
184
     * @return void
185
     */
186
    public static function cleaningMainTables(&$res):void
187
    {
188
        // Define the models and conditions for cleaning
189
        $clearThisModels = [
190
            [ExtensionForwardingRights::class => ''],
191
            [OutWorkTimes::class => ''],
192
            [IvrMenuActions::class => ''],
193
            [CallQueueMembers::class => ''],
194
            [OutgoingRoutingTable::class => ''],
195
            [IncomingRoutingTable::class => 'id>1'],
196
            [Sip::class => ''], // All SIP providers
197
            [Iax::class => ''], // All IAX providers
198
            [AsteriskManagerUsers::class => ''],
199
            [Extensions::class => 'type="' . Extensions::TYPE_IVR_MENU . '"'],  // IVR Menu
200
            [Extensions::class => 'type="' . Extensions::TYPE_CONFERENCE . '"'],  // CONFERENCE
201
            [Extensions::class => 'type="' . Extensions::TYPE_QUEUE . '"'],  // QUEUE
202
            [Users::class => 'id>"1"'], // All except root with their extensions
203
            [CustomFiles::class => ''],
204
            [NetworkFilters::class=>'permit!="0.0.0.0/0" AND deny!="0.0.0.0/0"'] //Delete all other rules
205
        ];
206
207
        // Iterate over each model and perform deletion based on conditions
208
        foreach ($clearThisModels as $modelParams) {
209
            foreach ($modelParams as $key => $value) {
210
                $records = call_user_func([$key, 'find'], $value);
211
                if (!$records->delete()) {
212
                    // If deletion fails, add error messages to the result object
213
                    $res->messages[] = $records->getMessages();
214
                    $res->success    = false;
215
                }
216
            }
217
        }
218
        // Allow all connections for 0.0.0.0/0 in firewall rules
219
        $firewallRules = FirewallRules::find();
220
        foreach ($firewallRules as $firewallRule){
221
            $firewallRule->action = 'allow';
222
            $firewallRule->save();
223
        }
224
    }
225
226
    /**
227
     * Perform cleaning operations on other extensions.
228
     *
229
     * @param PBXApiResult $res The result object to store any error messages.
230
     *
231
     * @return void
232
     */
233
    public static function cleaningOtherExtensions(&$res):void
234
    {
235
        // Define the parameters for querying the extensions to delete
236
        $parameters     = [
237
            'conditions' => 'not number IN ({ids:array})',
238
            'bind'       => [
239
                'ids' => [
240
                    '000063',   // Reads back the extension
241
                    '000064',   // 0000MILLI
242
                    '10003246', // Echo test
243
                    'hangup',   // System Extension
244
                    'busy',     // System Extension
245
                    'did2user', // System Extension
246
                    'voicemail',// System Extension
247
                ],
248
            ],
249
        ];
250
        $stopDeleting   = false;
251
        $countRecords   = Extensions::count($parameters);
252
        $deleteAttempts = 0;
253
        while ($stopDeleting === false) {
254
            $record = Extensions::findFirst($parameters);
255
            if ($record === null) {
256
                $stopDeleting = true;
257
                continue;
258
            }
259
            if ( ! $record->delete()) {
260
                $deleteAttempts += 1;
261
            }
262
            if ($deleteAttempts > $countRecords * 10) {
263
                $stopDeleting    = true; // Prevent loop
264
                $res->messages[] = $record->getMessages();
265
            }
266
        }
267
    }
268
269
    /**
270
     * Clean up custom sound files.
271
     *
272
     * @param PBXApiResult $res The result object to store any error messages.
273
     *
274
     * @return void
275
     */
276
    public static function cleaningSoundFiles(&$res):void
277
    {
278
        $rm     = Util::which('rm');
279
        $parameters = [
280
            'conditions' => 'category = :custom:',
281
            'bind'       => [
282
                'custom' => SoundFiles::CATEGORY_CUSTOM,
283
            ],
284
        ];
285
        $records    = SoundFiles::find($parameters);
286
        foreach ($records as $record) {
287
            if (stripos($record->path, '/storage/usbdisk1/mikopbx') !== false) {
288
                Processes::mwExec("{$rm} -rf {$record->path}");
289
                if ( ! $record->delete()) {
290
                    $res->messages[] = $record->getMessages();
291
                    $res->success    = false;
292
                }
293
            }
294
        }
295
    }
296
297
    /**
298
     * Deletes main database (CF) backups
299
     * @return void
300
     */
301
    public static function cleaningBackups():void
302
    {
303
        $di = Di::getDefault();
304
        $dir = $di->getShared('config')->path('core.mediaMountPoint').'/mikopbx/backup';
305
        if(file_exists($dir)){
306
            $chAttr     = Util::which('chattr');
307
            Processes::mwExec("$chAttr -i -R $dir");
308
            $rm     = Util::which('rm');
309
            Processes::mwExec("$rm -rf $dir/*");
310
        }
311
    }
312
313
314
}