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

CreateRowTransfer   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 139
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 28
eloc 68
c 1
b 0
f 0
dl 0
loc 139
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A initCallsData() 0 13 2
A execute() 0 13 4
B fillRedirectCdrData() 0 45 7
C fillFailRedirectCdrData() 0 30 12
A isFailRedirect() 0 3 3
1
<?php
2
3
4
namespace MikoPBX\Core\Workers\Libs\WorkerCallEvents;
5
6
7
use MikoPBX\Common\Models\CallDetailRecordsTmp;
8
use MikoPBX\Core\System\Util;
9
use MikoPBX\Core\Workers\WorkerCallEvents;
10
11
class CreateRowTransfer {
12
13
    public static function execute(WorkerCallEvents $worker, $action, $data, $calls_data = null):void
14
    {
15
        if( isset($worker->checkChanHangupTransfer[$data['agi_channel']]) ) {
16
            return;
17
        }
18
        $worker->checkChanHangupTransfer[$data['agi_channel']] = $action;
19
        self::initCallsData($data,$calls_data);
20
        if (count($calls_data) === 2) {
21
            // Это нормальная переадресация
22
            self::fillRedirectCdrData($worker, $action, $data, $calls_data);
23
        } elseif (self::isFailRedirect($calls_data)) {
24
            // Неудачная переадресация.
25
            self::fillFailRedirectCdrData($worker, $data, $calls_data);
26
        }
27
    }
28
29
    /**
30
     * Проверка на обрыв переадресации.
31
     * @param $calls_data
32
     * @return bool
33
     */
34
    private static function isFailRedirect($calls_data):bool
35
    {
36
        return empty($calls_data[0]['answer']) && count($calls_data) === 1 && ! empty($calls_data[0]['recordingfile']);
37
    }
38
39
    /**
40
     * Обработка обрыва переадресации.
41
     * @param $worker
42
     * @param $data
43
     * @param $calls_data
44
     */
45
    private static function fillFailRedirectCdrData($worker, $data, $calls_data):void
46
    {
47
        // Возобновление записи разговора при срыве переадресации.
48
        $row_data = $calls_data[0];
49
        $chan     = ($data['agi_channel'] === $row_data['src_chan']) ? $row_data['dst_chan'] : $row_data['src_chan'];
50
        $filter   = [
51
            'linkedid=:linkedid: AND endtime = ""',
52
            'bind'  => [
53
                'linkedid' => $data['linkedid'],
54
            ],
55
            'order' => 'is_app',
56
        ];
57
        /** @var CallDetailRecordsTmp $not_ended_cdr */
58
        $cdr = CallDetailRecordsTmp::find($filter);
59
        /** @var CallDetailRecordsTmp $row */
60
        $not_ended_cdr = null;
61
        $transferNotComplete = false;
62
        foreach ($cdr as $row){
63
            if($row->transfer === '1' && ($row->src_chan === $chan || $row->dst_chan === $chan) ){
64
                $not_ended_cdr = $row;
65
            }
66
            if($row->answer === '' && $row->endtime === ''
67
                && ($row->src_chan === $chan || $row->dst_chan === $chan) ){
68
                $transferNotComplete = true;
69
            }
70
        }
71
72
        if ($not_ended_cdr !== null && !$transferNotComplete) {
73
            $worker->StopMixMonitor($not_ended_cdr->src_chan);
74
            $worker->MixMonitor($not_ended_cdr->dst_chan, '', '', $not_ended_cdr->recordingfile);
75
        }
76
    }
77
78
    /**
79
     * Обработка нормальной переадресации.
80
     * @param $worker
81
     * @param $action
82
     * @param $data
83
     * @param $calls_data
84
     */
85
    private static function fillRedirectCdrData($worker, $action, $data, $calls_data):void
86
    {
87
        $insert_data = [];
88
        foreach ($calls_data as $row_data) {
89
            if ($row_data['src_chan'] === $data['agi_channel']) {
90
                $fname_chan = isset($insert_data['dst_chan']) ? 'src_chan' : 'dst_chan';
91
                $fname_num  = isset($insert_data['dst_num']) ? 'src_num' : 'dst_num';
92
93
                $insert_data[$fname_chan] = $row_data['dst_chan'];
94
                $insert_data[$fname_num]  = $row_data['dst_num'];
95
            } else {
96
                $fname_chan = ! isset($insert_data['src_chan']) ? 'src_chan' : 'dst_chan';
97
                $fname_num  = ! isset($insert_data['src_num']) ? 'src_num' : 'dst_num';
98
99
                $insert_data[$fname_chan] = $row_data['src_chan'];
100
                $insert_data[$fname_num]  = $row_data['src_num'];
101
            }
102
        }
103
        // Запись разговора.
104
        $worker->StopMixMonitor($insert_data['src_chan']);
105
        $worker->StopMixMonitor($insert_data['dst_chan']);
106
        $recordingfile = $worker->MixMonitor(
107
            $insert_data['dst_chan'],
108
            'transfer_' . $insert_data['src_num'] . '_' . $insert_data['dst_num'] . '_' . $data['linkedid']
109
        );
110
        //
111
        $insert_data['action']        = "{$action}_end_trasfer";
112
        $insert_data['recordingfile'] = $recordingfile;
113
        $insert_data['start']         = $data['end'];
114
        $insert_data['answer']        = $data['end'];
115
        $insert_data['linkedid']      = $data['linkedid'];
116
        $insert_data['UNIQUEID']      = $data['agi_threadid'];
117
        $insert_data['did']           = $data['did'];
118
        $insert_data['transfer']      = '0';
119
120
        /**
121
         * Отправка UserEvent
122
         */
123
        $insert_data['action'] = 'transfer_dial_create_cdr';
124
125
        $AgiData               = base64_encode(json_encode($insert_data));
126
        $am = Util::getAstManager('off');
127
        $am->UserEvent('CdrConnector', ['AgiData' => $AgiData]);
128
129
        InsertDataToDB::execute($insert_data);
130
    }
131
132
    /**
133
     * Получает из базы данных строки истории звонков.
134
     * @param $data
135
     * @param $calls_data
136
     */
137
    private static function initCallsData($data, &$calls_data):void
138
    {
139
        if (null === $calls_data) {
140
            $filter     = [
141
                'linkedid=:linkedid: AND endtime = "" AND transfer=1 AND (src_chan=:chan: OR dst_chan=:chan:)',
142
                'bind'  => [
143
                    'linkedid' => $data['linkedid'],
144
                    'chan'     => $data['agi_channel'],
145
                ],
146
                'order' => 'is_app',
147
            ];
148
            $m_data     = CallDetailRecordsTmp::find($filter);
149
            $calls_data = $m_data->toArray();
150
        }
151
    }
152
153
}