Passed
Push — develop ( b91c6d...602856 )
by Nikolay
05:44 queued 10s
created

System::shutdown()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
c 1
b 0
f 0
dl 0
loc 4
rs 10
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, 7 2020
7
 */
8
9
namespace MikoPBX\Core\System;
10
11
use MikoPBX\Common\Models\CustomFiles;
12
use MikoPBX\Core\System\Configs\CronConf;
13
use MikoPBX\Core\System\Configs\PHPConf;
14
use MikoPBX\Core\System\Configs\NTPConf;
15
use MikoPBX\Core\Asterisk\Configs\{QueueConf};
16
use Phalcon\Di;
17
18
class System extends Di\Injectable
19
{
20
    /**
21
     * System constructor
22
     */
23
    public function __construct()
24
    {
25
        $this->mikoPBXConfig = new MikoPBXConfig();
0 ignored issues
show
Bug Best Practice introduced by
The property mikoPBXConfig does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
26
    }
27
28
    /**
29
     * Returns logs dir
30
     *
31
     * @return string
32
     */
33
    public static function getLogDir(): string
34
    {
35
        $di     = Di::getDefault();
36
        if ($di !== null){
37
            return $di->getConfig()->path('core.logsPath');
38
        }
39
        return '/var/log';
40
    }
41
42
    /**
43
     * Refresh networks configs and restarts network daemon
44
     */
45
    public static function networkReload(): void
46
    {
47
        $network = new Network();
48
        $network->hostnameConfigure();
49
        $network->resolvConfGenerate();
50
        $network->loConfigure();
51
        $network->lanConfigure();
52
    }
53
54
    /**
55
     * Updates custom changes in config files
56
     */
57
    public static function updateCustomFiles()
58
    {
59
        $actions = [];
60
        /** @var \MikoPBX\Common\Models\CustomFiles $res_data */
61
        $res_data = CustomFiles::find("changed = '1'");
62
        foreach ($res_data as $file_data) {
63
            // Always restart asterisk after any custom file change
64
            $actions['asterisk_core_reload'] = 100;
65
            $filename                       = basename($file_data->filepath);
66
            switch ($filename) {
67
                case 'manager.conf':
68
                    $actions['manager'] = 10;
69
                    break;
70
                case 'musiconhold.conf':
71
                    $actions['musiconhold'] = 100;
72
                    break;
73
                case 'modules.conf':
74
                    $actions['modules'] = 10;
75
                    break;
76
                case 'http.conf':
77
                    $actions['manager'] = 10;
78
                    break;
79
                case 'root': // crontabs
80
                    $actions['cron'] = 10;
81
                    break;
82
                case 'queues.conf':
83
                    $actions['queues'] = 10;
84
                    break;
85
                case 'features.conf':
86
                    $actions['features'] = 10;
87
                    break;
88
                case 'ntp.conf':
89
                    $actions['systemtime'] = 100;
90
                    break;
91
                case 'jail.local': // fail2ban
92
                    $actions['firewall'] = 100;
93
                    break;
94
            }
95
        }
96
97
        asort($actions);
98
        self::invokeActions($actions);
99
        foreach ($res_data as $file_data) {
100
            /** @var \MikoPBX\Common\Models\CustomFiles $file_data */
101
            $file_data->writeAttribute("changed", '0');
102
            $file_data->save();
103
        }
104
    }
105
106
    /**
107
     * Batch module restart
108
     *
109
     * @param $actions
110
     *
111
     */
112
    public static function invokeActions($actions):void
113
    {
114
        foreach ($actions as $action => $value) {
115
            $res = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $res is dead and can be removed.
Loading history...
116
            switch ($action) {
117
                case 'manager':
118
                    PBX::managerReload();
119
                    break;
120
                case 'musiconhold':
121
                    PBX::musicOnHoldReload();
122
                    break;
123
                case 'modules':
124
                    PBX::modulesReload();
125
                    break;
126
                case 'cron':
127
                    $cron = new CronConf();
128
                    $cron->reStart();
129
                    break;
130
                case 'queues':
131
                    QueueConf::queueReload();
132
                    break;
133
                case 'features':
134
                    PBX::managerReload();
135
                    break;
136
                case 'systemtime':
137
                    System::setDate('');
138
                    break;
139
                case 'firewall':
140
                    Firewall::reloadFirewall();
141
                    break;
142
                case 'asterisk_core_reload':
143
                    PBX::sipReload();
144
                    PBX::iaxReload();
145
                    PBX::dialplanReload();
146
                    PBX::coreReload();
147
                    break;
148
                default:
149
            }
150
151
        }
152
    }
153
154
    /**
155
     * Loads additioanl kernel modules
156
     */
157
    public function loadKernelModules(): void
158
    {
159
        $modprobePath = Util::which('modprobe');
160
        $ulimitPath = Util::which('ulimit');
161
162
        Util::mwExec("{$modprobePath} -q dahdi");
163
        Util::mwExec("{$modprobePath} -q dahdi_transcode");
164
        Util::mwExec("{$ulimitPath} -n 4096");
165
        Util::mwExec("{$ulimitPath} -p 4096");
166
    }
167
168
169
    /**
170
     * Restart asterisk processor
171
     */
172
    public function onAfterPbxStarted(): void
173
    {
174
        $additionalModules = $this->di->getShared('pbxConfModules');
175
        foreach ($additionalModules as $appClass) {
176
            /** @var \MikoPBX\Modules\Config\ConfigClass $appClass */
177
            $appClass->onAfterPbxStarted();
178
        }
179
    }
180
181
    /**
182
     * Reboots the system after calling system_reboot_cleanup()
183
     */
184
    public static function rebootSync(): void
185
    {
186
        $mikopbx_rebootPath = Util::which('mikopbx_reboot');
187
        Util::mwExec("{$mikopbx_rebootPath} > /dev/null 2>&1");
188
    }
189
190
    /**
191
     * Reboots the system after calling system_reboot_cleanup()
192
     */
193
    public static function rebootSyncBg(): void
194
    {
195
        $mikopbx_rebootPath = Util::which('mikopbx_reboot');
196
        Util::mwExecBg("{$mikopbx_rebootPath} > /dev/null 2>&1");
197
    }
198
199
    /**
200
     * Shutdown the system
201
     */
202
    public static function shutdown(): void
203
    {
204
        $shutdownPath = Util::which('shutdown');
205
        Util::mwExec("{$shutdownPath} > /dev/null 2>&1");
206
    }
207
208
    /**
209
     * Setup system time
210
     *
211
     * @param $date - 2015.12.31-01:01:20
0 ignored issues
show
Documentation Bug introduced by
The doc comment - at position 0 could not be parsed: Unknown type name '-' at position 0 in -.
Loading history...
212
     *
213
     * @return bool
214
     */
215
    public static function setDate($date): bool
216
    {
217
        // Преобразование числа к дате. Если необходимо.
218
        $date = Util::numberToDate($date);
219
        // Валидация даты.
220
        $re_date = '/^\d{4}\.\d{2}\.\d{2}\-\d{2}\:\d{2}\:\d{2}$/';
221
        preg_match_all($re_date, $date, $matches, PREG_SET_ORDER, 0);
222
        if (count($matches) > 0) {
223
            $arr_data         = [];
224
            $datePath         = Util::which('date');
225
            Util::mwExec("{$datePath} -s '{$date}'", $arr_data);
226
        }
227
228
        $sys = new self();
229
        $sys->timezoneConfigure();
230
        return true;
231
    }
232
233
    /**
234
     * Populates /etc/TZ with an appropriate time zone
235
     */
236
    public function timezoneConfigure(): void
237
    {
238
        $timezone = $this->mikoPBXConfig->getGeneralSettings('PBXTimezone');;
239
        @unlink("/etc/TZ");
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

239
        /** @scrutinizer ignore-unhandled */ @unlink("/etc/TZ");

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
240
        @unlink("/etc/localtime");
241
242
        if ($timezone) {
243
            $zone_file = "/usr/share/zoneinfo/{$timezone}";
244
            if ( ! file_exists($zone_file)) {
245
                return;
246
            }
247
            $cpPath = Util::which('cp');
248
            Util::mwExec("{$cpPath}  {$zone_file} /etc/localtime");
249
            file_put_contents('/etc/TZ', $timezone);
250
            putenv("TZ={$timezone}");
251
            Util::mwExec("export TZ;");
252
        }
253
        $ntpConf = new NTPConf();
254
        $ntpConf->configure();
255
        PHPConf::phpTimeZoneConfigure();
256
    }
257
}
258