Passed
Push — develop ( 11e471...dd688e )
by Портнов
04:29
created

WorkerModelsEvents::rtpReload()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
/*
3
 * MikoPBX - free phone system for small business
4
 * Copyright (C) 2017-2020 Alexey Portnov and Nikolay Beketov
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with this program.
17
 * If not, see <https://www.gnu.org/licenses/>.
18
 */
19
20
namespace MikoPBX\Core\Workers;
21
22
require_once 'Globals.php';
23
24
use MikoPBX\Common\Models\{AsteriskManagerUsers,
25
    CallQueueMembers,
26
    CallQueues,
27
    Codecs,
28
    ConferenceRooms,
29
    CustomFiles,
30
    DialplanApplications,
31
    ExtensionForwardingRights,
32
    Extensions,
33
    ExternalPhones,
34
    Fail2BanRules,
35
    FirewallRules,
36
    Iax,
37
    IncomingRoutingTable,
38
    IvrMenu,
39
    IvrMenuActions,
40
    LanInterfaces,
41
    NetworkFilters,
42
    OutgoingRoutingTable,
43
    OutWorkTimes,
44
    PbxExtensionModules,
45
    PbxSettings,
46
    Sip,
47
    SipHosts,
48
    SoundFiles,
49
    Users
50
};
51
use MikoPBX\Common\Providers\BeanstalkConnectionModelsProvider;
52
use MikoPBX\Common\Providers\ModulesDBConnectionsProvider;
53
use MikoPBX\Common\Providers\PBXConfModulesProvider;
54
use MikoPBX\Core\Asterisk\Configs\QueueConf;
55
use MikoPBX\Core\System\{BeanstalkClient,
56
    Configs\CronConf,
57
    Configs\Fail2BanConf,
58
    Configs\IptablesConf,
59
    Configs\NatsConf,
60
    Configs\NginxConf,
61
    Configs\NTPConf,
62
    Configs\PHPConf,
63
    Configs\SSHConf,
64
    Configs\SyslogConf,
65
    PBX,
66
    Processes,
67
    System,
68
    Util
69
};
70
use MikoPBX\Modules\Config\ConfigClass;
71
use MikoPBX\Modules\PbxExtensionUtils;
72
use MikoPBX\PBXCoreREST\Workers\WorkerApiCommands;
73
use Phalcon\Di;
74
use Pheanstalk\Contract\PheanstalkInterface;
75
76
ini_set('error_reporting', E_ALL);
77
ini_set('display_startup_errors', 1);
78
79
class WorkerModelsEvents extends WorkerBase
80
{
81
    private const R_MANAGERS = 'reloadManager';
82
83
    private const R_QUEUES = 'reloadQueues';
84
85
    private const R_DIALPLAN = 'reloadDialplan';
86
87
    private const R_CUSTOM_F = 'updateCustomFiles';
88
89
    private const R_FIREWALL = 'reloadFirewall';
90
91
    private const R_NETWORK = 'networkReload';
92
93
    private const R_IAX = 'reloadIax';
94
95
    private const R_SIP = 'reloadSip';
96
97
    private const R_RTP = 'rtpReload';
98
99
    private const R_PBX_CORE = 'pbxCoreReload';
100
101
    private const R_FEATURES = 'reloadFeatures';
102
103
    private const R_CRON = 'reloadCron';
104
105
    public const  R_NGINX = 'reloadNginx';
106
107
    public const  R_NGINX_CONF = 'reloadNginxConf';
108
109
    public const  R_FAIL2BAN_CONF = 'reloadFail2BanConf';
110
111
    private const R_PHP_FPM = 'reloadPHPFPM';
112
113
    private const R_TIMEZONE = 'updateTomeZone';
114
115
    private const R_SYSLOG = 'restartSyslogD';
116
117
    private const R_SSH = 'reloadSSH';
118
119
    private const R_LICENSE = 'reloadLicense';
120
121
    private const R_NATS = 'reloadNats';
122
123
    private const R_VOICEMAIL = 'reloadVoicemail';
124
125
    private const R_REST_API_WORKER = 'reloadRestAPIWorker';
126
127
    private const R_CALL_EVENTS_WORKER = 'reloadWorkerCallEvents';
128
129
    private const R_PBX_MODULE_STATE = 'afterModuleStateChanged';
130
131
    private const R_MOH = 'reloadMoh';
132
133
    private const R_NTP = 'reloadNtp';
134
135
    private int $last_change;
136
    private array $modified_tables;
137
138
    private int $timeout = 2;
139
    private array $arrObject;
140
    private array $PRIORITY_R;
141
    private array $pbxSettingsDependencyTable = [];
142
    private array $modelsDependencyTable = [];
143
    private ConfigClass $modulesConfigObj;
144
145
    /**
146
     * The entry point
147
     *
148
     * @param $params
149
     */
150
    public function start($params): void
151
    {
152
        $this->last_change      = time() - 2;
153
        $this->arrObject        = $this->di->getShared(PBXConfModulesProvider::SERVICE_NAME);
154
        $this->modulesConfigObj = new ConfigClass();
155
156
        $this->initPbxSettingsDependencyTable();
157
        $this->initModelsDependencyTable();
158
159
        $this->PRIORITY_R = [
160
            self::R_PBX_MODULE_STATE,
161
            self::R_TIMEZONE,
162
            self::R_SYSLOG,
163
            self::R_REST_API_WORKER,
164
            self::R_NETWORK,
165
            self::R_FIREWALL,
166
            self::R_FAIL2BAN_CONF,
167
            self::R_SSH,
168
            self::R_LICENSE,
169
            self::R_NATS,
170
            self::R_NTP,
171
            self::R_PHP_FPM,
172
            self::R_NGINX,
173
            self::R_NGINX_CONF,
174
            self::R_CRON,
175
            self::R_PBX_CORE,
176
            self::R_FEATURES,
177
            self::R_SIP,
178
            self::R_RTP,
179
            self::R_IAX,
180
            self::R_DIALPLAN,
181
            self::R_QUEUES,
182
            self::R_MANAGERS,
183
            self::R_CUSTOM_F,
184
            self::R_VOICEMAIL,
185
            self::R_MOH,
186
            self::R_CALL_EVENTS_WORKER,
187
        ];
188
189
        $this->modified_tables = [];
190
191
        /** @var BeanstalkClient $client */
192
        $client = $this->di->getShared(BeanstalkConnectionModelsProvider::SERVICE_NAME);
193
        $client->subscribe(self::class, [$this, 'processModelChanges']);
194
        $client->subscribe($this->makePingTubeName(self::class), [$this, 'pingCallBack']);
195
        $client->setTimeoutHandler([$this, 'timeoutHandler']);
196
197
        while ($this->needRestart === false) {
198
            $client->wait();
199
        }
200
        // Execute all collected changes before exit
201
        $this->timeoutHandler();
202
    }
203
204
    /**
205
     * Инициализация таблицы зависимостей настроек m_PbxSettings и сервисов АТС.
206
     */
207
    private function initPbxSettingsDependencyTable(): void
208
    {
209
        $tables = [];
210
        // FeaturesSettings
211
        $tables[] = [
212
            'settingName' => [
213
                'PBXLanguage',
214
                'PBXInternalExtensionLength',
215
                'PBXRecordCalls',
216
                'PBXCallParkingExt',
217
                'PBXCallParkingStartSlot',
218
                'PBXCallParkingEndSlot',
219
                'PBXFeatureAttendedTransfer',
220
                'PBXFeatureBlindTransfer',
221
                'PBXFeatureDigitTimeout',
222
                'PBXFeatureAtxferNoAnswerTimeout',
223
                'PBXFeatureTransferDigitTimeout',
224
                'PBXFeaturePickupExten',
225
            ],
226
            'functions'   => [
227
                self::R_FEATURES,
228
                self::R_DIALPLAN,
229
            ],
230
        ];
231
        // AMIParameters
232
        $tables[] = [
233
            'settingName' => [
234
                'AMIPort',
235
                'AJAMPort',
236
                'AJAMPortTLS',
237
            ],
238
            'functions'   => [
239
                self::R_MANAGERS,
240
            ],
241
        ];
242
243
        // IaxParameters
244
        $tables[] = [
245
            'settingName' => [
246
                'IAXPort',
247
            ],
248
            'functions'   => [
249
                self::R_IAX,
250
            ],
251
        ];
252
        // Гостевые звонки без авторизацим.
253
        $tables[] = [
254
            'settingName' => [
255
                'PBXAllowGuestCalls',
256
            ],
257
            'functions'   => [
258
                self::R_SIP,
259
                self::R_DIALPLAN,
260
            ],
261
        ];
262
        // SipParameters
263
        $tables[] = [
264
            'settingName' => [
265
                'SIPPort',
266
                'SIPDefaultExpiry',
267
                'SIPMinExpiry',
268
                'SIPMaxExpiry',
269
                'PBXLanguage',
270
            ],
271
            'functions'   => [
272
                self::R_SIP,
273
            ],
274
        ];
275
276
        $tables[] = [
277
            'settingName' => [
278
                'RTPPortFrom',
279
                'RTPPortTo',
280
                'RTPStunServer',
281
            ],
282
            'functions'   => [
283
                self::R_RTP,
284
            ],
285
        ];
286
287
        // SSHParameters
288
        $tables[] = [
289
            'settingName' => [
290
                'SSHPort',
291
                'SSHPassword',
292
                'SSHAuthorizedKeys',
293
                'SSHRsaKey',
294
                'SSHDssKey',
295
                'SSHecdsaKey',
296
            ],
297
            'functions'   => [
298
                self::R_SSH,
299
            ],
300
        ];
301
302
        // FirewallParameters
303
        $tables[] = [
304
            'settingName' => [
305
                'SIPPort',
306
                'RTPPortFrom',
307
                'RTPPortTo',
308
                'IAXPort',
309
                'AMIPort',
310
                'AJAMPort',
311
                'AJAMPortTLS',
312
                'WEBPort',
313
                'WEBHTTPSPort',
314
                'SSHPort',
315
                'PBXFirewallEnabled',
316
                'PBXFail2BanEnabled',
317
            ],
318
            'functions'   => [
319
                self::R_FIREWALL,
320
            ],
321
            'strPosKey'   => 'FirewallSettings',
322
        ];
323
324
        // FirewallParameters
325
        $tables[] = [
326
            'settingName' => [
327
                'WEBPort',
328
                'WEBHTTPSPort',
329
                'WEBHTTPSPublicKey',
330
                'WEBHTTPSPrivateKey',
331
                'RedirectToHttps',
332
            ],
333
            'functions'   => [
334
                self::R_NGINX,
335
            ],
336
        ];
337
338
        // CronParameters
339
        $tables[] = [
340
            'settingName' => [
341
                'RestartEveryNight',
342
            ],
343
            'functions'   => [
344
                self::R_CRON,
345
            ],
346
        ];
347
348
        // DialplanParameters
349
        $tables[] = [
350
            'settingName' => [
351
                'PBXLanguage',
352
                'PBXRecordAnnouncementIn',
353
                'PBXRecordAnnouncementOut',
354
            ],
355
            'functions'   => [
356
                self::R_DIALPLAN,
357
            ],
358
        ];
359
        // DialplanParameters
360
        $tables[] = [
361
            'settingName' => [
362
                'PBXLanguage',
363
            ],
364
            'functions'   => [
365
                self::R_PBX_CORE,
366
            ],
367
        ];
368
369
        // VoiceMailParameters
370
        $tables[] = [
371
            'settingName' => [
372
                'MailTplVoicemailSubject',
373
                'MailTplVoicemailBody',
374
                'MailSMTPSenderAddress',
375
                'MailSMTPUsername',
376
                'PBXTimezone',
377
                'VoicemailNotificationsEmail',
378
                'SystemNotificationsEmail',
379
            ],
380
            'functions'   => [
381
                self::R_VOICEMAIL,
382
            ],
383
        ];
384
385
        // VisualLanguageSettings
386
        $tables[] = [
387
            'settingName' => [
388
                'SSHLanguage',
389
                'WebAdminLanguage',
390
            ],
391
            'functions'   => [
392
                self::R_REST_API_WORKER,
393
            ],
394
        ];
395
396
        // LicenseSettings
397
        $tables[] = [
398
            'settingName' => [
399
                'PBXLicense',
400
            ],
401
            'functions'   => [
402
                self::R_LICENSE,
403
                self::R_NATS,
404
            ],
405
        ];
406
407
        // TimeZoneSettings
408
        $tables[] = [
409
            'settingName' => [
410
                'PBXTimezone',
411
            ],
412
            'functions'   => [
413
                self::R_TIMEZONE,
414
                self::R_NGINX,
415
                self::R_PHP_FPM,
416
                self::R_REST_API_WORKER,
417
                self::R_SYSLOG,
418
            ],
419
        ];
420
421
        // NTPSettings
422
        $tables[] = [
423
            'settingName' => [
424
                'PBXManualTimeSettings',
425
                'NTPServer',
426
            ],
427
            'functions'   => [
428
                self::R_NTP,
429
            ],
430
        ];
431
432
        // CallRecordSettings
433
        $tables[] = [
434
            'settingName' => [
435
                'PBXRecordCalls',
436
                'PBXSplitAudioThread',
437
            ],
438
            'functions'   => [
439
                self::R_CALL_EVENTS_WORKER,
440
                self::R_DIALPLAN,
441
            ],
442
        ];
443
444
        $this->pbxSettingsDependencyTable = $tables;
445
    }
446
447
    /**
448
     * Инициализация таблицы зависимостей моделей и сервисов АТС.
449
     */
450
    private function initModelsDependencyTable(): void
451
    {
452
        $tables   = [];
453
        $tables[] = [
454
            'settingName' => [
455
                AsteriskManagerUsers::class,
456
            ],
457
            'functions'   => [
458
                self::R_MANAGERS,
459
            ],
460
        ];
461
462
        $tables[] = [
463
            'settingName' => [
464
                CallQueueMembers::class,
465
            ],
466
            'functions'   => [
467
                self::R_QUEUES,
468
            ],
469
        ];
470
471
        $tables[] = [
472
            'settingName' => [
473
                CallQueues::class,
474
            ],
475
            'functions'   => [
476
                self::R_QUEUES,
477
                self::R_DIALPLAN,
478
            ],
479
        ];
480
        $tables[] = [
481
            'settingName' => [
482
                ExternalPhones::class,
483
                Extensions::class,
484
                DialplanApplications::class,
485
                IncomingRoutingTable::class,
486
                IvrMenu::class,
487
                IvrMenuActions::class,
488
                OutgoingRoutingTable::class,
489
                OutWorkTimes::class,
490
                ConferenceRooms::class,
491
            ],
492
            'functions'   => [
493
                self::R_DIALPLAN,
494
            ],
495
        ];
496
497
        $tables[] = [
498
            'settingName' => [
499
                CustomFiles::class,
500
            ],
501
            'functions'   => [
502
                self::R_CUSTOM_F,
503
            ],
504
        ];
505
506
        $tables[] = [
507
            'settingName' => [
508
                Sip::class,
509
            ],
510
            'functions'   => [
511
                self::R_SIP,
512
                self::R_DIALPLAN,
513
                self::R_FIREWALL,
514
            ],
515
        ];
516
517
        $tables[] = [
518
            'settingName' => [
519
                Users::class,
520
                ExtensionForwardingRights::class,
521
            ],
522
            'functions'   => [
523
                self::R_SIP,
524
                self::R_DIALPLAN,
525
            ],
526
        ];
527
528
        $tables[] = [
529
            'settingName' => [
530
                FirewallRules::class,
531
                Fail2BanRules::class,
532
            ],
533
            'functions'   => [
534
                self::R_FIREWALL,
535
            ],
536
        ];
537
538
        $tables[] = [
539
            'settingName' => [
540
                Iax::class,
541
            ],
542
            'functions'   => [
543
                self::R_IAX,
544
                self::R_DIALPLAN,
545
            ],
546
        ];
547
548
        $tables[] = [
549
            'settingName' => [
550
                Codecs::class,
551
            ],
552
            'functions'   => [
553
                self::R_IAX,
554
                self::R_SIP,
555
            ],
556
        ];
557
558
        $tables[] = [
559
            'settingName' => [
560
                SoundFiles::class,
561
            ],
562
            'functions'   => [
563
                self::R_MOH,
564
                self::R_DIALPLAN,
565
            ],
566
        ];
567
568
        $tables[] = [
569
            'settingName' => [
570
                LanInterfaces::class,
571
            ],
572
            'functions'   => [
573
                self::R_NETWORK,
574
                self::R_IAX,
575
                self::R_SIP,
576
            ],
577
        ];
578
579
        $tables[] = [
580
            'settingName' => [
581
                SipHosts::class,
582
            ],
583
            'functions'   => [
584
                self::R_FIREWALL,
585
                self::R_SIP,
586
            ],
587
        ];
588
589
        $tables[] = [
590
            'settingName' => [
591
                NetworkFilters::class,
592
            ],
593
            'functions'   => [
594
                self::R_FIREWALL,
595
                self::R_SIP,
596
                self::R_MANAGERS,
597
            ],
598
        ];
599
600
        $this->modelsDependencyTable = $tables;
601
    }
602
603
    /**
604
     * Timeout handles
605
     */
606
    public function timeoutHandler(): void
607
    {
608
        $this->last_change = time() - $this->timeout;
609
        $this->startReload();
610
    }
611
612
    /**
613
     * Applies changes
614
     *
615
     * @return void
616
     */
617
    private function startReload(): void
618
    {
619
        if (count($this->modified_tables) === 0) {
620
            return;
621
        }
622
        $delta = time() - $this->last_change;
623
        if ($delta < $this->timeout) {
624
            return;
625
        }
626
627
        foreach ($this->PRIORITY_R as $method_name) {
628
            $action     = $this->modified_tables[$method_name] ?? null;
629
            $parameters = $this->modified_tables['parameters'][$method_name] ?? null;
630
            if ($action === null) {
631
                continue;
632
            }
633
            if (method_exists($this, $method_name)) {
634
                Util::sysLogMsg(__METHOD__, "Process changes by {$method_name}", LOG_DEBUG);
635
                if ($parameters === null) {
636
                    $this->$method_name();
637
                } else {
638
                    $this->$method_name($parameters);
639
                }
640
            }
641
        }
642
        // Send information about models changes to additional modules bulky without any details
643
        $this->modulesConfigObj->hookModulesMethod(ConfigClass::MODELS_EVENT_NEED_RELOAD, [$this->modified_tables]);
644
        $this->modified_tables = [];
645
    }
646
647
    /**
648
     * Parses for received Beanstalk message
649
     *
650
     * @param BeanstalkClient $message
651
     *
652
     * @throws \JsonException
653
     */
654
    public function processModelChanges(BeanstalkClient $message): void
655
    {
656
        $receivedMessage = json_decode($message->getBody(), true, 512, JSON_THROW_ON_ERROR);
657
        if ($receivedMessage['source'] === BeanstalkConnectionModelsProvider::SOURCE_INVOKE_ACTION
658
            && in_array($receivedMessage['action'], $this->PRIORITY_R, true))
659
        {
660
            $this->modified_tables[$receivedMessage['action']]               = true;
661
            $this->modified_tables['parameters'][$receivedMessage['action']] = $receivedMessage['parameters'];
662
        } elseif ($receivedMessage['source'] === BeanstalkConnectionModelsProvider::SOURCE_MODELS_CHANGED ) {
663
            $this->fillModifiedTables($receivedMessage);
664
        }
665
        $this->startReload();
666
        if ( ! $receivedMessage) {
667
            return;
668
        }
669
        // Send information about models changes to additional modules with changed data details
670
        $this->modulesConfigObj->hookModulesMethod(ConfigClass::MODELS_EVENT_CHANGE_DATA, [$receivedMessage]);
671
    }
672
673
    /**
674
     * Collects changes to determine which modules must be reloaded or reconfigured
675
     *
676
     * @param array $data
677
     */
678
    private function fillModifiedTables(array $data): void
679
    {
680
        $count_changes = count($this->modified_tables);
681
        $called_class  = $data['model'] ?? '';
682
        Util::sysLogMsg(__METHOD__, "New changes " . $called_class, LOG_DEBUG);
683
684
        $this->getNewSettingsForDependentModules($called_class);
685
        $this->fillModifiedTablesFromModels($called_class);
686
        $this->fillModifiedTablesFromPbxSettingsData($called_class, $data['recordId']);
687
        $this->fillModifiedTablesFromPbxExtensionModules($called_class, $data['recordId']);
688
689
        if ($count_changes === 0 && count($this->modified_tables) > 0) {
690
            // Начинаем отсчет времени при получении первой задачи.
691
            $this->last_change = time();
692
        }
693
    }
694
695
    /**
696
     * Gets new settings for dependence modules tables
697
     *
698
     */
699
    private function getNewSettingsForDependentModules(string $called_class): void
700
    {
701
        foreach ($this->arrObject as $configClassObj) {
702
            try {
703
                $dependencies = call_user_func([$configClassObj, ConfigClass::GET_DEPENDENCE_MODELS]);
704
                if (in_array($called_class, $dependencies, true)
705
                    && method_exists($configClassObj, ConfigClass::GET_SETTINGS)
706
                ) {
707
                    call_user_func([$configClassObj, ConfigClass::GET_SETTINGS]);
708
                }
709
            } catch (\Throwable $e) {
710
                global $errorLogger;
711
                $errorLogger->captureException($e);
712
                Util::sysLogMsg(__METHOD__, $e->getMessage(), LOG_ERR);
713
                continue;
714
            }
715
        }
716
    }
717
718
    /**
719
     * Analysis modified fields on MikoPBX models
720
     *
721
     * @param string $called_class
722
     */
723
    private function fillModifiedTablesFromModels(string $called_class): void
724
    {
725
        foreach ($this->modelsDependencyTable as $dependencyData) {
726
            if ( ! in_array($called_class, $dependencyData['settingName'], true)) {
727
                continue;
728
            }
729
            foreach ($dependencyData['functions'] as $function) {
730
                $this->modified_tables[$function] = true;
731
            }
732
        }
733
    }
734
735
    /**
736
     * Analysis modified fields on m_PbxSettings model record
737
     *
738
     * @param string $called_class
739
     * @param string $recordId
740
     */
741
    private function fillModifiedTablesFromPbxSettingsData(string $called_class, string $recordId): void
742
    {
743
        if (PbxSettings::class !== $called_class) {
744
            return;
745
        }
746
        /** @var PbxSettings $pbxSettings */
747
        $pbxSettings = PbxSettings::findFirstByKey($recordId);
748
        if ($pbxSettings === null) {
749
            return;
750
        }
751
        $settingName = $pbxSettings->key;
752
        foreach ($this->pbxSettingsDependencyTable as $data) {
753
            $additionalConditions = (isset($data['strPosKey']) && strpos($settingName, $data['strPosKey']) !== false);
754
            if ( ! $additionalConditions && ! in_array($settingName, $data['settingName'], true)) {
755
                continue;
756
            }
757
            foreach ($data['functions'] as $function) {
758
                $this->modified_tables[$function] = true;
759
            }
760
        }
761
    }
762
763
    /**
764
     * Analysis modified fields on PbxExtensionModules model record
765
     *
766
     * @param string $called_class
767
     * @param string $recordId
768
     */
769
    private function fillModifiedTablesFromPbxExtensionModules(string $called_class, string $recordId): void
770
    {
771
        if (PbxExtensionModules::class !== $called_class) {
772
            return;
773
        }
774
        $moduleSettings = PbxExtensionModules::findFirstById($recordId);
775
        if ($moduleSettings !== null) {
776
            self::invokeAction( self::R_PBX_MODULE_STATE, $moduleSettings->toArray(), 50);
777
        }
778
    }
779
780
    /**
781
     * Adds action to queue for postpone apply
782
     *
783
     * @param string $action
784
     * @param array  $parameters
785
     * @param int    $priority
786
     */
787
    public static function invokeAction(string $action, array $parameters = [], int $priority = 0): void
788
    {
789
        $di = Di::getDefault();
790
        if(!$di){
791
            return;
792
        }
793
        /** @var BeanstalkClient $queue */
794
        $queue   = $di->getShared(BeanstalkConnectionModelsProvider::SERVICE_NAME);
795
        $jobData = json_encode(
796
            [
797
                'source'     => BeanstalkConnectionModelsProvider::SOURCE_INVOKE_ACTION,
798
                'action'     => $action,
799
                'parameters' => $parameters,
800
                'model'      => ''
801
            ]
802
        );
803
        $queue->publish(
804
            $jobData,
805
            self::class,
806
            $priority,
807
            PheanstalkInterface::DEFAULT_DELAY,
808
            3600
809
        );
810
    }
811
812
    /**
813
     * Restarts gnats queue server daemon
814
     */
815
    public function reloadNats(): void
816
    {
817
        $natsConf = new NatsConf();
818
        $natsConf->reStart();
819
    }
820
821
    /**
822
     * Reloads Asterisk dialplan
823
     */
824
    public function reloadDialplan(): void
825
    {
826
        PBX::dialplanReload();
827
    }
828
829
    /**
830
     * Reloads Asterisk manager interface module
831
     */
832
    public function reloadManager(): void
833
    {
834
        PBX::managerReload();
835
    }
836
837
    /**
838
     * Generates queue.conf and restart asterisk queue module
839
     */
840
    public function reloadQueues(): void
841
    {
842
        QueueConf::queueReload();
843
    }
844
845
    /**
846
     * Updates custom changes in config files
847
     */
848
    public function updateCustomFiles(): void
849
    {
850
        System::updateCustomFiles();
851
    }
852
853
    /**
854
     * Applies iptables settings and restart firewall
855
     */
856
    public function reloadFirewall(): void
857
    {
858
        IptablesConf::updateFirewallRules();
859
        IptablesConf::reloadFirewall();
860
    }
861
862
    public function pbxCoreReload(): void
863
    {
864
        PBX::coreRestart();
865
    }
866
867
    /**
868
     *  Refreshes networks configs and restarts network daemon
869
     */
870
    public function networkReload(): void
871
    {
872
        System::networkReload();
873
    }
874
875
    /**
876
     * Refreshes IAX configs and reload iax2 module
877
     */
878
    public function reloadIax(): void
879
    {
880
        PBX::iaxReload();
881
    }
882
883
    /**
884
     * Reloads MOH file list in Asterisk.
885
     */
886
    public function reloadMoh(): void
887
    {
888
        PBX::mohReload();
889
    }
890
891
    /**
892
     * Refreshes SIP configs and reload PJSIP module
893
     */
894
    public function reloadSip(): void
895
    {
896
        PBX::sipReload();
897
    }
898
899
    /**
900
     * Update RTP config file.
901
     */
902
    public function rtpReload(): void
903
    {
904
        PBX::rtpReload();
905
    }
906
907
    /**
908
     *  Refreshes features configs and reload features module
909
     */
910
    public function reloadFeatures(): void
911
    {
912
        PBX::featuresReload();
913
    }
914
915
    /**
916
     * Restarts CROND daemon
917
     */
918
    public function reloadCron(): void
919
    {
920
        $cron = new CronConf();
921
        $cron->reStart();
922
    }
923
924
    /**
925
     * Restarts NTP daemon
926
     */
927
    public function reloadNtp(): void
928
    {
929
        NTPConf::configure();
930
    }
931
932
    /**
933
     * Restarts Nginx daemon
934
     */
935
    public function reloadNginx(): void
936
    {
937
        $nginxConf = new NginxConf();
938
        $nginxConf->generateConf();
939
        $nginxConf->reStart();
940
    }
941
942
    /**
943
     * Applies modules locations changes and restarts Nginx daemon
944
     */
945
    public function reloadNginxConf(): void
946
    {
947
        $nginxConf = new NginxConf();
948
        $nginxConf->generateModulesConfigs();
949
        $nginxConf->reStart();
950
    }
951
952
    /**
953
     * Restarts Fail2Ban daemon
954
     */
955
    public function reloadFail2BanConf(): void
956
    {
957
        Fail2BanConf::reloadFail2ban();
958
    }
959
960
    /**
961
     * Restarts PHP-FPM daemon
962
     */
963
    public function reloadPHPFPM(): void
964
    {
965
        PHPConf::reStart();
966
    }
967
968
    /**
969
     * Configures SSH settings
970
     */
971
    public function reloadSSH(): void
972
    {
973
        $sshConf = new SSHConf();
974
        $sshConf->configure();
975
    }
976
977
    /**
978
     * Reconfigures TomeZone settings
979
     */
980
    public function updateTomeZone(): void
981
    {
982
        System::timezoneConfigure();
983
    }
984
985
    /**
986
     * Restarts rsyslog.
987
     */
988
    public function restartSyslogD(): void
989
    {
990
        // Рестарт демона Syslog.
991
        $syslogConf = new SyslogConf();
992
        $syslogConf->reStart();
993
    }
994
995
    /**
996
     *  Reloads Asterisk voicemail module
997
     */
998
    public function reloadVoicemail(): void
999
    {
1000
        PBX::voicemailReload();
1001
    }
1002
1003
    /**
1004
     *  Reloads WorkerApiCommands worker
1005
     */
1006
    public function reloadRestAPIWorker(): void
1007
    {
1008
        Processes::processPHPWorker(WorkerApiCommands::class);
1009
    }
1010
1011
    /**
1012
     *  Reloads WorkerCallEvents worker
1013
     */
1014
    public function reloadWorkerCallEvents(): void
1015
    {
1016
        Processes::processPHPWorker(WorkerCallEvents::class);
1017
    }
1018
1019
    /**
1020
     * Process after PBXExtension state changes
1021
     *
1022
     * @param array $pbxModuleRecord
1023
     */
1024
    public function afterModuleStateChanged(array $pbxModuleRecord): void
1025
    {
1026
        // // Recreate modules array
1027
        PBXConfModulesProvider::recreateModulesProvider();
1028
        //
1029
        // // Recreate database connections
1030
        ModulesDBConnectionsProvider::recreateModulesDBConnections();
1031
1032
        $this->arrObject = $this->di->get(PBXConfModulesProvider::SERVICE_NAME);
1033
1034
        $className       = str_replace('Module', '', $pbxModuleRecord['uniqid']);
1035
        $configClassName = "\\Modules\\{$pbxModuleRecord['uniqid']}\\Lib\\{$className}Conf";
1036
        if (class_exists($configClassName)) {
1037
            $configClassObj = new $configClassName();
1038
1039
            // Reconfigure fail2ban and restart iptables
1040
            if (method_exists($configClassObj, ConfigClass::GENERATE_FAIL2BAN_JAILS)
1041
                && ! empty(call_user_func([$configClassObj, ConfigClass::GENERATE_FAIL2BAN_JAILS]))) {
1042
                $this->modified_tables[self::R_FAIL2BAN_CONF] = true;
1043
            }
1044
1045
            // Refresh Nginx conf if module has any locations
1046
            if (method_exists($configClassObj, ConfigClass::CREATE_NGINX_LOCATIONS)
1047
                && ! empty(call_user_func([$configClassObj, ConfigClass::CREATE_NGINX_LOCATIONS]))) {
1048
                $this->modified_tables[self::R_NGINX_CONF] = true;
1049
            }
1050
1051
            // Refresh crontab rules if module has any for it
1052
            if (method_exists($configClassObj, ConfigClass::CREATE_CRON_TASKS)) {
1053
                $tasks = [];
1054
                call_user_func_array([$configClassObj, ConfigClass::CREATE_CRON_TASKS], [&$tasks]);
1055
                if ( ! empty($tasks)) {
1056
                    $this->modified_tables[self::R_CRON] = true;
1057
                }
1058
            }
1059
1060
            // Reconfigure asterisk manager interface
1061
            if (method_exists($configClassObj, ConfigClass::GENERATE_MANAGER_CONF)
1062
                && ! empty(call_user_func([$configClassObj, ConfigClass::GENERATE_MANAGER_CONF]))) {
1063
                 $this->modified_tables[self::R_MANAGERS] = true;
1064
            }
1065
1066
            // Hook modules AFTER_ methods
1067
            if ($pbxModuleRecord['disabled'] === '1'
1068
                && method_exists($configClassObj, ConfigClass::ON_AFTER_MODULE_DISABLE))
1069
            {
1070
                call_user_func([$configClassObj, ConfigClass::ON_AFTER_MODULE_DISABLE]);
1071
            } elseif ($pbxModuleRecord['disabled'] === '0'
1072
                && method_exists($configClassObj, ConfigClass::ON_AFTER_MODULE_ENABLE))
1073
            {
1074
                call_user_func([$configClassObj, ConfigClass::ON_AFTER_MODULE_ENABLE]);
1075
            }
1076
        }
1077
    }
1078
}
1079
1080
/**
1081
 * The start point
1082
 */
1083
WorkerModelsEvents::startWorker($argv ?? null);