Passed
Push — develop ( 6a531b...8455bc )
by Nikolay
05:46
created

ModelsBase::getIdentityFieldName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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

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