Passed
Push — develop ( 2c64b4...534ba1 )
by Nikolay
05:07
created

CallQueuesController::updateExtension()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 12
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 2
1
<?php
2
/**
3
 * Copyright (C) MIKO LLC - All Rights Reserved
4
 * Unauthorized copying of this file, via any medium is strictly prohibited
5
 * Proprietary and confidential
6
 * Written by Nikolay Beketov, 5 2018
7
 *
8
 */
9
10
namespace MikoPBX\AdminCabinet\Controllers;
11
12
use MikoPBX\AdminCabinet\Forms\CallQueueEditForm;
13
use MikoPBX\Common\Models\{CallQueueMembers, CallQueues, Extensions, SoundFiles};
14
15
class CallQueuesController extends BaseController
16
{
17
18
    /**
19
     * Получение списка очередей вызовово
20
     */
21
    public function indexAction(): void
22
    {
23
        $queues             = CallQueues::find();
24
        $this->view->queues = $queues;
25
    }
26
27
28
    /**
29
     * Карточка редактирования очереди
30
     *
31
     * @param string $uniqid - идентификатор редактируемой очереди
32
     */
33
    public function modifyAction(string $uniqid = ''): void
34
    {
35
        $queue            = CallQueues::findFirstByUniqid($uniqid);
36
        $queueMembersList = [];
37
        $soundfilesList   = [];
38
        $extensionList    = [];
39
        if ($queue === null) {
40
            $queue                              = new CallQueues();
41
            $queue->uniqid                      = Extensions::TYPE_QUEUE . strtoupper('-' . md5($queue->id . time()));
42
            $queue->caller_hear                 = 'moh';
43
            $queue->seconds_to_ring_each_member = 20;
44
            $queue->seconds_for_wrapup          = 15;
45
            $queue->announce_position           = 1;
46
            $queue->announce_hold_time          = 1;
47
            $queue->periodic_announce_frequency = 45;
48
            $queue->extension                   = Extensions::getNextFreeApplicationNumber();
49
        } else {
50
            // Списк экстеншенов очереди
51
            $parameters = [
52
                'order'      => 'priority',
53
                'conditions' => 'queue=:queue:',
54
                'bind'       => [
55
                    'queue' => $queue->uniqid,
56
                ],
57
            ];
58
            $members    = CallQueueMembers::find($parameters);
59
            foreach ($members as $member) {
60
                $queueMembersList[] = [
61
                    'id'       => $member->id,
62
                    'number'   => $member->extension,
63
                    'callerid' => $member->Extensions->getRepresent(),
64
                ];
65
            }
66
        }
67
68
        $extensionList[""] = $this->translation->_("ex_SelectNumber");
69
        // Список всех используемых эктеншенов
70
        $parameters = [
71
            'conditions' => 'number IN ({ids:array})',
72
            'bind'       => [
73
                'ids' => [
74
                    $queue->timeout_extension,
75
                    $queue->redirect_to_extension_if_empty,
76
                    $queue->redirect_to_extension_if_unanswered,
77
                    $queue->redirect_to_extension_if_repeat_exceeded,
78
                ],
79
            ],
80
        ];
81
        $extensions = Extensions::find($parameters);
82
        foreach ($extensions as $record) {
83
            $extensionList[$record->number] = $record->getRepresent();
84
        }
85
86
        // Список звуковых файлов для очередей
87
        $soundfilesList[""] = $this->translation->_("sf_SelectAudioFile");
88
        $soundfilesList[-1] = '-';
89
        $soundFiles         = SoundFiles::find('category="custom"');
90
        foreach ($soundFiles as $soundFile) {
91
            $soundfilesList[$soundFile->id] = $soundFile->name;
92
        }
93
94
        $form                        = new CallQueueEditForm(
95
            $queue, [
96
                      'extensions' => $extensionList,
97
                      'soundfiles' => $soundfilesList,
98
                  ]
99
        );
100
        $this->view->form            = $form;
101
        $this->view->extensionsTable = $queueMembersList;
102
        $this->view->represent       = $queue->getRepresent();
103
        $this->view->extension       = $queue->extension;
104
    }
105
106
107
    /**
108
     * Сохранение очереди через AJAX запрос из формы
109
     */
110
    public function saveAction(): void
111
    {
112
        if ( ! $this->request->isPost()) {
113
            return;
114
        }
115
        $this->db->begin();
116
117
        $data  = $this->request->getPost();
118
        $queue = CallQueues::findFirstByUniqid($data['uniqid']);
119
        if ($queue === null) {
120
            $queue                        = new CallQueues();
121
            $extension                    = new Extensions();
122
            $extension->type              = Extensions::TYPE_QUEUE;
123
            $extension->number            = $data["extension"];
124
            $extension->callerid          = $this->sanitizeCallerId($data["name"]);
125
            $extension->userid            = null;
126
            $extension->show_in_phonebook = 1;
127
            $extension->public_access     = 1;
128
        } else {
129
            $extension = $queue->Extensions;
130
        }
131
132
        // Заполним параметры внутреннего номера
133
        if ( ! $this->updateExtension($extension, $data)) {
134
            $this->view->success = false;
135
            $this->db->rollback();
136
137
            return;
138
        }
139
140
        // Заполним параметры пользователя
141
        if ( ! $this->updateQueue($queue, $data)) {
142
            $this->view->success = false;
143
            $this->db->rollback();
144
145
            return;
146
        }
147
148
        // Заполним параметры участников очереди
149
        if ( ! $this->updateQueueMembers($data)) {
150
            $this->view->success = false;
151
            $this->db->rollback();
152
153
            return;
154
        }
155
156
        $this->flash->success($this->translation->_('ms_SuccessfulSaved'));
157
        $this->view->success = true;
158
        $this->db->commit();
159
160
        // Если это было создание карточки то надо перегрузить страницу с указанием ID
161
        if (empty($data['id'])) {
162
            $this->view->reload = "call-queues/modify/{$data['uniqid']}";
163
        }
164
    }
165
166
    /**
167
     * Обновление параметров внутреннего номера
168
     *
169
     * @param \MikoPBX\Common\Models\Extensions $extension
170
     * @param array                             $data массив полей из POST запроса
171
     *
172
     * @return bool update result
173
     */
174
    private function updateExtension(Extensions $extension, array $data): bool
175
    {
176
        $extension->number   = $data['extension'];
177
        $extension->callerid = $this->sanitizeCallerId($data['name']);
178
        if ($extension->save() === false) {
179
            $errors = $extension->getMessages();
180
            $this->flash->error(implode('<br>', $errors));
181
182
            return false;
183
        }
184
185
        return true;
186
    }
187
188
    /**
189
     * Обновление параметров очереди
190
     *
191
     * @param \MikoPBX\Common\Models\CallQueues $queue
192
     * @param array                             $data массив полей из POST запроса
193
     *
194
     * @return bool update result
195
     */
196
    private function updateQueue(CallQueues $queue, array $data): bool
197
    {
198
        foreach ($queue as $name => $value) {
199
            switch ($name) {
200
                case "extension":
201
                case "name":
202
                    $queue->$name = $data[$name];
203
                    break;
204
                case "recive_calls_while_on_a_call":
205
                case "announce_position":
206
                case "announce_hold_time":
207
                    if (array_key_exists($name, $data)) {
208
                        $queue->$name = ($data[$name] == 'on') ? "1" : "0";
209
                    } else {
210
                        $queue->$name = "0";
211
                    }
212
                    break;
213
214
                case "periodic_announce_sound_id":
215
                case "redirect_to_extension_if_repeat_exceeded":
216
                case "redirect_to_extension_if_empty":
217
                    if ( ! array_key_exists($name, $data) || empty($data[$name])) {
218
                        $queue->$name = null;
219
                        continue 2;
220
                    }
221
                    $queue->$name = $data[$name];
222
223
                    break;
224
                case "timeout_to_redirect_to_extension":
225
                case "number_unanswered_calls_to_redirect":
226
                    if ( ! array_key_exists($name, $data)) {
227
                        continue 2;
228
                    }
229
                    if (empty($data[$name])) {
230
                        $queue->$name = null;
231
                    } else {
232
                        $queue->$name = $data[$name];
233
                    }
234
                    break;
235
                case "timeout_extension":
236
                    if ( ! array_key_exists($name, $data)
237
                        || empty($data[$name])
238
                        || (array_key_exists('timeout_to_redirect_to_extension', $data)
239
                            && intval($data['timeout_to_redirect_to_extension']) === 0)) {
240
                        $queue->$name = null;
241
                        continue 2;
242
                    }
243
                    $queue->$name = $data[$name];
244
245
                    break;
246
                case "redirect_to_extension_if_unanswered":
247
                    if ( ! array_key_exists($name, $data)
248
                        || empty($data[$name])
249
                        || (array_key_exists('number_unanswered_calls_to_redirect', $data)
250
                            && intval($data['number_unanswered_calls_to_redirect']) === 0)) {
251
                        $queue->$name = null;
252
                        continue 2;
253
                    }
254
                    $queue->$name = $data[$name];
255
256
                    break;
257
                default:
258
                    if ( ! array_key_exists($name, $data)) {
259
                        continue 2;
260
                    }
261
                    $queue->$name = $data[$name];
262
            }
263
        }
264
265
        if ($queue->save() === false) {
266
            $errors = $queue->getMessages();
267
            $this->flash->error(implode('<br>', $errors));
268
269
            return false;
270
        }
271
272
        return true;
273
    }
274
275
    /**
276
     * Обновление списка участников очереди
277
     *
278
     * @param array $data массив полей из POST запроса
279
     *
280
     * @return bool update result
281
     */
282
    private function updateQueueMembers(array $data): bool
283
    {
284
        $realMembers = [];
285
        // Обновим настройки у существующих членов очереди
286
        $membersTable = json_decode($data['members']);
287
        foreach ($membersTable as $member) {
288
            $parameters   = [
289
                'conditions' => 'extension = :number: AND queue=:uniqid:',
290
                'bind'       => [
291
                    'number' => $member->number,
292
                    'uniqid' => $data['uniqid'],
293
                ],
294
            ];
295
            $queueMembers = CallQueueMembers::find($parameters);
296
            if (is_countable($queueMembers) && count($queueMembers) > 1) {
297
                // откуда то взались лишние. Надо их всех удалить и создать нового
298
                if ($queueMembers->delete() === false) {
299
                    $errors = $queueMembers->getMessages();
300
                    $this->flash->error(implode('<br>', $errors));
301
302
                    return false;
303
                }
304
                $queueMember = new CallQueueMembers();
305
            } elseif (is_countable($queueMembers) && count($queueMembers) === 1) {
306
                $queueMember = $queueMembers->getFirst();
307
            } else {
308
                $queueMember = new CallQueueMembers();
309
            }
310
311
            $queueMember->priority  = $member->priority;
312
            $queueMember->extension = $member->number;
313
            $queueMember->queue     = $data['uniqid'];
314
            $realMembers[]          = $member->number;
315
            if ($queueMember->save() === false) {
316
                $errors = $queueMember->getMessages();
317
                $this->flash->error(implode('<br>', $errors));
318
319
                return false;
320
            }
321
        }
322
323
        // Удалим членов очереди которх нет в списке
324
        $parameters = [
325
            'conditions' => 'extension NOT IN  ({numbers:array}) AND queue=:uniqid:',
326
            'bind'       => [
327
                'numbers' => $realMembers,
328
                'uniqid'  => $data['uniqid'],
329
            ],
330
        ];
331
332
        $deletedMembers = CallQueueMembers::find($parameters);
333
        if ($deletedMembers && $deletedMembers->delete() === false) {
334
            $errors = $deletedMembers->getMessages();
335
            $this->flash->error(implode('<br>', $errors));
336
337
            return false;
338
        }
339
340
        return true;
341
    }
342
343
    /**
344
     * Удаление очереди по ее ID
345
     *
346
     * @param string $uniqid
347
     */
348
    public function deleteAction(string $uniqid = ''): void
349
    {
350
        if ($uniqid === '') {
351
            return;
352
        }
353
354
        $queue = CallQueues::findFirstByUniqid($uniqid);
355
        if ($queue === null) {
356
            return;
357
        }
358
        $errors = false;
359
360
        $this->db->begin();
361
        $extension = $queue->Extensions;
362
        if ( ! $extension->delete()) {
363
            $errors = $extension->getMessages();
364
        }
365
        if ($errors) {
366
            $this->flash->warning(implode('<br>', $errors));
367
            $this->db->rollback();
368
        } else {
369
            $this->db->commit();
370
        }
371
372
        $this->forward('call-queues/index');
373
    }
374
}