Passed
Push — develop ( cfa396...74c300 )
by Nikolay
06:43 queued 11s
created

UpdateConfigsUpToVer20202730::processUpdate()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 9
c 1
b 0
f 0
dl 0
loc 13
rs 9.9666
cc 2
nc 2
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, 10 2020
7
 *
8
 */
9
10
namespace MikoPBX\Core\System\Upgrade\Releases;
11
12
use MikoPBX\Common\Models\Codecs;
13
use MikoPBX\Common\Models\Extensions;
14
use MikoPBX\Common\Models\SoundFiles;
15
use MikoPBX\Core\System\MikoPBXConfig;
16
use MikoPBX\Core\System\Upgrade\UpgradeSystemConfigInterface;
17
use MikoPBX\Core\System\Util;
18
use Phalcon\Config as ConfigAlias;
19
use Phalcon\Di\Injectable;
20
21
class UpdateConfigsUpToVer20202730 extends Injectable implements UpgradeSystemConfigInterface
22
{
23
    public const PBX_VERSION = '2020.2.730';
24
25
    private ConfigAlias $config;
26
27
    private MikoPBXConfig $mikoPBXConfig;
28
29
    private bool $isLiveCD;
30
31
    /**
32
     * Class constructor.
33
     */
34
    public function __construct()
35
    {
36
        $this->config = $this->getDI()->getShared('config');
37
        $this->mikoPBXConfig = new MikoPBXConfig();
38
        $this->isLiveCD =  file_exists('/offload/livecd');
39
    }
40
41
    public function processUpdate():void
42
    {
43
        if ($this->isLiveCD){
44
            return;
45
        }
46
47
        $this->deleteOrphanCodecs();
48
        $this->addCustomCategoryToSoundFiles();
49
        $this->cleanAstDB();
50
        $this->copyMohFilesToStorage();
51
        $this->removeOldCacheFolders();
52
        $this->updateExtensionsTable();
53
        $this->moveReadOnlySoundsToStorage();
54
    }
55
56
    /**
57
     * Deletes all not actual codecs
58
     */
59
    private function deleteOrphanCodecs()
60
    {
61
        $availCodecs = [
62
            // Видео кодеки.
63
            'h263p' => 'H.263+',
64
            'h263'  => 'H.263',
65
            'h264'  => 'H.264',
66
67
            // Аудио кодеки
68
            'adpcm' => 'ADPCM',
69
            'alaw'  => 'G.711 A-law',
70
            'ulaw'  => 'G.711 µ-law',
71
            'g719'  => 'G.719',
72
            'g722'  => 'G.722',
73
            'g726'  => 'G.726',
74
            'gsm'   => 'GSM',
75
            'ilbc'  => 'ILBC',
76
            'lpc10' => 'LPC-10',
77
            'speex' => 'Speex',
78
            'slin'  => 'Signed Linear PCM',
79
            'opus'  => 'Opus',
80
        ];
81
        $codecs = Codecs::find();
82
83
        // Удалим лишние кодеки
84
        /** @var \MikoPBX\Common\Models\Codecs $codec */
85
        foreach ($codecs as $codec){
86
            if(array_key_exists($codec->name, $availCodecs)){
87
                continue;
88
            }
89
            if(!$codec->delete()){
90
                Util::sysLogMsg(__CLASS__, 'Can not delete codec '.$codec->name. ' from MikoPBX\Common\Models\Codecs');
91
            }
92
        }
93
94
        foreach ($availCodecs as $availCodec => $desc){
95
            $codecData = Codecs::findFirst('name="'.$availCodec.'"');
96
            if ($codecData === null) {
97
                $codecData              = new Codecs();
98
            }elseif($codecData->description === $desc){
99
                unset($codecData);
100
                continue;
101
            }
102
            $codecData->name        = $availCodec;
103
            if(substr($availCodec,0,3) === 'h26'){
104
                $type = 'video';
105
            }else{
106
                $type = 'audio';
107
            }
108
            $codecData->type        = $type;
109
            $codecData->description = $desc;
110
            if(!$codecData->save()){
111
                Util::sysLogMsg(__CLASS__, 'Can not update codec info '.$codecData->name. ' from \MikoPBX\Common\Models\Codecs');
112
            }
113
        }
114
    }
115
116
    /**
117
     * Updates category attribute on SoundFiles table
118
     * Add custom category to all sound files
119
     */
120
    private function addCustomCategoryToSoundFiles()
121
    {
122
        $soundFiles = SoundFiles::find();
123
        foreach ($soundFiles as $sound_file) {
124
            $sound_file->category = SoundFiles::CATEGORY_CUSTOM;
125
            $sound_file->update();
126
        }
127
    }
128
129
    /**
130
     * Clean UserBuddyStatus on AstDB
131
     */
132
    private function cleanAstDB()
133
    {
134
        $astDbPath = $this->config->path('astDatabase.dbfile');
135
        if(file_exists($astDbPath)){
136
            $table = 'astdb';
137
            $sql = 'DELETE FROM '.$table.' WHERE key LIKE "/DND/SIP%" OR key LIKE "/CF/SIP%" OR key LIKE "/UserBuddyStatus/SIP%"';
138
            $db = new \SQLite3($astDbPath);
139
            try {
140
                $db->exec($sql);
141
            } catch (\Error $e) {
142
                Util::sysLogMsg(__CLASS__, 'Can clean astdb from UserBuddyStatus...'.$e->getMessage());
143
                sleep(2);
144
            }
145
            $db->close();
146
            unset($db);
147
        }
148
    }
149
150
    /**
151
     * Copies MOH sound files to storage and creates record on SoundFiles table
152
     */
153
    private function copyMohFilesToStorage():void
154
    {
155
        $oldMohDir     = $this->config->path('asterisk.astvarlibdir') . '/sounds/moh';
156
        if(!file_exists($oldMohDir)){
157
            return;
158
        }
159
        $currentMohDir = $this->config->path('asterisk.mohdir');
160
        if ( ! Util::mwMkdir($currentMohDir)) {
161
            return;
162
        }
163
164
        $files = scandir($oldMohDir);
165
        foreach ($files as $file) {
166
            if (in_array($file, ['.', '..'])) {
167
                continue;
168
            }
169
            if (copy($oldMohDir . '/' . $file, $currentMohDir . '/' . $file)) {
170
                $sound_file           = new SoundFiles();
171
                $sound_file->path     = $currentMohDir . '/' . $file;
172
                $sound_file->category = SoundFiles::CATEGORY_MOH;
173
                $sound_file->name     = $file;
174
                $sound_file->save();
175
            }
176
        }
177
    }
178
179
    /**
180
     * Remove old cache folders
181
     */
182
    private function removeOldCacheFolders():void
183
    {
184
        $mediaMountPoint = $this->config->path('core.mediaMountPoint');
185
        $oldCacheDirs    = [
186
            "$mediaMountPoint/mikopbx/cache_js_dir",
187
            "$mediaMountPoint/mikopbx/cache_img_dir",
188
            "$mediaMountPoint/mikopbx/cache_css_dir",
189
        ];
190
        foreach ($oldCacheDirs as $old_cache_dir) {
191
            if (is_dir($old_cache_dir)) {
192
                $rmPath = Util::which('rm');
193
                Util::mwExec("{$rmPath} -rf $old_cache_dir");
194
            }
195
        }
196
    }
197
    /**
198
     * Updates show_in_phonebook attribute on Extensions table
199
     */
200
    private function updateExtensionsTable():void
201
    {
202
        $showInPhonebookTypes=[
203
            Extensions::TYPE_DIALPLAN_APPLICATION,
204
            Extensions::TYPE_SIP,
205
            Extensions::TYPE_EXTERNAL,
206
            Extensions::TYPE_QUEUE,
207
            Extensions::TYPE_IVR_MENU,
208
            Extensions::TYPE_CONFERENCE,
209
210
        ];
211
        $extensions = Extensions::find();
212
        foreach ($extensions as $extension){
213
            if (in_array($extension->type, $showInPhonebookTypes)){
214
                $extension->show_in_phonebook='1';
215
                $extension->update();
216
            }
217
        }
218
    }
219
220
    /**
221
     * Moves predefined sound files to storage disk
222
     * Changes SoundFiles records
223
     */
224
    private function moveReadOnlySoundsToStorage():void
225
    {
226
        $currentMediaDir = $this->config->path('asterisk.customSoundDir').'/';
227
        if (!is_dir($currentMediaDir)){
228
            Util::mwMkdir($currentMediaDir);
229
        }
230
        $soundFiles = SoundFiles::find();
231
        foreach ($soundFiles as $soundFile){
232
            if (stripos($soundFile->path, '/offload/asterisk/sounds/other/')===0){
233
                $newPath = $currentMediaDir.pathinfo($soundFile->path)['basename'];
234
                if (copy($soundFile->path, $newPath)) {
235
                    $soundFile->path = $newPath;
236
                    $soundFile->update();
237
                }
238
            }
239
        }
240
    }
241
}