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

SystemManagementProcessor::installModule()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 55
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 31
dl 0
loc 55
rs 9.1128
c 1
b 0
f 0
cc 5
nc 6
nop 1

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;
21
22
use MikoPBX\Core\System\Notifications;
23
use MikoPBX\Core\System\Processes;
24
use MikoPBX\Core\System\Storage;
25
use MikoPBX\Core\System\System;
26
use MikoPBX\Core\System\Util;
27
use MikoPBX\PBXCoreREST\Lib\System\RestoreDefaultSettings;
28
use Phalcon\Di\Injectable;
29
30
31
/**
32
 * Class SystemManagementProcessor
33
 *
34
 * @package MikoPBX\PBXCoreREST\Lib
35
 *
36
 */
37
class SystemManagementProcessor extends Injectable
38
{
39
    /**
40
     * Processes System requests
41
     *
42
     * @param array $request
43
     *
44
     * @return PBXApiResult An object containing the result of the API call.
45
     *
46
     * @throws \Exception
47
     */
48
    public static function callBack(array $request): PBXApiResult
49
    {
50
        $action         = $request['action'];
51
        $data           = $request['data'];
52
        $res            = new PBXApiResult();
53
        $res->processor = __METHOD__;
54
        switch ($action) {
55
            case 'reboot':
56
                System::rebootSync();
57
                $res->success = true;
58
                break;
59
            case 'shutdown':
60
                System::shutdown();
61
                $res->success = true;
62
                break;
63
            case 'getDate':
64
                $res->success           = true;
65
                $res->data['timestamp'] = time();
66
                break;
67
            case 'setDate':
68
                $res->success = System::setDate($data['timestamp'], $data['userTimeZone']);
69
                break;
70
            case 'updateMailSettings':
71
                $notifier     = new Notifications();
72
                $res->success = $notifier->sendTestMail();
73
                break;
74
            case 'sendMail':
75
                $res = self::sendMail($data);
76
                break;
77
            case 'upgrade':
78
                $res = self::upgradeFromImg($data['temp_filename']);
79
                break;
80
            case 'restoreDefault':
81
                $ch = 0;
82
                do{
83
                    $ch++;
84
                    $res = RestoreDefaultSettings::main();
85
                    sleep(1);
86
                }while($ch <= 10 && !$res->success);
87
                break;
88
            case 'convertAudioFile':
89
                $mvPath = Util::which('mv');
90
                Processes::mwExec("{$mvPath} {$request['data']['temp_filename']} {$request['data']['filename']}");
91
                $res = self::convertAudioFile($request['data']['filename']);
92
                break;
93
            default:
94
                $res->messages[] = "Unknown action - {$action} in systemCallBack";
95
        }
96
97
        $res->function = $action;
98
99
        return $res;
100
    }
101
102
    /**
103
     * Sends an email notification.
104
     *
105
     * @param array $data The data containing email, subject, and body.
106
     *
107
     * @return PBXApiResult An object containing the result of the API call.
108
     */
109
    private static function sendMail(array $data): PBXApiResult
110
    {
111
        $res            = new PBXApiResult();
112
        $res->processor = __METHOD__;
113
        if (isset($data['email']) && isset($data['subject']) && isset($data['body'])) {
114
            if (isset($data['encode']) && $data['encode'] === 'base64') {
115
                $data['subject'] = base64_decode($data['subject']);
116
                $data['body']    = base64_decode($data['body']);
117
            }
118
            $notifier = new Notifications();
119
            $result   = $notifier->sendMail($data['email'], $data['subject'], $data['body']);
120
            if ($result === true) {
121
                $res->success = true;
122
            } else {
123
                $res->success    = false;
124
                $res->messages[] = 'Notifications::sendMail method returned false';
125
            }
126
        } else {
127
            $res->success    = false;
128
            $res->messages[] = 'Not all query parameters were set';
129
        }
130
131
        return $res;
132
    }
133
134
    /**
135
     * Upgrade the PBX using uploaded IMG file.
136
     *
137
     * @param string $tempFilename The path to the uploaded image file.
138
     *
139
     * @return PBXApiResult An object containing the result of the API call.
140
     */
141
    public static function upgradeFromImg(string $tempFilename): PBXApiResult
142
    {
143
        $res                  = new PBXApiResult();
144
        $res->processor       = __METHOD__;
145
        $res->success         = true;
146
        $res->data['message'] = 'In progress...';
147
148
        if ( ! file_exists($tempFilename)) {
149
            $res->success    = false;
150
            $res->messages[] = "Update file '{$tempFilename}' not found.";
151
152
            return $res;
153
        }
154
155
        if ( ! file_exists('/var/etc/cfdevice')) {
156
            $res->success    = false;
157
            $res->messages[] = "The system is not installed";
158
159
            return $res;
160
        }
161
        $dev     = trim(file_get_contents('/var/etc/cfdevice'));
162
        $storage = new Storage();
163
164
        // Generate update script
165
        $cmd = '/bin/busybox grep "$(/bin/busybox  cat /var/etc/storage_device) " < /etc/fstab | /bin/busybox awk -F"[= ]" "{ print \$2}"';
166
        $storage_uuid = trim(shell_exec($cmd));
167
        $cf_uuid      = $storage->getUuid("{$dev}3");
168
        $data = "#!/bin/sh".PHP_EOL.
169
                'rm -rf "$0";'.PHP_EOL.
170
                "export storage_uuid='$storage_uuid';".PHP_EOL.
171
                "export cf_uuid='$cf_uuid';".PHP_EOL.
172
                "export updateFile='$tempFilename';".PHP_EOL;
173
174
        // Mount boot partition
175
        $cmd = '/bin/lsblk -o UUID,PKNAME -p | /bin/busybox grep "'.$cf_uuid.'" | /bin/busybox cut -f 2 -d " "';
176
        $bootDisc = trim(shell_exec($cmd));
177
178
        $systemDir = '/system';
179
        Util::mwMkdir($systemDir);
180
        $result = Processes::mwExec("mount {$bootDisc}1 $systemDir");
181
        if($result === 0){
182
            file_put_contents("$systemDir/update.sh", $data);
183
            // Reboot the system
184
            System::rebootSyncBg();
185
        }else{
186
            $res->success    = false;
187
            $res->messages[] = "Fail mount boot device...";
188
        }
189
190
        return $res;
191
    }
192
193
194
    /**
195
     * Convert the audio file to various codecs using Asterisk.
196
     *
197
     * @param string $filename The path of the audio file to be converted.
198
     * @return PBXApiResult An object containing the result of the API call.
199
     */
200
    public static function convertAudioFile(string $filename): PBXApiResult
201
    {
202
        $res            = new PBXApiResult();
203
        $res->processor = __METHOD__;
204
        if ( ! file_exists($filename)) {
205
            $res->success    = false;
206
            $res->messages[] = "File '{$filename}' not found.";
207
208
            return $res;
209
        }
210
        $out          = [];
211
        $tmp_filename = '/tmp/' . time() . "_" . basename($filename);
212
        if (false === copy($filename, $tmp_filename)) {
213
            $res->success    = false;
214
            $res->messages[] = "Unable to create temporary file '{$tmp_filename}'.";
215
216
            return $res;
217
        }
218
219
        // Change extension to wav
220
        $trimmedFileName = Util::trimExtensionForFile($filename);
221
        $n_filename     = $trimmedFileName . ".wav";
222
        $n_filename_mp3 = $trimmedFileName . ".mp3";
223
224
        // Convert file to wav format
225
        $tmp_filename = escapeshellcmd($tmp_filename);
226
        $n_filename   = escapeshellcmd($n_filename);
227
        $soxPath      = Util::which('sox');
228
        Processes::mwExec("{$soxPath} -v 0.99 -G '{$tmp_filename}' -c 1 -r 8000 -b 16 '{$n_filename}'", $out);
229
        $result_str = implode('', $out);
230
231
        // Convert wav file to mp3 format
232
        $lamePath = Util::which('lame');
233
        Processes::mwExec("{$lamePath} -b 32 --silent '{$n_filename}' '{$n_filename_mp3}'", $out);
234
        $result_mp3 = implode('', $out);
235
236
        // Convert the file to various codecs using Asterisk
237
        $codecs = ['alaw', 'ulaw', 'gsm', 'g722', 'wav'];
238
        $rmPath       = Util::which('rm');
239
        $asteriskPath = Util::which('asterisk');
240
        foreach ($codecs as $codec){
241
            $result = shell_exec("$asteriskPath -rx 'file convert $tmp_filename $trimmedFileName.$codec'");
242
            if(strpos($result, 'Converted') !== 0){
243
                shell_exec("$rmPath -rf /root/test.{$codec}");
244
            }
245
        }
246
247
        // Remove temporary file
248
        unlink($tmp_filename);
249
        if ($result_str !== '' && $result_mp3 !== '') {
250
            // Conversion failed
251
            $res->success    = false;
252
            $res->messages[] = $result_str;
253
254
            return $res;
255
        }
256
257
        if (file_exists($filename)
258
            && $filename !== $n_filename
259
            && $filename !== $n_filename_mp3) {
260
            // Remove the original file if it's different from the converted files
261
            unlink($filename);
262
        }
263
264
        $res->success = true;
265
        $res->data[]  = $n_filename_mp3;
266
267
        return $res;
268
    }
269
270
}