Passed
Push — develop ( 75092d...34130d )
by Портнов
04:55
created

VoiceMailConf::getIncludeInternal()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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