Passed
Pull Request — master (#16)
by Nikolay
13:10 queued 02:12
created

SIPConf::generateGeneralPj()   C

Complexity

Conditions 14
Paths 144

Size

Total Lines 92
Code Lines 70

Duplication

Lines 0
Ratio 0 %

Importance

Changes 7
Bugs 0 Features 0
Metric Value
eloc 70
c 7
b 0
f 0
dl 0
loc 92
rs 5.3745
cc 14
nc 144
nop 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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, 10 2020
7
 */
8
9
namespace MikoPBX\Core\Asterisk\Configs;
10
11
use MikoPBX\Common\Models\{Codecs,
12
    ExtensionForwardingRights,
13
    Extensions as ExtensionsModel,
14
    NetworkFilters,
15
    OutgoingRoutingTable,
16
    PbxSettings,
17
    Sip,
18
    Users};
19
use MikoPBX\Core\Asterisk\AstDB;
20
use MikoPBX\Modules\Config\ConfigClass;
21
use MikoPBX\Core\System\{Network, Util};
22
use MikoPBX\Core\Utilities\SubnetCalculator;
23
24
class SIPConf extends ConfigClass
25
{
26
    public const TYPE_PJSIP = 'PJSIP';
27
28
    protected $data_peers;
29
    protected $data_providers;
30
    protected $data_rout;
31
    protected string $technology;
32
    protected array  $contexts_data;
33
34
    protected string $description = 'pjsip.conf';
35
36
    /**
37
     *
38
     * @return array
39
     */
40
    public function dependenceModels(): array
41
    {
42
        return [Sip::class, Users::class];
43
    }
44
45
    /**
46
     * Генератор sip.conf
47
     *
48
     * @return bool|void
49
     */
50
    protected function generateConfigProtected(): void
51
    {
52
        $conf = '';
53
        $conf .= $this->generateGeneralPj();
54
        $conf .= $this->generateProvidersPj();
55
        $conf .= $this->generatePeersPj();
56
57
        Util::fileWriteContent($this->config->path('asterisk.astetcdir') . '/pjsip.conf', $conf);
58
        $pjConf = '[log_mappings]'."\n".
59
            'type=log_mappings'."\n".
60
            'asterisk_error = 0'."\n".
61
            'asterisk_warning = 2'."\n".
62
            'asterisk_debug = 1,3,4,5,6'."\n\n";
63
64
        file_put_contents($this->config->path('asterisk.astetcdir') . '/pjproject.conf', $pjConf);
65
        file_put_contents($this->config->path('asterisk.astetcdir') . '/sorcery.conf', '');
66
67
        $db = new AstDB();
68
        foreach ($this->data_peers as $peer) {
69
            // Помещаем в AstDB сведения по маршуртизации.
70
            $ringlength = ($peer['ringlength'] == 0) ? '' : trim($peer['ringlength']);
71
            $db->databasePut('FW_TIME', "{$peer['extension']}", $ringlength);
72
            $db->databasePut('FW', "{$peer['extension']}", trim($peer['forwarding']));
73
            $db->databasePut('FW_BUSY', "{$peer['extension']}", trim($peer['forwardingonbusy']));
74
            $db->databasePut('FW_UNAV', "{$peer['extension']}", trim($peer['forwardingonunavailable']));
75
        }
76
    }
77
78
    /**
79
     * Генератора секции general pjsip.conf
80
     *
81
     *
82
     * @return string
83
     */
84
    private function generateGeneralPj(): string
85
    {
86
        $network = new Network();
87
        $lang    = $this->generalSettings['PBXLanguage'];
88
89
        $topology    = 'public';
90
        $extipaddr   = '';
91
        $exthostname = '';
92
        $networks    = $network->getEnabledLanInterfaces();
93
        $subnets     = [];
94
        foreach ($networks as $if_data) {
95
            $lan_config = $network->getInterface($if_data['interface']);
96
            if (empty($lan_config['ipaddr']) || empty($lan_config['subnet'])) {
97
                continue;
98
            }
99
            $sub = new SubnetCalculator($lan_config['ipaddr'], $lan_config['subnet']);
100
            $net = $sub->getNetworkPortion() . '/' . $lan_config['subnet'];
101
            if ($if_data['topology'] === 'private' && in_array($net, $subnets, true) === false) {
102
                $subnets[] = $net;
103
            }
104
            if (trim($if_data['internet']) === '1') {
105
                $topology    = trim($if_data['topology']);
106
                $extipaddr   = trim($if_data['extipaddr']);
107
                $exthostname = trim($if_data['exthostname']);
108
            }
109
        }
110
111
        $networks = NetworkFilters::find('local_network=1');
112
        foreach ($networks as $net) {
113
            if (in_array($net->permit, $subnets, true) === false) {
114
                $subnets[] = $net->permit;
115
            }
116
        }
117
        $codecs = $this->getCodecs();
118
        $codecConf = '';
119
        foreach ($codecs as $codec){
120
            $codecConf.= "allow = {$codec}\n";
121
        }
122
123
        $pbxVersion = PbxSettings::getValueByKey('PBXVersion');
124
        $natConf = '';
125
        if ($topology === 'private') {
126
            foreach ($subnets as $net) {
127
                $natConf .= "local_net={$net}\n";
128
            }
129
            if ( ! empty($exthostname)) {
130
                $parts = explode(':', $exthostname);
131
                $natConf  .= 'external_media_address=' . $parts[0] . "\n";
132
                $natConf  .= 'external_signaling_address=' . $parts[0] . "\n";
133
                $natConf  .= 'external_signaling_port=' . ($parts[1] ?? '5060');
134
            } elseif ( ! empty($extipaddr)) {
135
                $parts = explode(':', $extipaddr);
136
                $natConf  .= 'external_media_address=' . $parts[0] . "\n";
137
                $natConf  .= 'external_signaling_address=' . $parts[0] . "\n";
138
                $natConf  .= 'external_signaling_port=' . ($parts[1] ?? '5060');
139
            }
140
        }
141
142
        $conf = "[general] \n" .
143
            "disable_multi_domain=on\n" .
144
            "transport = udp \n\n" .
145
146
            "[global] \n" .
147
            "type = global\n" .
148
            "endpoint_identifier_order=username,ip,anonymous\n" .
149
            "user_agent = mikopbx-{$pbxVersion}\n\n" .
150
151
            "[anonymous]\n" .
152
            "type = endpoint\n" .
153
            $codecConf.
154
            "language={$lang}\n".
155
            "timers = no\n" .
156
            "context = public-direct-dial\n\n".
157
158
            "[transport-udp]\n" .
159
            "type = transport\n" .
160
            "protocol = udp\n" .
161
            "bind=0.0.0.0:{$this->generalSettings['SIPPort']}\n".
162
            "{$natConf}\n\n".
163
164
            "[transport-tcp]\n" .
165
            "type = transport\n" .
166
            "protocol = tcp\n" .
167
            "bind=0.0.0.0:{$this->generalSettings['SIPPort']}\n".
168
            "{$natConf}\n\n".
169
            '';
170
171
        $varEtcDir = $this->config->path('core.varEtcDir');
172
        file_put_contents($varEtcDir . '/topology_hash', md5($topology . $exthostname . $extipaddr));
173
        $conf .= "\n";
174
175
        return $conf;
176
    }
177
178
    /**
179
     * Генератор секции провайдеров в sip.conf
180
     *
181
     *
182
     * @return string
183
     */
184
    private function generateProvidersPj(): string
185
    {
186
        $conf        = '';
187
        $reg_strings = '';
188
        $prov_config = '';
189
        if ($this->data_providers===null){
190
            $this->getSettings();
191
        }
192
        foreach ($this->data_providers as $provider) {
193
            $manual_attributes = Util::parseIniSettings(base64_decode($provider['manualattributes'] ?? ''));
194
            $port              = (trim($provider['port']) === '') ? '5060' : $provider['port'];
195
196
            $need_register = $provider['noregister'] !== '1';
197
            if ($need_register) {
198
                $options     = [
199
                    'type'     => 'auth',
200
                    'username' => $provider['username'],
201
                    'password' => $provider['secret'],
202
                ];
203
                $reg_strings .= "[REG-AUTH-{$provider['uniqid']}]\n";
204
                $reg_strings .= Util::overrideConfigurationArray($options, $manual_attributes, 'registration-auth');
205
206
                $options     = [
207
                    'type'                        => 'registration',
208
                    // 'transport'                   => 'transport-udp',
209
                    'outbound_auth'               => "REG-AUTH-{$provider['uniqid']}",
210
                    'contact_user'                => $provider['username'],
211
                    'retry_interval'              => '30',
212
                    'max_retries'                 => '100',
213
                    'forbidden_retry_interval'    => '300',
214
                    'fatal_retry_interval'        => '300',
215
                    'expiration'                  => $this->generalSettings['SIPDefaultExpiry'],
216
                    'server_uri'                  => "sip:{$provider['host']}:{$port}",
217
                    'client_uri'                  => "sip:{$provider['username']}@{$provider['host']}:{$port}",
218
                ];
219
                $reg_strings .= "[REG-{$provider['uniqid']}] \n";
220
                $reg_strings .= Util::overrideConfigurationArray($options, $manual_attributes, 'registration');
221
            }
222
223
            if ('1' !== $provider['receive_calls_without_auth']) {
224
                $options     = [
225
                    'type'     => 'auth',
226
                    'username' => $provider['username'],
227
                    'password' => $provider['secret'],
228
                ];
229
                $prov_config .= "[{$provider['uniqid']}-OUT]\n";
230
                $prov_config .= Util::overrideConfigurationArray($options, $manual_attributes, 'endpoint-auth');
231
            }
232
233
            $defaultuser = (trim($provider['defaultuser']) === '') ? $provider['username'] : $provider['defaultuser'];
234
            if ( ! empty($defaultuser) && '1' !== $provider['receive_calls_without_auth']) {
235
                $contact = "sip:$defaultuser@{$provider['host']}:{$port}";
236
            } else {
237
                $contact = "sip:{$provider['host']}:{$port}";
238
            }
239
240
            $options     = [
241
                'type'               => 'aor',
242
                'max_contacts'       => '1',
243
                'contact'            => $contact,
244
                'maximum_expiration' => $this->generalSettings['SIPMaxExpiry'],
245
                'minimum_expiration' => $this->generalSettings['SIPMinExpiry'],
246
                'default_expiration' => $this->generalSettings['SIPDefaultExpiry'],
247
            ];
248
            if($provider['qualify'] === '1'){
249
                $options['qualify_frequency'] = $provider['qualifyfreq'];
250
                $options['qualify_timeout']   = '3.0';
251
            }
252
253
            $prov_config .= "[{$provider['uniqid']}]\n";
254
            $prov_config .= Util::overrideConfigurationArray($options, $manual_attributes, 'aor');
255
256
            $options     = [
257
                'type'     => 'identify',
258
                'endpoint' => $provider['uniqid'],
259
                'match'    => $provider['host'],
260
            ];
261
            $prov_config .= "[{$provider['uniqid']}]\n";
262
            $prov_config .= Util::overrideConfigurationArray($options, $manual_attributes, 'identify');
263
264
            $fromdomain = (trim($provider['fromdomain']) === '') ? $provider['host'] : $provider['fromdomain'];
265
            $from       = (trim(
266
                    $provider['fromuser']
267
                ) === '') ? "{$provider['username']}; username" : "{$provider['fromuser']}; fromuser";
268
            $from_user  = ($provider['disablefromuser'] === '1') ? null : $from;
269
            $lang       = $this->generalSettings['PBXLanguage'];
270
271
            if (count($this->contexts_data[$provider['context_id']]) === 1) {
272
                $context_id = $provider['uniqid'];
273
            } else {
274
                $context_id = $provider['context_id'];
275
            }
276
            $dtmfmode = ($provider['dtmfmode'] === 'rfc2833') ? 'rfc4733' : $provider['dtmfmode'];
277
            $options  = [
278
                'type'            => 'endpoint',
279
                '100rel'          => "no",
280
                'context'         => "{$context_id}-incoming",
281
                'dtmf_mode'       => $dtmfmode,
282
                'disallow'        => 'all',
283
                'allow'           => $provider['codecs'],
284
                'rtp_symmetric'   => 'yes',
285
                'force_rport'     => 'yes',
286
                'rewrite_contact' => 'yes',
287
                'ice_support'     => 'no',
288
                'direct_media'    => 'no',
289
                'from_user'       => $from_user,
290
                'from_domain'     => $fromdomain,
291
                'sdp_session'     => 'mikopbx',
292
                'language'        => $lang,
293
                'aors'            => $provider['uniqid'],
294
                'timers'          => ' no',
295
            ];
296
            if ('1' !== $provider['receive_calls_without_auth']) {
297
                $options['outbound_auth'] = "{$provider['uniqid']}-OUT";
298
            }
299
            $prov_config .= "[{$provider['uniqid']}]\n";
300
            $prov_config .= Util::overrideConfigurationArray($options, $manual_attributes, 'endpoint');
301
        }
302
303
        $conf .= $reg_strings;
304
        $conf .= $prov_config;
305
306
        return $conf;
307
    }
308
309
    /**
310
     * Генератор сеции пиров для sip.conf
311
     *
312
     *
313
     * @return string
314
     */
315
    public function generatePeersPj(): string
316
    {
317
        if ($this->data_peers===null){
318
            $this->getSettings();
319
        }
320
        $lang              = $this->generalSettings['PBXLanguage'];
321
        $additionalModules = $this->di->getShared('pbxConfModules');
322
        $conf              = '';
323
324
        foreach ($this->data_peers as $peer) {
325
            $manual_attributes = Util::parseIniSettings($peer['manualattributes'] ?? '');
326
327
            $language = str_replace('_', '-', strtolower($lang));
328
            $language = (trim($language) === '') ? 'en-en' : $language;
329
330
            $calleridname = (trim($peer['calleridname']) === '') ? $peer['extension'] : $peer['calleridname'];
331
            $busylevel    = (trim($peer['busylevel']) === '') ? '1' : '' . $peer['busylevel'];
332
333
            $options = [
334
                'type'     => 'auth',
335
                'username' => $peer['extension'],
336
                'password' => $peer['secret'],
337
            ];
338
            $conf    .= "[{$peer['extension']}] \n";
339
            $conf    .= Util::overrideConfigurationArray($options, $manual_attributes, 'auth');
340
341
            $options = [
342
                'type'              => 'aor',
343
                'qualify_frequency' => '60',
344
                'qualify_timeout'   => '5',
345
                'max_contacts'      => '5',
346
            ];
347
            $conf    .= "[{$peer['extension']}] \n";
348
            $conf    .= Util::overrideConfigurationArray($options, $manual_attributes, 'aor');
349
350
            $dtmfmode = ($peer['dtmfmode'] === 'rfc2833') ? 'rfc4733' : $peer['dtmfmode'];
351
            $options  = [
352
                'type'                 => 'endpoint',
353
                // 'transport'            => 'transport-udp',
354
                'context'              => 'all_peers',
355
                'dtmf_mode'            => $dtmfmode,
356
                'disallow'             => 'all',
357
                'allow'                => $peer['codecs'],
358
                'rtp_symmetric'        => 'yes',
359
                'force_rport'          => 'yes',
360
                'rewrite_contact'      => 'yes',
361
                'ice_support'          => 'no',
362
                'direct_media'         => 'no',
363
                'callerid'             => "{$calleridname} <{$peer['extension']}>",
364
                // 'webrtc'   => 'yes',
365
                'send_pai'             => 'yes',
366
                'call_group'           => '1',
367
                'pickup_group'         => '1',
368
                'sdp_session'          => 'mikopbx',
369
                'language'             => $language,
370
                'mailboxes'            => 'admin@voicemailcontext',
371
                'device_state_busy_at' => $busylevel,
372
                'aors'                 => $peer['extension'],
373
                'auth'                 => $peer['extension'],
374
                'outbound_auth'        => $peer['extension'],
375
                'acl'                  => "acl_{$peer['extension']}",
376
                'timers'               => ' no',
377
            ];
378
            // ---------------- //
379
            $conf .= "[{$peer['extension']}] \n";
380
            $conf .= Util::overrideConfigurationArray($options, $manual_attributes, 'endpoint');
381
382
            foreach ($additionalModules as $Object) {
383
                $conf .= $Object->generatePeerPjAdditionalOptions($peer);
384
            }
385
        }
386
387
        foreach ($additionalModules as $Object) {
388
            // Prevent cycling, skip current class
389
            if (is_a($Object, __CLASS__)) {
390
                continue;
391
            }
392
            $conf .= $Object->generatePeersPj();
393
        }
394
395
        return $conf;
396
    }
397
398
    /**
399
     * Получение настроек.
400
     */
401
    public function getSettings(): void
402
    {
403
        $this->contexts_data  = [];
404
        // Настройки для текущего класса.
405
        $this->data_peers     = $this->getPeers();
406
        $this->data_providers = $this->getProviders();
407
        $this->data_rout      = $this->getOutRoutes();
408
        $this->technology     = self::getTechnology();
409
    }
410
411
    /**
412
     * Получение данных по SIP пирам.
413
     *
414
     * @return array
415
     */
416
    private function getPeers(): array
417
    {
418
        /** @var \MikoPBX\Common\Models\NetworkFilters $network_filter */
419
        /** @var \MikoPBX\Common\Models\Sip $sip_peer */
420
        /** @var \MikoPBX\Common\Models\Extensions $extension */
421
        /** @var \MikoPBX\Common\Models\Users $user */
422
        /** @var \MikoPBX\Common\Models\ExtensionForwardingRights $extensionForwarding */
423
424
        $data    = [];
425
        $db_data = Sip::find("type = 'peer' AND ( disabled <> '1')");
426
        foreach ($db_data as $sip_peer) {
427
            $arr_data       = $sip_peer->toArray();
428
            $network_filter = null;
429
            if (null != $sip_peer->networkfilterid) {
430
                $network_filter = NetworkFilters::findFirst($sip_peer->networkfilterid);
431
            }
432
            $arr_data['permit'] = ($network_filter === null) ? '' : $network_filter->permit;
433
            $arr_data['deny']   = ($network_filter === null) ? '' : $network_filter->deny;
434
435
            // Получим используемые кодеки.
436
            $arr_data['codecs'] = $this->getCodecs();
437
438
            // Имя сотрудника.
439
            $extension = ExtensionsModel::findFirst("number = '{$sip_peer->extension}'");
440
            if (null === $extension) {
441
                $arr_data['publicaccess'] = false;
442
                $arr_data['language']     = '';
443
                $arr_data['calleridname'] = $sip_peer->extension;
444
            } else {
445
                $arr_data['publicaccess'] = $extension->public_access;
446
                $arr_data['calleridname'] = $extension->callerid;
447
                $user                     = Users::findFirst($extension->userid);
448
                if (null !== $user) {
449
                    $arr_data['language'] = $user->language;
450
                    $arr_data['user_id']  = $user->id;
451
                }
452
            }
453
            $extensionForwarding = ExtensionForwardingRights::findFirst("extension = '{$sip_peer->extension}'");
454
            if (null === $extensionForwarding) {
455
                $arr_data['ringlength']              = '';
456
                $arr_data['forwarding']              = '';
457
                $arr_data['forwardingonbusy']        = '';
458
                $arr_data['forwardingonunavailable'] = '';
459
            } else {
460
                $arr_data['ringlength']              = $extensionForwarding->ringlength;
461
                $arr_data['forwarding']              = $extensionForwarding->forwarding;
462
                $arr_data['forwardingonbusy']        = $extensionForwarding->forwardingonbusy;
463
                $arr_data['forwardingonunavailable'] = $extensionForwarding->forwardingonunavailable;
464
            }
465
            $data[] = $arr_data;
466
        }
467
468
        return $data;
469
    }
470
471
    /**
472
     * Возвращает доступные пиру кодеки.
473
     *
474
     * @return array
475
     */
476
    private function getCodecs(): array
477
    {
478
        $arr_codecs = [];
479
        $filter     = [
480
            'conditions'=>'disabled="0"',
481
            'order' => 'type, priority',
482
        ];
483
        $codecs     = Codecs::find($filter);
484
        foreach ($codecs as $codec_data) {
485
            $arr_codecs[] = $codec_data->name;
486
        }
487
488
        return $arr_codecs;
489
    }
490
491
    /**
492
     * Получение данных по SIP провайдерам.
493
     *
494
     * @return array
495
     */
496
    private function getProviders(): array
497
    {
498
        /** @var \MikoPBX\Common\Models\Sip $sip_peer */
499
        /** @var \MikoPBX\Common\Models\NetworkFilters $network_filter */
500
        // Получим настройки всех аккаунтов.
501
        $data    = [];
502
        $db_data = Sip::find("type = 'friend' AND ( disabled <> '1')");
503
        foreach ($db_data as $sip_peer) {
504
            $arr_data                               = $sip_peer->toArray();
505
            $arr_data['receive_calls_without_auth'] = $sip_peer->receive_calls_without_auth;
506
            $network_filter                         = NetworkFilters::findFirst($sip_peer->networkfilterid);
507
            $arr_data['permit']                     = ($network_filter === null) ? '' : $network_filter->permit;
508
            $arr_data['deny']                       = ($network_filter === null) ? '' : $network_filter->deny;
509
510
            // Получим используемые кодеки.
511
            $arr_data['codecs'] = $this->getCodecs();
512
513
            $context_id = preg_replace("/[^a-z\d]/iu", '', $sip_peer->host . $sip_peer->port);
514
            if ( ! isset($this->contexts_data[$context_id])) {
515
                $this->contexts_data[$context_id] = [];
516
            }
517
            $this->contexts_data[$context_id][$sip_peer->uniqid] = $sip_peer->username;
518
519
            $arr_data['context_id'] = $context_id;
520
            $data[]                 = $arr_data;
521
        }
522
523
        return $data;
524
    }
525
526
    /**
527
     * Генератор исходящих контекстов для пиров.
528
     *
529
     * @return array
530
     */
531
    private function getOutRoutes(): array
532
    {
533
        if ($this->data_peers===null){
534
            $this->getSettings();
535
        }
536
        /** @var \MikoPBX\Common\Models\OutgoingRoutingTable $rout */
537
        /** @var \MikoPBX\Common\Models\OutgoingRoutingTable $routs */
538
        /** @var \MikoPBX\Common\Models\Sip $db_data */
539
        /** @var \MikoPBX\Common\Models\Sip $sip_peer */
540
541
        $data    = [];
542
        $routs   = OutgoingRoutingTable::find(['order' => 'priority']);
543
        $db_data = Sip::find("type = 'friend' AND ( disabled <> '1')");
544
        foreach ($routs as $rout) {
545
            foreach ($db_data as $sip_peer) {
546
                if ($sip_peer->uniqid !== $rout->providerid) {
547
                    continue;
548
                }
549
                $arr_data                = $rout->toArray();
550
                $arr_data['description'] = $sip_peer->description;
551
                $arr_data['uniqid']      = $sip_peer->uniqid;
552
                $data[]                  = $arr_data;
553
            }
554
        }
555
556
        return $data;
557
    }
558
559
560
561
    /**
562
     * Генератор extension для контекста peers.
563
     *
564
     * @return string
565
     */
566
    public function extensionGenContexts(): string
567
    {
568
        if ($this->data_peers===null){
569
            $this->getSettings();
570
        }
571
        // Генерация внутреннего номерного плана.
572
        $conf = '';
573
574
        foreach ($this->data_peers as $peer) {
575
            $conf .= "[peer_{$peer['extension']}] \n";
576
            $conf .= "include => internal \n";
577
            $conf .= "include => outgoing \n";
578
        }
579
580
        $contexts = [];
581
        // Входящие контексты.
582
        foreach ($this->data_providers as $provider) {
583
            $contexts_data = $this->contexts_data[$provider['context_id']];
584
            if (count($contexts_data) === 1) {
585
                $conf .= ExtensionsConf::generateIncomingContextPeers($provider['uniqid'], $provider['username'], '');
586
            } elseif ( ! in_array($provider['context_id'], $contexts, true)) {
587
                $conf       .= ExtensionsConf::generateIncomingContextPeers(
588
                    $contexts_data,
589
                    null,
590
                    $provider['context_id']
591
                );
592
                $contexts[] = $provider['context_id'];
593
            }
594
        }
595
596
        return $conf;
597
    }
598
599
    /**
600
     * Генерация хинтов.
601
     *
602
     * @return string
603
     */
604
    public function extensionGenHints(): string
605
    {
606
        if ($this->data_peers===null){
607
            $this->getSettings();
608
        }
609
        $conf = '';
610
        foreach ($this->data_peers as $peer) {
611
            $conf .= "exten => {$peer['extension']},hint,{$this->technology}/{$peer['extension']} \n";
612
        }
613
614
        return $conf;
615
    }
616
617
    public function extensionGenInternal(): string
618
    {
619
        if ($this->data_peers===null){
620
            $this->getSettings();
621
        }
622
        // Генерация внутреннего номерного плана.
623
        $conf = '';
624
        foreach ($this->data_peers as $peer) {
625
            $conf .= "exten => {$peer['extension']},1,Goto(internal-users,{$peer['extension']},1) \n";
626
        }
627
        $conf .= "\n";
628
629
        return $conf;
630
    }
631
632
    public function extensionGenInternalTransfer(): string
633
    {
634
        if ($this->data_peers===null){
635
            $this->getSettings();
636
        }
637
        // Генерация внутреннего номерного плана.
638
        $conf = '';
639
        foreach ($this->data_peers as $peer) {
640
            $conf .= "exten => {$peer['extension']},1,Set(__ISTRANSFER=transfer_) \n";
641
            $conf .= "	same => n,Goto(internal-users,{$peer['extension']},1) \n";
642
        }
643
        $conf .= "\n";
644
645
        return $conf;
646
    }
647
648
    /**
649
     * Returns PJSIP ot SIP uses at PBX
650
     *
651
     * @return string
652
     */
653
    public static function getTechnology(): string
654
    {
655
        return self::TYPE_PJSIP;
656
    }
657
}