Passed
Push — develop ( d5179e...bede24 )
by Портнов
05:56 queued 11s
created

WorkerCallEvents::hangupChanCheckSipTrtansfer()   C

Complexity

Conditions 14
Paths 37

Size

Total Lines 54
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 37
c 2
b 0
f 0
dl 0
loc 54
rs 6.2666
cc 14
nc 37
nop 2

How to fix   Long Method    Complexity   

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 (C) 2017-2020 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\Core\Workers;
21
require_once 'Globals.php';
22
23
use MikoPBX\Core\System\{BeanstalkClient, MikoPBXConfig, Storage, Util};
24
use MikoPBX\Core\Workers\Libs\WorkerCallEvents\SelectCDR;
25
use MikoPBX\Core\Workers\Libs\WorkerCallEvents\UpdateDataInDB;
26
use Phalcon\Text;
27
28
class WorkerCallEvents extends WorkerBase
29
{
30
    public    array $mixMonitorChannels = [];
31
    protected bool  $record_calls       = true;
32
    protected bool  $split_audio_thread = false;
33
    public    array $checkChanHangupTransfer = [];
34
35
    /**
36
     * Инициирует запись разговора на канале.
37
     *
38
     * @param string    $channel
39
     * @param ?string   $file_name
40
     * @param ?string   $sub_dir
41
     * @param ?string   $full_name
42
     *
43
     * @return string
44
     */
45
    public function MixMonitor($channel, $file_name = null, $sub_dir = null, $full_name = null): string
46
    {
47
        $resFile = $this->mixMonitorChannels[$channel]??'';
48
        if($resFile !== ''){
49
            return $resFile;
50
        }
51
        $resFile           = '';
52
        $file_name = str_replace('/', '_', $file_name);
53
        if ($this->record_calls) {
54
            [$f, $options] = $this->setMonitorFilenameOptions($full_name, $sub_dir, $file_name);
55
            $arr = $this->am->GetChannels(false);
56
            if(!in_array($channel, $arr, true)){
57
                return '';
58
            }
59
            $srcFile = "{$f}.wav";
60
            $resFile = "{$f}.mp3";
61
            $this->am->MixMonitor($channel, $srcFile, $options);
62
            $this->mixMonitorChannels[$channel] = $resFile;
63
            $this->am->UserEvent('StartRecording', ['recordingfile' => $resFile, 'recchan' => $channel]);
64
        }
65
        return $resFile;
66
    }
67
68
    /**
69
     * @param string|null $full_name
70
     * @param string|null $sub_dir
71
     * @param string|null $file_name
72
     * @return array
73
     */
74
    public function setMonitorFilenameOptions(?string $full_name, ?string $sub_dir, ?string $file_name): array{
75
        if (!file_exists($full_name)) {
0 ignored issues
show
Bug introduced by
It seems like $full_name can also be of type null; however, parameter $filename of file_exists() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

75
        if (!file_exists(/** @scrutinizer ignore-type */ $full_name)) {
Loading history...
76
            $monitor_dir = Storage::getMonitorDir();
77
            if ($sub_dir === null) {
78
                $sub_dir = date('Y/m/d/H/');
79
            }
80
            $f = "{$monitor_dir}/{$sub_dir}{$file_name}";
81
        } else {
82
            $f = Util::trimExtensionForFile($full_name);
83
        }
84
        if ($this->split_audio_thread) {
85
            $options = "abSr({$f}_in.wav)t({$f}_out.wav)";
86
        } else {
87
            $options = 'ab';
88
        }
89
        return array($f, $options);
90
    }
91
92
    /**
93
     * Останавливает запись разговора на канале.
94
     * @param string $channel
95
     */
96
    public function StopMixMonitor($channel): void
97
    {
98
        if(isset($this->mixMonitorChannels[$channel])){
99
            unset($this->mixMonitorChannels[$channel]);
100
        }else{
101
            return;
102
        }
103
        if ($this->record_calls) {
104
            $this->am->StopMixMonitor($channel);
105
        }
106
    }
107
108
    /**
109
     *
110
     * @param $params
111
     */
112
    public function start($params): void
113
    {
114
        $this->mixMonitorChannels       = [];
115
        $this->checkChanHangupTransfer  = [];
116
        $mikoPBXConfig            = new MikoPBXConfig();
117
        $this->record_calls       = $mikoPBXConfig->getGeneralSettings('PBXRecordCalls') === '1';
118
        $this->split_audio_thread = $mikoPBXConfig->getGeneralSettings('PBXSplitAudioThread') === '1';
119
        $this->am                 = Util::getAstManager('off');
120
121
        // PID сохраняем при начале работы Worker.
122
        $client = new BeanstalkClient(self::class);
123
        $client->subscribe(self::class, [$this, 'callEventsWorker']);
124
        $client->subscribe(WorkerCdr::SELECT_CDR_TUBE, [$this, 'selectCDRWorker']);
125
        $client->subscribe(WorkerCdr::UPDATE_CDR_TUBE, [$this, 'updateCDRWorker']);
126
        $client->subscribe($this->makePingTubeName(self::class), [$this, 'pingCallBack']);
127
        $client->setErrorHandler([$this, 'errorHandler']);
128
129
        while ($this->needRestart === false) {
130
            $client->wait();
131
        }
132
    }
133
134
    /**
135
     * Обработчик событий изменения состояния звонка.
136
     *
137
     * @param array | BeanstalkClient $tube
138
     */
139
    public function callEventsWorker($tube): void
140
    {
141
        $data      = json_decode($tube->getBody(), true);
142
        $funcName = "Action_".$data['action']??'';
143
        if ( method_exists($this, $funcName) ) {
144
            $this->$funcName($data);
145
        }
146
        $className = __NAMESPACE__.'\Libs\WorkerCallEvents\\'.Text::camelize($funcName, '_');
147
        if( method_exists($className, 'execute') ){
148
            $className::execute($this, $data);
149
        }
150
151
        $tube->reply(json_encode(true));
152
    }
153
154
    /**
155
     * Получения CDR к обработке.
156
     *
157
     * @param array | BeanstalkClient $tube
158
     */
159
    public function updateCDRWorker($tube): void
160
    {
161
        $q    = $tube->getBody();
162
        $data = json_decode($q, true);
163
        UpdateDataInDB::execute($data);
164
        $tube->reply(json_encode(true));
165
    }
166
167
    /**
168
     * @param array | BeanstalkClient $tube
169
     */
170
    public function selectCDRWorker($tube): void
171
    {
172
        $filter   = json_decode($tube->getBody(), true);
173
        $res_data = SelectCDR::execute($filter);
174
        $tube->reply($res_data);
175
    }
176
177
    public function errorHandler($m): void
178
    {
179
        Util::sysLogMsg(self::class . '_ERROR', $m, LOG_ERR);
180
    }
181
}
182
183
184
// Start worker process
185
WorkerCallEvents::startWorker($argv??null);