Passed
Push — develop ( cdbcb8...3c7a50 )
by Nikolay
05:38 queued 10s
created

ProvidersController::updateAdditionalHosts()   B

Complexity

Conditions 7
Paths 13

Size

Total Lines 35
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 25
dl 0
loc 35
rs 8.5866
c 0
b 0
f 0
cc 7
nc 13
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\AdminCabinet\Controllers;
21
22
use MikoPBX\AdminCabinet\Forms\{IaxProviderEditForm, SipProviderEditForm};
23
use MikoPBX\Common\Models\{Iax, Providers, Sip, SipHosts};
24
25
class ProvidersController extends BaseController
26
{
27
28
    /**
29
     * Получение общего списка провайдеров
30
     */
31
    public function indexAction(): void
32
    {
33
        $providers     = Providers::find();
34
        $providersList = [];
35
        foreach ($providers as $provider) {
36
            $modelType       = ucfirst($provider->type);
37
            $provByType      = $provider->$modelType;
38
            $providersList[] = [
39
                'uniqid'     => $provByType->uniqid,
40
                'name'       => $provByType->description,
41
                'username'   => $provByType->username,
42
                'hostname'   => $provByType->host,
43
                'type'       => $provider->type,
44
                'status'     => $provByType->disabled ? 'disabled' : '',
45
                'existLinks' => $provider->OutgoingRouting->count() > 0 ? 'true' : 'false',
46
47
            ];
48
        }
49
        $this->view->providerlist = $providersList;
50
    }
51
52
53
    /**
54
     * Открытие карточки SIP провайдера и заполнение значений по умолчанию
55
     *
56
     * @param string $uniqid Уникальный идентификатор провайдера, если мы открываем существующего
57
     */
58
    public function modifysipAction(string $uniqid = ''): void
59
    {
60
        $provider = Providers::findFirstByUniqid($uniqid);
61
62
        if ($provider === null) {
63
            $uniqid                     = strtoupper('SIP-' . time());
64
            $provider                   = new Providers();
65
            $provider->type             = 'SIP';
66
            $provider->uniqid           = $uniqid;
67
            $provider->sipuid           = $uniqid;
68
            $provider->Sip              = new Sip();
69
            $provider->Sip->uniqid      = $uniqid;
70
            $provider->Sip->type        = 'friend';
71
            $provider->Sip->port        = 5060;
72
            $provider->Sip->disabled    = '0';
73
            $provider->Sip->qualifyfreq = 60;
74
            $provider->Sip->qualify     = '1';
75
        }
76
77
        $providerHost = $provider->Sip->host;
78
        $sipHosts   = $provider->Sip->SipHosts;
0 ignored issues
show
Bug Best Practice introduced by
The property SipHosts does not exist on MikoPBX\Common\Models\Sip. Since you implemented __get, consider adding a @property annotation.
Loading history...
79
        $hostsTable = [];
80
        foreach ($sipHosts as $host) {
81
            if ($providerHost !== $host->address){
82
                $hostsTable[] = $host->address;
83
            }
84
        }
85
        $this->view->hostsTable = $hostsTable;
86
        $this->view->form       = new SipProviderEditForm($provider->Sip);
87
        $this->view->represent  = $provider->getRepresent();
88
    }
89
90
    /**
91
     * Открытие карточки IAX провайдера и заполнение значений по умолчанию
92
     *
93
     * @param string $uniqid Уникальный идентификатор провайдера, если мы открываем существующего
94
     */
95
    public function modifyiaxAction(string $uniqid = ''): void
96
    {
97
        $provider = Providers::findFirstByUniqid($uniqid);
98
99
        if ($provider === null) {
100
            $uniqid                  = strtoupper('IAX-' . time());
101
            $provider                = new Providers();
102
            $provider->type          = 'IAX';
103
            $provider->uniqid        = $uniqid;
104
            $provider->iaxuid        = $uniqid;
105
            $provider->Iax           = new Iax();
106
            $provider->Iax->uniqid   = $uniqid;
107
            $provider->Iax->disabled = '0';
108
            $provider->Iax->qualify  = '1';
109
        }
110
111
        $this->view->form      = new IaxProviderEditForm($provider->Iax);
112
        $this->view->represent = $provider->getRepresent();
113
    }
114
115
    /**
116
     * Включение провайдера
117
     *
118
     * @param string $type   тип провайдера SIP или IAX
119
     * @param string $uniqid Уникальный идентификатор провайдера, если мы открываем существующего
120
     */
121
    public function enableAction(string $type, string $uniqid = ''): void
122
    {
123
        $this->view->success = false;
124
        switch ($type) {
125
            case 'iax':
126
            {
127
                $provider = Iax::findFirstByUniqid($uniqid);
128
                break;
129
            }
130
            case 'sip':
131
            {
132
                $provider = Sip::findFirstByUniqid($uniqid);
133
                break;
134
            }
135
            default:
136
                $provider = null;
137
        }
138
        if ($provider !== null) {
139
            $provider->disabled = '0';
140
            if ($provider->save() === true) {
141
                $this->view->success = true;
142
            }
143
        }
144
    }
145
146
    /**
147
     * Отключение провайдера
148
     *
149
     * @param string $type   тип провайдера SIP или IAX
150
     * @param string $uniqid Уникальный идентификатор провайдера, если мы открываем существующего
151
     */
152
    public function disableAction(string $type, string $uniqid = ''): void
153
    {
154
        $this->view->success = false;
155
        switch ($type) {
156
            case 'iax':
157
            {
158
                $provider = Iax::findFirstByUniqid($uniqid);
159
                break;
160
            }
161
            case 'sip':
162
            {
163
                $provider = Sip::findFirstByUniqid($uniqid);
164
                break;
165
            }
166
            default:
167
                $provider = null;
168
        }
169
        if ($provider !== null) {
170
            $provider->disabled = '1';
171
            if ($provider->save() === true) {
172
                $this->view->success = true;
173
            }
174
        }
175
    }
176
177
    /**
178
     * Saves provider over ajax request from a web form
179
     *
180
     * @param string $type - sip or iax
181
     *
182
     */
183
    public function saveAction(string $type): void
184
    {
185
        if ( ! $this->request->isPost()) {
186
            $this->forward('network/index');
187
        }
188
        $this->db->begin();
189
        $data = $this->request->getPost();
190
191
        // Updates SIP and IAX tables
192
        if ( ! $this->saveProvider($data, $type)) {
193
            $this->view->success = false;
194
            $this->db->rollback();
195
196
            return;
197
        }
198
199
        // Update additional hosts table
200
        if ( ! $this->updateAdditionalHosts($data)) {
201
            $this->view->success = false;
202
            $this->db->rollback();
203
204
            return;
205
        }
206
207
        $this->flash->success($this->translation->_('ms_SuccessfulSaved'));
208
        $this->view->success = true;
209
        $this->db->commit();
210
211
        // Если это было создание карточки то надо перегрузить страницу с указанием ID
212
        if (empty($data['id'])) {
213
            $this->view->reload = "providers/modify{$type}/{$data['uniqid']}";
214
        }
215
    }
216
217
    /**
218
     * Save providers data table
219
     *
220
     * @param array  $data - POST DATA
221
     * @param string $type - sip or iax
222
     *
223
     * @return bool save result
224
     */
225
    private function saveProvider(array $data, string $type): bool
226
    {
227
        // Проверим это новый провайдер или старый
228
        $provider = Providers::findFirstByUniqid($data['uniqid']);
229
        if ($provider === null) {
230
            $provider         = new Providers();
231
            $provider->uniqid = $data['uniqid'];
232
            switch ($type) {
233
                case 'iax':
234
                    $provider->iaxuid = $data['uniqid'];
235
                    $provider->type   = 'IAX';
236
                    $provider->Iax    = new Iax();
237
                    break;
238
                case 'sip':
239
                    $provider->sipuid = $data['uniqid'];
240
                    $provider->type   = 'SIP';
241
                    $provider->Sip    = new Sip();
242
                    break;
243
            }
244
        }
245
246
        if ($provider->save() === false) {
247
            $errors = $provider->getMessages();
248
            $this->flash->warning(implode('<br>', $errors));
249
            return false;
250
        }
251
252
        switch ($type) {
253
            case 'iax':
254
                $providerByType = $provider->Iax;
255
                break;
256
            case 'sip':
257
                $providerByType = $provider->Sip;
258
                break;
259
            default:
260
                $providerByType = [];
261
        }
262
263
        foreach ($providerByType as $name => $value) {
264
            switch ($name) {
265
                case 'id':
266
                    break;
267
                case 'qualify':
268
                case 'disablefromuser':
269
                case 'noregister':
270
                case 'receive_calls_without_auth':
271
                    if (array_key_exists($name, $data)) {
272
                        $providerByType->$name = ($data[$name] === 'on') ? 1 : 0;
273
                    } else {
274
                        $providerByType->$name = 0;
275
                    }
276
                    break;
277
                case 'manualattributes':
278
                    if (array_key_exists($name, $data)) {
279
                        $providerByType->setManualAttributes($data[$name]);
280
                    }
281
                    break;
282
                default:
283
                    if (array_key_exists($name, $data)) {
284
                        $providerByType->$name = $data[$name];
285
                    }
286
            }
287
        }
288
289
        if ($providerByType->save() === false) {
290
            $errors = $providerByType->getMessages();
291
            $this->flash->warning(implode('<br>', $errors));
292
293
            return false;
294
        }
295
296
        return true;
297
    }
298
299
    /**
300
     * Update additional hosts table
301
     *
302
     * @param array $data массив полей из POST запроса
303
     *
304
     * @return bool update result
305
     */
306
    private function updateAdditionalHosts(array $data): bool
307
    {
308
        $providerHost = $data['host'];
309
        $additionalHosts = json_decode($data['additionalHosts']);
310
        $hosts = array_merge([], $additionalHosts, [$providerHost]);
311
        $parameters=[
312
            'conditions'=>'provider_id = :providerId:',
313
            'bind'=>[
314
                'providerId'=>$data['uniqid']
315
            ]
316
        ];
317
        $currentRecords = SipHosts::find($parameters);
318
        foreach ($currentRecords as $record){
319
            if (!in_array($record->address, $hosts)){
320
                if ($record->delete() === false) {
321
                    $errors = $record->getMessages();
322
                    $this->flash->warning(implode('<br>', $errors));
323
                    return false;
324
                }
325
            } elseif (($key = array_search($record->address, $hosts)) !== false) {
326
                unset($hosts[$key]);
327
            }
328
        }
329
        foreach ($hosts as $record){
330
            $currentRecord = new SipHosts();
331
            $currentRecord->provider_id = $data['uniqid'];
332
            $currentRecord->address = $record;
333
            if ($currentRecord->save() === false) {
334
                $errors = $currentRecord->getMessages();
335
                $this->flash->warning(implode('<br>', $errors));
336
                return false;
337
            }
338
        }
339
340
        return true;
341
    }
342
343
    /**
344
     * Deletes provider record by unique id
345
     *
346
     * @param string $uniqid
347
     */
348
    public function deleteAction(string $uniqid = ''): void
349
    {
350
        if ($uniqid === '') {
351
            return;
352
        }
353
354
        $provider = Providers::findFirstByUniqid($uniqid);
355
        if ($provider === null) {
356
            return;
357
        }
358
359
        $this->db->begin();
360
        $errors = false;
361
        if ($provider->Iax) {
362
            $iax = $provider->Iax;
363
            if ( ! $iax->delete()) {
364
                $errors = $iax->getMessages();
365
            }
366
        }
367
368
        if ($errors === false && $provider->Sip) {
369
            $sip = $provider->Sip;
370
            if ($sip->SipHosts) {
371
                $sipHosts = $provider->SipHosts;
372
                if ( ! $sipHosts->delete()) {
373
                    $errors = $sipHosts->getMessages();
374
                }
375
            }
376
            if ($errors === false && ! $sip->delete()) {
377
                $errors = $sip->getMessages();
378
            }
379
        }
380
381
        if ($errors) {
382
            $this->flash->warning(implode('<br>', $errors));
383
            $this->db->rollback();
384
        } else {
385
            $this->db->commit();
386
        }
387
388
389
        $this->forward('providers/index');
390
    }
391
392
}