Passed
Push — develop ( 0cacf0...905a46 )
by Портнов
05:08
created

VoiceMailConf::getToMail()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 20
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 13
c 0
b 0
f 0
dl 0
loc 20
rs 9.8333
cc 3
nc 3
nop 1
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\Asterisk\Configs;
21
22
use MikoPBX\Common\Models\CallDetailRecordsTmp;
23
use MikoPBX\Common\Providers\CDRDatabaseProvider;
24
use MikoPBX\Core\System\Processes;
25
use MikoPBX\Core\System\Storage;
26
use MikoPBX\Core\System\Util;
27
use MikoPBX\Common\Models\Extensions;
28
use MikoPBX\Common\Models\Sip;
29
use MikoPBX\Common\Models\Users;
30
use Phalcon\Di;
31
use Phalcon\Mvc\Model\Manager;
32
33
class VoiceMailConf extends CoreConfigClass
34
{
35
    public const VOICE_MAIL_EXT = 'voicemail';
36
    protected string $description = 'voicemail.conf';
37
38
    /**
39
     * Prepares additional contexts sections in the extensions.conf file
40
     *
41
     * @return string
42
     */
43
    public function extensionGenContexts(): string
44
    {
45
        $conf  = "[voice_mail_peer] \n";
46
        $conf .= 'exten => '.self::VOICE_MAIL_EXT.',1,Answer()' . "\n\t";
47
        $conf .= 'same => n,ExecIf($["${CHANNEL:0:5}" == "Local"]?Set(pl=${IF($["${CHANNEL:-1}" == "1"]?2:1)}))' . "\n\t";
48
        $conf .= 'same => n,ExecIf($["${CHANNEL:0:5}" == "Local"]?Set(bridgePeer=${IMPORT(${CUT(CHANNEL,\;,1)}\;${pl},BRIDGEPEER)}))' . "\n\t";
49
        $conf .= 'same => n,ExecIf($[ "${FROM_CHAN}" == "${bridgePeer}" ]?ChannelRedirect(${bridgePeer},${CONTEXT},${EXTEN},2))' . "\n\t";
50
        $conf .= 'same => n,AGI(/usr/www/src/Core/Asterisk/agi-bin/clean_timeout.php)' . "\n\t";
51
        $conf .= 'same => n,Gosub(voicemail_start,${EXTEN},1)' . "\n\t";
52
        $conf .= 'same => n,VoiceMail(admin@voicemailcontext)' . "\n\t";
53
        $conf .= 'same => n,Hangup()' . "\n\n";
54
55
        return  $conf;
56
    }
57
58
    protected function generateConfigProtected(): void
59
    {
60
        // Уважаемый ${VM_NAME}:\n\n\tВам пришло новое голосовое сообщение длиной ${VM_DUR}
61
        // под номером (number ${VM_MSGNUM})\nв ящик ${VM_MAILBOX} от ${VM_CALLERID}, в ${VM_DATE}. \n\t
62
        $emailsubject = $this->generalSettings['MailTplVoicemailSubject'];
63
        $emailsubject = str_replace(["\n", "\t"], '', $emailsubject);
64
65
        $emailbody = $this->generalSettings['MailTplVoicemailBody'];
66
        $emailbody = str_replace(["\n", "\t"], ['\n', ''], $emailbody);
67
68
        $emailfooter = $this->generalSettings['MailTplVoicemailFooter'];
69
        $emailfooter = str_replace(["\n", "\t"], ['\n', ''], $emailfooter);
70
71
        $from = $this->generalSettings['MailSMTPSenderAddress'];
72
        if (empty($from)) {
73
            $from =  $this->generalSettings['MailSMTPUsername'];
74
        }
75
76
        $timezone = $this->generalSettings['PBXTimezone'];
77
        $msmtpPath = Util::which('voicemail-sender');
78
79
        $conf     = "[general]\n" .
80
            "format=wav\n" .
81
            "attach=yes\n" .
82
            "maxmsg=100\n" .
83
            "maxsecs=120\n" .
84
            "maxgreet=60\n" .
85
            "maxsilence=10\n" .
86
            "silencethreshold=128\n" .
87
            "maxlogins=3\n" .
88
            "moveheard=yes\n" .
89
            "charset=UTF-8\n" .
90
            "pbxskip=yes\n" .
91
            "fromstring=VoiceMail\n" .
92
            "emailsubject={$emailsubject}\n" .
93
            "emailbody={$emailbody}".'\n\n'."{$emailfooter}\n" .
94
            "emaildateformat=%A, %d %B %Y в %H:%M:%S\n" .
95
            "pagerdateformat=%T %D\n" .
96
            "mailcmd={$msmtpPath}\n" .
97
            "serveremail={$from}\n\n" .
98
            "[zonemessages]\n" .
99
            "local={$timezone}|'vm-received' q 'digits/at' H 'hours' M 'minutes'\n\n";
100
101
        $conf .= "[voicemailcontext]\n";
102
103
        $mail_box = $this->generalSettings['VoicemailNotificationsEmail'];
104
        if (empty($mail_box)) {
105
            $mail_box = $this->generalSettings['SystemNotificationsEmail'];
106
        }
107
        $conf .= "admin => admin," . Util::translate("user") . ",{$mail_box},,attach=yes|tz=local|delete=yes\n";
108
        Util::fileWriteContent($this->config->path('asterisk.astetcdir') . '/voicemail.conf', $conf);
109
    }
110
111
    /**
112
     * @param      $srcFileName
113
     * @param      $linkedId
114
     * @param      $time
115
     * @param bool $copy
116
     * @return string
117
     */
118
    public static function getCopyFilename($srcFileName, $linkedId, $time, bool $copy = true):string{
119
        $filename = Util::trimExtensionForFile($srcFileName) . '.wav';
120
        $recordingFile = '';
121
        // Переопределим путь к файлу записи разговора. Для конференции файл один.
122
        $monitor_dir = Storage::getMonitorDir();
123
        $sub_dir     = date('Y/m/d', $time);
124
        $dirName = "$monitor_dir/$sub_dir/INBOX/";
125
        if(Util::mwMkdir($dirName)){
126
            $recordingFile = $dirName.$linkedId.'.wav';
127
            $cpPath = Util::which('cp');
128
            if($copy === true){
129
                Processes::mwExec("{$cpPath} {$filename} {$recordingFile}");
130
            }
131
            if($copy === true && !file_exists($recordingFile)){
132
                $recordingFile = '';
133
            }else{
134
                $recordingFile = Util::trimExtensionForFile($recordingFile) . '.mp3';
135
            }
136
        }
137
        return $recordingFile;
138
    }
139
140
    /**
141
     * Возвращает список пользователей VM.
142
     * @return array
143
     */
144
    public static function getUsersVM():array
145
    {
146
        $di = Di::getDefault();
147
        if(!$di){
148
            return [];
149
        }
150
        /** @var Manager $manager */
151
        $manager = $di->get('modelsManager');
152
        $parameters = [
153
            'models'     => [
154
                'Sip' => Sip::class,
155
            ],
156
            'conditions' => 'Sip.type = :type: AND Users.email <> ""',
157
            'bind'       => ['type' => 'peer'],
158
            'columns'    => [
159
                'extension'      => 'Sip.extension',
160
                'email'          => 'Users.email',
161
                'username'       => 'Users.username',
162
            ],
163
            'order'      => 'Sip.extension',
164
            'joins'      => [
165
                'Extensions' => [
166
                    0 => Extensions::class,
167
                    1 => 'Sip.extension = Extensions.number',
168
                    2 => 'Extensions',
169
                    3 => 'LEFT',
170
                ],
171
                'Users' => [
172
                    0 => Users::class,
173
                    1 => 'Users.id = Extensions.userid',
174
                    2 => 'Users',
175
                    3 => 'INNER',
176
                ]
177
            ],
178
        ];
179
        $query  = $manager->createBuilder($parameters)->getQuery();
180
        $result = $query->execute()->toArray();
181
        $mails = [];
182
        foreach ($result as $data){
183
            if(empty($data['email'])){
184
                continue;
185
            }
186
            $mails[$data['extension']] = $data;
187
        }
188
        return $mails;
189
    }
190
191
    /**
192
     * Возвращает все
193
     * @param $linkedId
194
     * @return array
195
     */
196
    public static function getToMail($linkedId):array
197
    {
198
        $toMails  = [];
199
        $allMails = self::getUsersVM();
200
        $filter         = [
201
            'linkedid=:linkedid: AND disposition <> "ANSWERED"',
202
            'bind' => [
203
                'linkedid' => $linkedId,
204
            ],
205
            'columns' => 'dst_num'
206
        ];
207
        $m_data = CDRDatabaseProvider::getTempCdr($filter);
208
        foreach ($m_data as $row){
209
            $mailData = $allMails[$row['dst_num']]??false;
210
            if($mailData){
211
                $toMails[] = $mailData['email'];
212
            }
213
        }
214
215
        return $toMails;
216
    }
217
218
}