Passed
Push — develop ( 71b08a...99379a )
by Nikolay
06:34
created

ModelsBase::getIndexColumn()   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
 * Copyright © MIKO LLC - All Rights Reserved
4
 * Unauthorized copying of this file, via any medium is strictly prohibited
5
 * Proprietary and confidential
6
 * Written by Alexey Portnov, 6 2020
7
 */
8
9
namespace MikoPBX\Common\Models;
10
11
use MikoPBX\AdminCabinet\Library\Elements;
12
use MikoPBX\Core\System\Util;
13
use Phalcon\Db\Adapter\AdapterInterface;
14
use Phalcon\Db\RawValue;
15
use Phalcon\Messages\Message;
16
use Phalcon\Messages\MessageInterface;
17
use Phalcon\Mvc\Model;
18
use Phalcon\Mvc\Model\Relation;
19
use Phalcon\Mvc\Model\Resultset;
20
use Phalcon\Mvc\Model\Resultset\Simple;
21
use Phalcon\Mvc\Model\ResultsetInterface;
22
use Phalcon\Text;
23
use Phalcon\Url;
24
25
/**
26
 * Class ModelsBase
27
 *
28
 * @method static mixed findFirstById(array|string|int $parameters = null)
29
 * @method static mixed findFirstByKey(string|null $parameters)
30
 * @method static mixed findFirstByUniqid(array|string|int $parameters = null)
31
 * @method static mixed findFirst(array|string|int $parameters = null)
32
 * @method static ResultsetInterface find(array|string|int $parameters = null)
33
 * @method static mixed count(array $parameters = null)
34
 * @method  bool create()
35
 * @method  bool delete()
36
 * @method  bool save()
37
 * @method  bool update()
38
 * @method  array|MessageInterface[] getMessages(mixed $filter = null)
39
 * @method static AdapterInterface getReadConnection()
40
 * @method  Simple|false getRelated(string $alias, $arguments = null)
41
 *
42
 * @property \Phalcon\Mvc\Model\Manager _modelsManager
43
 * @property \Phalcon\Di                di
44
 *
45
 * @package MikoPBX\Common\Models
46
 */
47
abstract class ModelsBase extends Model
48
{
49
50
    public function initialize(): void
51
    {
52
        self::setup(['orm.events' => true]);
53
        $this->keepSnapshots(true);
54
55
        // Пройдемся по модулям и подключим их отношения к текущей модели, если они описаны
56
        $cacheKey   = explode('\\', static::class)[3];
57
        $modulesDir = $this->di->getShared('config')->core->modulesDir;
58
        $parameters = [
59
            'conditions' => 'disabled=0',
60
            'cache'      => [
61
                'key'      => $cacheKey,
62
                'lifetime' => 5, //seconds
63
            ],
64
        ];
65
        $modules    = PbxExtensionModules::find($parameters)->toArray();
66
        foreach ($modules as $module) {
67
            $moduleModelsDir = "{$modulesDir}/{$module['uniqid']}/Models";
68
            $results         = glob($moduleModelsDir . '/*.php', GLOB_NOSORT);
69
            foreach ($results as $file) {
70
                $className        = pathinfo($file)['filename'];
71
                $moduleModelClass = "\\Modules\\{$module['uniqid']}\\Models\\{$className}";
72
                if (class_exists($moduleModelClass) && method_exists($moduleModelClass, 'getDynamicRelations')) {
73
                    $moduleModelClass::getDynamicRelations($this);
74
                }
75
            }
76
        }
77
    }
78
79
    /**
80
     * Обработчик ошибок валидации, обычно сюда попадаем если неправильно
81
     * сохраняются или удаляютмя модели или неправильно настроены зависимости между ними.
82
     * Эта функция формирует список ссылок на объект который мы пытаемся удалить
83
     *
84
     * При описании отношений необходимо в foreignKey секцию добавлять атрибут
85
     * message в котором указывать алиас посе слова Models,
86
     * например Models\IvrMenuTimeout, иначе метод getRelated не сможет найти зависимые
87
     * записи в моделях
88
     */
89
    public function onValidationFails(): void
90
    {
91
        $errorMessages = $this->getMessages();
92
        if (php_sapi_name() === 'cli') {
93
            Util::sysLogMsg(__CLASS__, implode(' ', $errorMessages));
94
95
            return;
96
        }
97
        foreach ($errorMessages as $errorMessage) {
98
            if ($errorMessage->getType() === 'ConstraintViolation') {
99
                $arrMessageParts = explode('Common\\Models\\', $errorMessage->getMessage());
100
                if (count($arrMessageParts) === 2) {
101
                    $relatedModel = $arrMessageParts[1];
102
                } else {
103
                    $relatedModel = $errorMessage->getMessage();
104
                }
105
                $relatedRecords  = $this->getRelated($relatedModel);
106
                $newErrorMessage = $this->t('ConstraintViolation');
107
                $newErrorMessage .= "<ul class='list'>";
108
                if ($relatedRecords === false) {
109
                    throw new Model\Exception('Error on models relationship ' . $errorMessage);
110
                }
111
                if ($relatedRecords instanceof Resultset) {
112
                    foreach ($relatedRecords as $item) {
113
                        $newErrorMessage .= '<li>' . $item->getRepresent(true) . '</li>';
0 ignored issues
show
Bug introduced by
The method getRepresent() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

113
                        $newErrorMessage .= '<li>' . $item->/** @scrutinizer ignore-call */ getRepresent(true) . '</li>';

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
114
                    }
115
                } else {
116
                    $newErrorMessage .= '<li>Unknown object</li>';
117
                }
118
                $newErrorMessage .= '</ul>';
119
                $errorMessage->setMessage($newErrorMessage);
120
                break;
121
            }
122
        }
123
    }
124
125
    /**
126
     * Функция для доступа к массиву переводов из моделей, используется для
127
     * сообщений на понятном пользователю языке
128
     *
129
     * @param       $message
130
     * @param array $parameters
131
     *
132
     * @return mixed
133
     */
134
    public function t($message, $parameters = [])
135
    {
136
        return $this->getDI()->getShared('translation')->t($message, $parameters);
137
    }
138
139
    /**
140
     * Fill default values from annotations
141
     */
142
    public function beforeValidationOnCreate(): void
143
    {
144
        $metaData      = $metaData = $this->di->get('modelsMetadata');
0 ignored issues
show
Unused Code introduced by
The assignment to $metaData is dead and can be removed.
Loading history...
145
        $defaultValues = $metaData->getDefaultValues($this);
146
        foreach ($defaultValues as $field => $value) {
147
            if ( ! isset($this->{$field}) || $this->{$field} === null) {
148
                $this->{$field} = new RawValue($value);
149
            }
150
        }
151
    }
152
153
    /**
154
     * Функция позволяет вывести список зависимостей с сылками,
155
     * которые мешают удалению текущей сущности
156
     *
157
     * @return bool
158
     */
159
    public function beforeDelete(): bool
160
    {
161
        return $this->checkRelationsSatisfaction($this, $this);
162
    }
163
164
    /**
165
     *  Check whether this object has unsatisfied relations or not
166
     *
167
     * @param $theFirstDeleteRecord
168
     * @param $currentDeleteRecord
169
     *
170
     * @return bool
171
     */
172
    private function checkRelationsSatisfaction($theFirstDeleteRecord, $currentDeleteRecord): bool
173
    {
174
        $result = true;
175
        $relations
176
                = $currentDeleteRecord->_modelsManager->getRelations(get_class($currentDeleteRecord));
177
        foreach ($relations as $relation) {
178
            $foreignKey = $relation->getOption('foreignKey');
179
            if ( ! array_key_exists('action', $foreignKey)) {
180
                continue;
181
            }
182
            // Check if there are some record which restrict delete current record
183
            $relatedModel             = $relation->getReferencedModel();
184
            $mappedFields             = $relation->getFields();
185
            $mappedFields             = is_array($mappedFields)
186
                ? $mappedFields : [$mappedFields];
187
            $referencedFields         = $relation->getReferencedFields();
188
            $referencedFields         = is_array($referencedFields)
189
                ? $referencedFields : [$referencedFields];
190
            $parameters['conditions'] = '';
191
            $parameters['bind']       = [];
192
            foreach ($referencedFields as $index => $referencedField) {
193
                $parameters['conditions']             .= $index > 0
194
                    ? ' OR ' : '';
195
                $parameters['conditions']             .= $referencedField
196
                    . '= :field'
197
                    . $index . ':';
198
                $bindField
199
                                                      = $mappedFields[$index];
200
                $parameters['bind']['field' . $index] = $currentDeleteRecord->$bindField;
201
            }
202
            $relatedRecords = $relatedModel::find($parameters);
203
            switch ($foreignKey['action']) {
204
                case Relation::ACTION_RESTRICT: // Restrict deletion and add message about unsatisfied undeleted links
205
                    foreach ($relatedRecords as $relatedRecord) {
206
                        if (serialize($relatedRecord) === serialize($theFirstDeleteRecord)) {
207
                            continue; // It is checked object
208
                        }
209
                        $message = new Message(
210
                            $theFirstDeleteRecord->t(
211
                                'mo_BeforeDeleteFirst',
212
                                [
213
                                    'represent' => $relatedRecord->getRepresent(true),
214
                                ]
215
                            )
216
                        );
217
                        $theFirstDeleteRecord->appendMessage($message);
218
                        $result = false;
219
                    }
220
                    break;
221
                case Relation::ACTION_CASCADE: // Удалим все зависимые записи
222
                    foreach ($relatedRecords as $record) {
223
                        $result = $result && $record->checkRelationsSatisfaction($theFirstDeleteRecord, $record);
224
                        if ($result) {
225
                            $result = $record->delete();
226
                        }
227
                    }
228
                    break;
229
                case Relation::NO_ACTION: // Clear all refs
230
                    break;
231
                default:
232
                    break;
233
            }
234
        }
235
236
        return $result;
237
    }
238
239
    /**
240
     * После сохранения данных любой модели
241
     */
242
    public function afterSave(): void
243
    {
244
        $this->processSettingsChanges('afterSave');
245
        $this->clearCache(static::class);
246
    }
247
248
    /**
249
     * Готовит массив действий для перезапуска модулей ядра системы
250
     * и Asterisk
251
     *
252
     * @param $action string  быть afterSave или afterDelete
253
     */
254
    private function processSettingsChanges(string $action): void
255
    {
256
        if (php_sapi_name() !== 'cli') {
257
            if ( ! $this->hasSnapshotData()) {
258
                return;
259
            } // nothing changed
260
261
            $changedFields = $this->getUpdatedFields();
262
            if (empty($changedFields) && $action === 'afterSave') {
263
                return;
264
            }
265
266
            // Add changed fields set to benstalk queue
267
            $queue = $this->di->getShared('beanstalkConnection');
268
269
            if ($this instanceof PbxSettings) {
270
                $idProperty = 'key';
271
            } else {
272
                $idProperty = 'id';
273
            }
274
            $id      = $this->$idProperty;
275
            $jobData = json_encode(
276
                [
277
                    'model'         => get_class($this),
278
                    'recordId'      => $id,
279
                    'action'        => $action,
280
                    'changedFields' => $changedFields,
281
                ]
282
            );
283
            $queue->publish($jobData);
284
        }
285
    }
286
287
    /**
288
     * Очистка кешей при сохранении данных в базу
289
     *
290
     * @param $calledClass string модель, с чей кеш будем чистить в полном формате
291
     */
292
    public function clearCache(string $calledClass): void
293
    {
294
        if ($this->di->has('managedCache')) {
295
            $managedCache = $this->di->getShared('managedCache');
296
            $category     = explode('\\', $calledClass)[3];
297
            $keys         = $managedCache->getAdapter()->getKeys($category);
298
            if (count($keys) > 0) {
299
                $managedCache->deleteMultiple($keys);
300
            }
301
        }
302
        if ($this->di->has('modelsCache')) {
303
            $modelsCache = $this->di->getShared('modelsCache');
304
            $category    = explode('\\', $calledClass)[3];
305
            $keys        = $modelsCache->getAdapter()->getKeys($category);
306
            if (count($keys) > 0) {
307
                $modelsCache->deleteMultiple($keys);
308
            }
309
        }
310
    }
311
312
    /**
313
     * После удаления данных любой модели
314
     */
315
    public function afterDelete(): void
316
    {
317
        $this->processSettingsChanges('afterDelete');
318
        $this->clearCache(static::class);
319
    }
320
321
    /**
322
     * Возвращает предстваление элемента базы данных
323
     *  для сообщения об ошибках с ссылкой на элемент или для выбора в списках
324
     *  строкой
325
     *
326
     * @param bool $needLink - предстваление с ссылкой
327
     *
328
     * @return string
329
     */
330
    public function getRepresent($needLink = false): string
331
    {
332
        switch (static::class) {
333
            case AsteriskManagerUsers::class:
334
                $name = '<i class="asterisk icon"></i> ';
335
                if (empty($this->id)) {
336
                    $name .= $this->t('mo_NewElementAsteriskManagerUsers');
337
                } else {
338
                    $name .= $this->t('repAsteriskManagerUsers', ['represent' => $this->username]);
339
                }
340
                break;
341
            case CallQueueMembers::class:
342
                $name = $this->Extensions->getRepresent();
343
                break;
344
            case CallQueues::class:
345
                $name = '<i class="users icon"></i> ';
346
                if (empty($this->id)) {
347
                    $name .= $this->t('mo_NewElementCallQueues');
348
                } else {
349
                    $name .= $this->t('mo_CallQueueShort4Dropdown') . ': ' . $this->name;
350
                }
351
                break;
352
            case ConferenceRooms::class:
353
                $name = '<i class="phone volume icon"></i> ';
354
                if (empty($this->id)) {
355
                    $name .= $this->t('mo_NewElementConferenceRooms');
356
                } else {
357
                    $name .= $this->t('mo_ConferenceRoomsShort4Dropdown') . ': ' . $this->name;;
358
                }
359
                break;
360
            case CustomFiles::class:
361
                $name = "<i class='file icon'></i> {$this->filepath}";
362
                break;
363
            case DialplanApplications::class:
364
                $name = '<i class="php icon"></i> ';
365
                if (empty($this->id)) {
366
                    $name .= $this->t('mo_NewElementDialplanApplications');
367
                } else {
368
                    $name .= $this->t('mo_ApplicationShort4Dropdown') . ': ' . $this->name;;
369
                }
370
                break;
371
            case ExtensionForwardingRights::class:
372
                $name = $this->Extensions->getRepresent();
373
                break;
374
            case Extensions::class:
375
                // Для внутреннего номера бывают разные представления
376
                if ($this->type === 'EXTERNAL') {
377
                    $icon = '<i class="icons"><i class="user outline icon"></i><i class="top right corner alternate mobile icon"></i></i>';
378
                } else {
379
                    $icon = '<i class="icons"><i class="user outline icon"></i></i>';
380
                }
381
                if (empty($this->id)) {
382
                    $name = "{$icon} {$this->t('mo_NewElementExtensions')}";
383
                } elseif ($this->userid > 0) {
384
                    $name = '';
385
                    if (isset($this->Users->username)) {
386
                        $name = $this->trimName($this->Users->username);
387
                    }
388
                    $name = "{$icon} {$name} <{$this->number}>";
389
                } else {
390
                    switch (strtoupper($this->type)) {
391
                        case 'CONFERENCE':
392
                            $name = $this->ConferenceRooms->getRepresent();
393
                            break;
394
                        case 'QUEUE':
395
                            $name = $this->CallQueues->getRepresent();
396
                            break;
397
                        case 'DIALPLAN APPLICATION':
398
                            $name = $this->DialplanApplications->getRepresent();
399
                            break;
400
                        case 'IVR MENU':
401
                            $name = $this->IvrMenu->getRepresent();
402
                            break;
403
                        case 'MODULES':
404
                            $name = '<i class="puzzle piece icon"></i> '
405
                                . $this->t('mo_ModuleShort4Dropdown')
406
                                . ': '
407
                                . $this->callerid;
408
                            break;
409
                        case 'EXTERNAL':
410
                        case 'SIP':
411
                        default:
412
                            $name = "{$this->callerid} <{$this->number}>";
413
                    }
414
                }
415
                break;
416
            case ExternalPhones::class:
417
                $name = $this->Extensions->getRepresent();
418
                break;
419
            case Fail2BanRules::class:
420
                $name = '';
421
                break;
422
            case FirewallRules::class:
423
                $name = $this->category;
424
                break;
425
            case Iax::class:
426
                $name = '<i class="server icon"></i> ';
427
                if (empty($this->id)) {
428
                    $name .= $this->t('mo_NewElementIax');
429
                } elseif ($this->disabled === '1') {
430
                    $name .= "{$this->description} ({$this->t( 'mo_Disabled' )})";
431
                } else {
432
                    $name .= $this->description;
433
                }
434
                break;
435
            case IvrMenu::class:
436
                $name = '<i class="sitemap icon"></i> ';
437
                if (empty($this->id)) {
438
                    $name .= $this->t('mo_NewElementIvrMenu');
439
                } else {
440
                    $name .= $this->t('mo_IVRMenuShort4Dropdown') . ': ' . $this->name;
441
                }
442
                break;
443
            case IvrMenuActions::class:
444
                $name = $this->IvrMenu->name;
445
                break;
446
            case Codecs::class:
447
                $name = $this->name;
448
                break;
449
            case IncomingRoutingTable::class:
450
                $name = '<i class="map signs icon"></i> ';
451
                if (empty($this->id)) {
452
                    $name .= $this->t('mo_NewElementIncomingRoutingTable');
453
                } elseif ( ! empty($this->note)) {
454
                    $name .= $this->t('repIncomingRoutingTable', ['represent' => $this->note]);
455
                } else {
456
                    $name .= $this->t('repIncomingRoutingTableNumber', ['represent' => $this->id]);
457
                }
458
                break;
459
            case LanInterfaces::class:
460
                // LanInterfaces
461
                $name = $this->name;
462
                break;
463
            case NetworkFilters::class:
464
                $name = '<i class="globe icon"></i> ';
465
                if (empty($this->id)) {
466
                    $name .= $this->t('mo_NewElementNetworkFilters');
467
                } else {
468
                    $name .= $this->description . '('
469
                        . $this->t('fw_PermitNetwork') . ': ' . $this->permit
470
                        . ')';
471
                }
472
                break;
473
            case OutgoingRoutingTable::class:
474
                $name = '<i class="random icon"></i> ';
475
                if (empty($this->id)) {
476
                    $name .= $this->t('mo_NewElementOutgoingRoutingTable');
477
                } elseif ( ! empty($this->rulename)) {
478
                    $name .= $this->t('repOutgoingRoutingTable', ['represent' => $this->rulename]);
479
                } else {
480
                    $name .= $this->t('repOutgoingRoutingTableNumber', ['represent' => $this->id]);
481
                }
482
                break;
483
            case OutWorkTimes::class:
484
                $name = '<i class="time icon"></i> ';
485
                if (empty($this->id)) {
486
                    $name .= $this->t('mo_NewElementOutWorkTimes');
487
                } elseif ( ! empty($this->description)) {
488
                    $name .= $this->t('repOutWorkTimes', ['represent' => $this->description]);
489
                } else {
490
                    $represent = '';
491
                    if (is_numeric($this->date_from)) {
492
                        $represent .= date("d/m/Y", $this->date_from) . '-';
493
                    }
494
                    if (is_numeric($this->date_to)) {
495
                        $represent .= date("d/m/Y", $this->date_to) . ' ';
496
                    }
497
                    if (isset($this->weekday_from)) {
498
                        $represent .= $this->t(date('D', strtotime("Sunday +{$this->weekday_from} days"))) . '-';
499
                    }
500
                    if (isset($this->weekday_to)) {
501
                        $represent .= $this->t(date('D', strtotime("Sunday +{$this->weekday_to} days"))) . ' ';
502
                    }
503
                    if (isset($this->time_from) || isset($this->time_to)) {
504
                        $represent .= $this->time_from . ' - ' . $this->time_to . ' ';
505
                    }
506
                    $name .= $this->t('repOutWorkTimes', ['represent' => $represent]);
507
                }
508
                break;
509
            case Providers::class:
510
                if ($this->type === "IAX") {
511
                    $name = $this->Iax->getRepresent();
512
                } else {
513
                    $name = $this->Sip->getRepresent();
514
                }
515
                break;
516
            case PbxSettings::class:
517
                $name = $this->key;
518
                break;
519
            case PbxExtensionModules::class:
520
                $name = '<i class="puzzle piece icon"></i> '
521
                    . $this->t('mo_ModuleShort4Dropdown') . ': '
522
                    . $this->name;
523
                break;
524
            case Sip::class:
525
                $name = '<i class="server icon"></i> ';
526
                if (empty($this->id)) {
527
                    $name .= $this->t('mo_NewElementSip');
528
                } elseif ($this->disabled === '1') {
529
                    $name .= "{$this->description} ({$this->t( 'mo_Disabled' )})";
530
                } else {
531
                    $name .= $this->description;
532
                }
533
534
                break;
535
            case Users::class:
536
                $name = '<i class="user outline icon"></i> ' . $this->username;
537
                break;
538
            case SoundFiles::class:
539
                $name = '<i class="file audio outline icon"></i> ';
540
                if (empty($this->id)) {
541
                    $name .= $this->t('mo_NewElementSoundFiles');
542
                } else {
543
                    $name .= $this->t('repSoundFiles', ['represent' => $this->name]);
544
                }
545
546
                break;
547
            default:
548
                $name = 'Unknown';
549
        }
550
551
        if ($needLink) {
552
            if (empty($name)) {
0 ignored issues
show
introduced by
The condition empty($name) is always false.
Loading history...
553
                $name = $this->t('repLink');
554
            }
555
            $link     = $this->getWebInterfaceLink();
556
            $category = explode('\\', static::class)[3];
557
            $result   = $this->t(
558
                'rep' . $category,
559
                [
560
                    'represent' => "<a href='{$link}'>{$name}</a>",
561
                ]
562
            );
563
        } else {
564
            $result = $name;
565
        }
566
567
        return $result;
568
    }
569
570
    /**
571
     * Укорачивает длинные имена
572
     *
573
     * @param $s
574
     *
575
     * @return string
576
     */
577
    private function trimName($s): string
578
    {
579
        $max_length = 64;
580
581
        if (strlen($s) > $max_length) {
582
            $offset = ($max_length - 3) - strlen($s);
583
            $s      = substr($s, 0, strrpos($s, ' ', $offset)) . '...';
584
        }
585
586
        return $s;
587
    }
588
589
    /**
590
     * Return link on database record in web interface
591
     *
592
     * @return string
593
     */
594
    public function getWebInterfaceLink(): string
595
    {
596
        $url = new Url();
597
598
        $baseUri = $this->di->getShared('config')->path('adminApplication.baseUri');
599
        $link    = '#';
600
        switch (static::class) {
601
            case AsteriskManagerUsers::class:
602
                $link = $url->get('asterisk-managers/modify/' . $this->id, null, null, $baseUri);
603
                break;
604
            case CallQueueMembers::class:
605
                $link = $url->get('call-queues/modify/' . $this->CallQueues->uniqid, null, null, $baseUri);
606
                break;
607
            case CallQueues::class:
608
                $link = $url->get('call-queues/modify/' . $this->uniqid, null, null, $baseUri);
609
                break;
610
            case ConferenceRooms::class:
611
                $link = $url->get('conference-rooms/modify/' . $this->uniqid, null, null, $baseUri);
612
                break;
613
            case CustomFiles::class:
614
                $link = $url->get('custom-files/modify/' . $this->id, null, null, $baseUri);
615
                break;
616
            case DialplanApplications::class:
617
                $link = $url->get('dialplan-applications/modify/' . $this->uniqid, null, null, $baseUri);
618
                break;
619
            case ExtensionForwardingRights::class:
620
621
                break;
622
            case Extensions::class:
623
                $link = $url->get('extensions/modify/' . $this->id, null, null, $baseUri);
624
                break;
625
            case ExternalPhones::class:
626
                if ($this->Extensions->is_general_user_number === "1") {
627
                    $parameters    = [
628
                        'conditions' => 'is_general_user_number="1" AND type="EXTERNAL" AND userid=:userid:',
629
                        'bind'       => [
630
                            'userid' => $this->Extensions->userid,
631
                        ],
632
                    ];
633
                    $needExtension = Extensions::findFirst($parameters);
634
                    $link          = $url->get('extensions/modify/' . $needExtension->id, null, null, $baseUri);
635
                } else {
636
                    $link = '#';//TODO сделать если будет раздел для допоплнинельных номеров пользователя
637
                }
638
                break;
639
            case Fail2BanRules::class:
640
                $link = '#';//TODO сделать если будет fail2ban
641
                break;
642
            case FirewallRules::class:
643
                $link = $url->get('firewall/modify/' . $this->NetworkFilters->id, null, null, $baseUri);
644
                break;
645
            case Iax::class:
646
                $link = $url->get('providers/modifyiax/' . $this->Providers->id, null, null, $baseUri);
647
                break;
648
            case IvrMenu::class:
649
                $link = $url->get('ivr-menu/modify/' . $this->uniqid, null, null, $baseUri);
650
                break;
651
            case IvrMenuActions::class:
652
                $link = $url->get('ivr-menu/modify/' . $this->IvrMenu->uniqid, null, null, $baseUri);
653
                break;
654
            case Codecs::class:
655
                break;
656
            case IncomingRoutingTable::class:
657
                $link = $url->get('incoming-routes/modify/' . $this->id, null, null, $baseUri);
658
                break;
659
            case LanInterfaces::class:
660
                $link = $url->get('network/index/', null, null, $baseUri);
661
                break;
662
            case NetworkFilters::class:
663
                $link = $url->get('firewall/modify/' . $this->id, null, null, $baseUri);
664
                break;
665
            case OutgoingRoutingTable::class:
666
                $link = $url->get('outbound-routes/modify/' . $this->id, null, null, $baseUri);
667
                break;
668
            case OutWorkTimes::class:
669
                $link = $url->get('out-off-work-time/modify/' . $this->id, null, null, $baseUri);
670
                break;
671
            case Providers::class:
672
                if ($this->type === "IAX") {
673
                    $link = $url->get('providers/modifyiax/' . $this->uniqid, null, null, $baseUri);
674
                } else {
675
                    $link = $url->get('providers/modifysip/' . $this->uniqid, null, null, $baseUri);
676
                }
677
                break;
678
            case PbxSettings::class:
679
                $link = $url->get('general-settings/index');
680
                break;
681
            case PbxExtensionModules::class:
682
                $link = $url->get(Text::uncamelize($this->uniqid), null, null, $baseUri);
683
                break;
684
            case Sip::class:
685
                if ($this->Extensions) { // Это внутренний номер?
686
                    if ($this->Extensions->is_general_user_number === "1") {
687
                        $link = $url->get('extensions/modify/' . $this->Extensions->id, null, null, $baseUri);
688
                    } else {
689
                        $link = '#';//TODO сделать если будет раздел для допоплнинельных номеров пользователя
690
                    }
691
                } elseif ($this->Providers) { // Это провайдер
692
                    $link = $url->get('providers/modifysip/' . $this->Providers->id, null, null, $baseUri);
693
                }
694
                break;
695
            case Users::class:
696
                $parameters    = [
697
                    'conditions' => 'userid=:userid:',
698
                    'bind'       => [
699
                        'userid' => $this->id,
700
                    ],
701
                ];
702
                $needExtension = Extensions::findFirst($parameters);
703
                $link          = $url->get('extensions/modify/' . $needExtension->id, null, null, $baseUri);
704
                break;
705
            case SoundFiles::class:
706
                $link = $url->get('sound-files/modify/' . $this->id, null, null, $baseUri);
707
                break;
708
            default:
709
        }
710
711
        return $link;
712
    }
713
714
    /**
715
     * Returns Identity field name for current model
716
     *
717
     * @return string
718
     */
719
    public function getIdentityFieldName(): string
720
    {
721
        $metaData = $this->di->get('modelsMetadata');
722
723
        return $metaData->getIdentityField($this);
724
    }
725
}