Passed
Push — develop ( 15bc6b...5ea31b )
by Nikolay
05:50 queued 12s
created

PostController::upgradeOverUploadedImg()   B

Complexity

Conditions 8
Paths 12

Size

Total Lines 25
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 16
dl 0
loc 25
rs 8.4444
c 0
b 0
f 0
cc 8
nc 12
nop 0
1
<?php
2
/**
3
 * Copyright (C) MIKO LLC - All Rights Reserved
4
 * Unauthorized copying of this file, via any medium is strictly prohibited
5
 * Proprietary and confidential
6
 * Written by Nikolay Beketov, 4 2020
7
 *
8
 */
9
10
namespace MikoPBX\PBXCoreREST\Controllers\System;
11
12
use MikoPBX\Common\Models\SoundFiles;
13
use MikoPBX\Core\System\Util;
14
use MikoPBX\PBXCoreREST\Controllers\BaseController;
15
use Phalcon\Di;
16
17
/**
18
 * /pbxcore/api/system/{name}' Управление системой в целом (POST).
19
 *
20
 * Установка системного времени
21
 *   curl -X POST -d '{"date": "2015.12.31-01:01:20"}' http://172.16.156.212/pbxcore/api/system/setDate;
22
 *
23
 * Отправка email.
24
 *   curl -X POST -d '{"email": "[email protected]", "subject":"Привет от mikopbx", "body":"Тестовое сообщение", "encode":
25
 *   ""}' http://172.16.156.223/pbxcore/api/system/sendMail;
26
 *     'encode' - может быть пустой строкой или 'base64', на случай, если subject и body передаются в base64;
27
 *
28
 * Снятие бана IP адреса
29
 *   curl -X POST -d '{"ip": "172.16.156.1"}' http://172.16.156.212/pbxcore/api/system/unBanIp;
30
 *   Пример ответа:
31
 *   {"result":"Success","data":[{"jail":"asterisk","ip":"172.16.156.1","timeofban":1522326119}],"function":"getBanIp"}
32
 *
33
 * Получение содержимого файла.
34
 *   curl -X POST -d '{"filename": "/etc/asterisk/asterisk.conf"}'
35
 *   http://172.16.156.212/pbxcore/api/system/fileReadContent; Примеры ответа:
36
 *   {"result":"ERROR","message":"API action not found;","function":"fileReadContent"}
37
 *   {"result":"Success","data":"W2RpcmVj","function":"fileReadContent"}
38
 *
39
 * Конвертация аудио файла:
40
 *   curl -X POST -d '{"filename": "/tmp/WelcomeMaleMusic.mp3"}'
41
 *   http://172.16.156.212/pbxcore/api/system/convertAudioFile; Пример ответа:
42
 *   {
43
 *      "result": "Success",
44
 *      "filename": "/tmp/WelcomeMaleMusic.wav",
45
 *      "function": "convertAudioFile"
46
 *   }
47
 *
48
 * Загрузка аудио файла на АТС:
49
 *   curl  -X POST -d '{"filename": "/storage/usbdisk1/mikopbx/tmp/1577195443/test.mp3"}'
50
 *   http://127.0.0.1/pbxcore/api/system/uploadAudioFile -H 'Cookie: XDEBUG_SESSION=PHPSTORM'; curl  -F
51
 *   "file=@/storage/usbdisk1/mikopbx/voicemailarchive/monitor/2019/11/29/10/mikopbx-15750140_201_YNrXH1KHDj.mp3"
52
 *   http://127.0.0.1/pbxcore/api/system/uploadAudioFile;
53
 *
54
 * Пример ответа:
55
 *   {
56
 *      "result": "Success",
57
 *      "filename": "/tmp/WelcomeMaleMusic.wav",
58
 *      "function": "uploadAudioFile"
59
 *   }
60
 *
61
 * Удаление аудио файла:
62
 *   curl -X POST -d '{"filename": "/storage/usbdisk1/mikopbx/tmp/2233333.wav"}'
63
 *   http://172.16.156.212/pbxcore/api/system/removeAudioFile;
64
 *
65
 *
66
 * Обновление системы (офлайн) curl -X POST -d
67
 *   '{"filename": "/storage/usbdisk1/mikopbx/tmp/2019.4.200-mikopbx-generic-x86-64-linux.img"}'
68
 *   http://127.0.0.1/pbxcore/api/system/upgrade -H 'Cookie: XDEBUG_SESSION=PHPSTORM'; curl -F
69
 *   "[email protected]" http://172.16.156.212/pbxcore/api/system/upgrade;
70
 *
71
 *
72
 * Онлайн обновление АТС. curl -X POST -d '{"md5":"df7622068d0d58700a2a624d991b6c1f", "url":
73
 *   "https://www.askozia.ru/upload/update/firmware/6.2.96-9.0-svn-mikopbx-x86-64-cross-linux.img"}'
74
 *   http://172.16.156.223/pbxcore/api/system/upgradeOnline;
75
 *
76
 *
77
 * Install new module with params by URL
78
 * curl -X POST -d '{"uniqid":"ModuleCTIClient", "md5":"fd9fbf38298dea83667a36d1d0464eae", "url":
79
 * "https://www.askozia.ru/upload/update/modules/ModuleCTIClient/ModuleCTIClientv01.zip"}'
80
 * http://172.16.156.223/pbxcore/api/modules/uploadNewModule;
81
 *
82
 *
83
 * Receive uploading status
84
 * curl  -X POST -d '{"uniqid":"ModuleSmartIVR"} http://172.16.156.223/pbxcore/api/system/statusUploadingNewModule
85
 *
86
 *
87
 * Install new module from ZIP archive:
88
 * curl -F "[email protected]" http://127.0.0.1/pbxcore/api/modules/uploadNewModule;
89
 *
90
 *
91
 * Uninstall module:
92
 * curl -X POST -d '{"uniqid":"ModuleSmartIVR"} http://172.16.156.223/pbxcore/api/system/uninstallModule
93
 *
94
 *
95
 */
96
class PostController extends BaseController
97
{
98
    public function callAction($actionName): void
99
    {
100
        $data = null;
101
        switch ($actionName){
102
            case 'upgrade':
103
                if ($this->upgradeOverUploadedImg()===false){
104
                    return;
105
                }
106
                break;
107
            case 'uploadAudioFile':
108
                if ($this->uploadAudioFile()) {
109
                    $actionName = 'convertAudioFile';
110
                } else {
111
                    return;
112
                }
113
                break;
114
            case 'uploadNewModule':
115
                $data  = $this->uploadNewModule();
116
                if ($data === false){
117
                    return;
118
                }
119
                break;
120
            default:
121
                $row_data = $this->request->getRawBody();
122
                // Проверим, переданные данные.
123
                if ( ! Util::isJson($row_data)) {
124
                    $this->sendError(400, 'It is not JSON');
125
                    return;
126
                }
127
                $data = json_decode($row_data, true);
128
        }
129
130
        $this->sendRequestToBackendWorker('system', $actionName, $data);
131
    }
132
133
    /**
134
     * Prepare uploaded image to update
135
     * @return bool
136
     */
137
    private function upgradeOverUploadedImg():bool
138
    {
139
        $di       = Di::getDefault();
140
        $tempDir  = $di->getShared('config')->path('core.tempPath');
141
        $upd_file = "{$tempDir}/update.img";
142
        $res      = false;
143
        if ($this->request->hasFiles() === 0) {
144
            // Используем существующий файл;
145
            $postData = json_decode($this->request->getRawBody(), true);
146
            if ($postData && isset($postData['filename']) && file_exists($postData['filename'])) {
147
                $cpPath = Util::which('cp');
148
                $res = Util::mwExec("{$cpPath} '{$postData['filename']}' '{$upd_file}'") === 0;
149
            }
150
        } else {
151
            // Загружаем новый файл на сервер
152
            foreach ($this->request->getUploadedFiles() as $file) {
153
                $res = $file->moveTo($upd_file);
154
            }
155
        }
156
        // Проверяем существование файла.
157
       $res =  ($res && file_exists($upd_file));
158
        if (!$res){
159
            $this->sendError(404, 'Update file not found.');
160
        }
161
        return $res;
162
163
    }
164
165
    /**
166
     * Categorize and store uploaded audio files
167
     * @return bool
168
     */
169
    private function uploadAudioFile():bool
170
    {
171
        $category = $this->request->getPost('category');
172
        $di       = Di::getDefault();
173
        $mediaDir = $di->getShared('config')->path('asterisk.mediadir');
174
        $mohDir   = $di->getShared('config')->path('asterisk.mohdir');
175
        foreach ($this->request->getUploadedFiles() as $file) {
176
            switch ($category) {
177
                case SoundFiles::CATEGORY_MOH:
178
                    $filename = "{$mohDir}/" . basename($file->getName());
179
                    break;
180
                case SoundFiles::CATEGORY_CUSTOM:
181
                    $filename = "{$mediaDir}/" . basename($file->getName());
182
                    break;
183
                default:
184
                    $this->sendError(400, 'Category not set');
185
                    return false;
186
            }
187
            $data['uploadedBlob'] = $file->getTempName();
188
            $data['filename']     = $filename;
189
        }
190
       return true;
191
    }
192
193
    /**
194
     * Upload extension module, or download it from internet if only url was sent
195
     */
196
    private function uploadNewModule()
197
    {
198
        if ($this->request->hasFiles() === 0) {
199
            if (Util::isJson($this->request->getRawBody())) {
200
                $row_data = $this->request->getRawBody();
201
                $data     = json_decode($row_data, true);
202
            } else {
203
                $this->sendError(400, 'Body is not JSON');
204
                return false;
205
            }
206
        } else {
207
            $tempDir     = $this->config->path('core.tempPath');
0 ignored issues
show
Bug Best Practice introduced by
The property config does not exist on MikoPBX\PBXCoreREST\Cont...s\System\PostController. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug introduced by
The method path() 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

207
            /** @scrutinizer ignore-call */ 
208
            $tempDir     = $this->config->path('core.tempPath');

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...
208
            $module_file = "{$tempDir}/" . time() . '.zip';
209
            if ($this->request->hasFiles() > 0) {
210
                foreach ($this->request->getUploadedFiles() as $file) {
211
                    $extension = Util::getExtensionOfFile($file->getName());
212
                    if ($extension !== 'zip') {
213
                        continue;
214
                    }
215
                    $file->moveTo($module_file);
216
                    break;
217
                }
218
            }
219
            if (file_exists($module_file)) {
220
                $cmd = 'f="' . $module_file . '"; p=`7za l $f | grep module.json`;if [ "$?" == "0" ]; then 7za -so e -y -r $f `echo $p |  awk -F" " \'{print $6}\'`; fi';
221
                Util::mwExec($cmd, $out);
222
                $settings = json_decode(implode("\n", $out), true);
223
224
                $module_uniqid = $settings['module_uniqid'] ?? null;
225
                if ( ! $module_uniqid) {
226
                    $this->sendError(400, 'The" module_uniqid " in the module file is not described.the json or file does not exist.');
227
                }
228
                $data = [
229
                    'md5'    => md5_file($module_file),
230
                    'url'    => "file://{$module_file}",
231
                    'l_file' => $module_file,
232
                    'uniqid' => $module_uniqid,
233
                ];
234
            } else {
235
                $this->sendError(500, 'Failed to upload file to server');
236
                return false;
237
            }
238
        }
239
        return $data;
240
    }
241
}