Passed
Push — develop ( b3fca4...078ece )
by Nikolay
04:51
created

System::getLogDir()   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 © 2017-2023 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\System;
21
22
use DateTime;
23
use DateTimeZone;
24
use MikoPBX\Common\Models\PbxSettings;
25
use MikoPBX\Common\Models\PbxSettingsConstants;
26
use MikoPBX\Core\System\Configs\PHPConf;
27
use MikoPBX\Core\Workers\Libs\WorkerModelsEvents\Actions\ReloadCrondAction;
28
use MikoPBX\Core\Workers\Libs\WorkerModelsEvents\Actions\ReloadManagerAction;
29
use MikoPBX\Core\Workers\WorkerModelsEvents;
30
use Phalcon\Di;
31
32
33
/**
34
 * Class System
35
 *
36
 * This class provides various system-level functionalities.
37
 *
38
 * @package MikoPBX\Core\System
39
 * @property \Phalcon\Config config
40
 */
41
class System extends Di\Injectable
42
{
43
44
    /**
45
     * Returns the directory where logs are stored.
46
     * @deprecated use Directories::getDir(Directories::CORE_LOGS_DIR);
47
     *
48
     * @return string - Directory path where logs are stored.
49
     */
50
    public static function getLogDir(): string
51
    {
52
        return Directories::getDir(Directories::CORE_LOGS_DIR);
53
    }
54
55
    /**
56
     * Restart modules or services based on the provided actions.
57
     * @deprecated use WorkerModelsEvents::invokeAction($actionClassNames);
58
     *
59
     * @param array $actions - The actions to be performed.
60
     *
61
     * @return void
62
     */
63
    public static function invokeActions(array $actions): void
64
    {
65
        // Process each action
66
        foreach ($actions as $action => $value) {
67
            // Restart modules or services based on action
68
            switch ($action) {
69
                case 'manager':
70
                    WorkerModelsEvents::invokeAction(ReloadManagerAction::class);
71
                    break;
72
                case 'cron':
73
                    WorkerModelsEvents::invokeAction(ReloadCrondAction::class);
74
                    break;
75
                default:
76
            }
77
        }
78
    }
79
80
    /**
81
     * Sets the system date and time based on timestamp and timezone.
82
     *
83
     * @param int    $timeStamp - Unix timestamp.
84
     * @param string $remote_tz - Timezone string.
85
     *
86
     * @return bool
87
     * @throws \Exception
88
     */
89
    public static function setDate(int $timeStamp, string $remote_tz): bool
90
    {
91
        $datePath = Util::which('date');
92
93
        // Fetch timezone from database
94
        $db_tz = PbxSettings::getValueByKey(PbxSettingsConstants::PBX_TIMEZONE);
95
        $origin_tz = '';
96
97
        // Read existing timezone from file if it exists
98
        if (file_exists('/etc/TZ')) {
99
            $origin_tz = file_get_contents("/etc/TZ");
100
        }
101
102
        // If the timezones are different, configure the timezone
103
        if ($origin_tz !== $db_tz){
104
            self::timezoneConfigure();
105
        }
106
107
        // Calculate the time offset and set the system time
108
        $origin_tz = $db_tz;
109
        $origin_dtz = new DateTimeZone($origin_tz);
110
        $remote_dtz = new DateTimeZone($remote_tz);
111
        $origin_dt  = new DateTime('now', $origin_dtz);
112
        $remote_dt  = new DateTime('now', $remote_dtz);
113
        $offset     = $origin_dtz->getOffset($origin_dt) - $remote_dtz->getOffset($remote_dt);
114
        $timeStamp  = $timeStamp - $offset;
115
116
        // Execute date command to set system time
117
        Processes::mwExec("{$datePath} +%s -s @{$timeStamp}");
118
119
        return true;
120
    }
121
122
    /**
123
     * Reboots the system after calling system_reboot_cleanup()
124
     *
125
     * @return void
126
     */
127
    public static function reboot(): void
128
    {
129
        $pbx_reboot = Util::which('pbx_reboot');
130
        Processes::mwExec("{$pbx_reboot} > /dev/null 2>&1");
131
    }
132
133
    /**
134
     * Reboots the system after calling system_reboot_cleanup()
135
     * @deprecated Use System::reboot() instead.
136
     * @return void
137
     */
138
    public static function rebootSync(): void
139
    {
140
        System::reboot();
141
    }
142
143
    /**
144
     * Shutdown the system.
145
     */
146
    public static function shutdown(): void
147
    {
148
        $shutdownPath = Util::which('shutdown');
149
        Processes::mwExec("{$shutdownPath} > /dev/null 2>&1");
150
    }
151
152
    /**
153
     * Configures the system timezone according to the PBXTimezone setting.
154
     *
155
     * @return void
156
     */
157
    public static function timezoneConfigure(): void
158
    {
159
        // Get the timezone setting from the database
160
        $timezone = PbxSettings::getValueByKey(PbxSettingsConstants::PBX_TIMEZONE);
161
162
        // If /etc/TZ or /etc/localtime exist, delete them
163
        if (file_exists('/etc/TZ')) {
164
            unlink("/etc/TZ");
165
        }
166
        if (file_exists('/etc/localtime')) {
167
            unlink("/etc/localtime");
168
        }
169
170
        // If a timezone is set, configure it
171
        if ($timezone) {
172
173
            // The path to the zone file
174
            $zone_file = "/usr/share/zoneinfo/{$timezone}";
175
176
            // If the zone file exists, copy it to /etc/localtime
177
            if ( ! file_exists($zone_file)) {
178
                return;
179
            }
180
            $cpPath = Util::which('cp');
181
            Processes::mwExec("{$cpPath}  {$zone_file} /etc/localtime");
182
183
            // Write the timezone to /etc/TZ and set the TZ environment variable
184
            file_put_contents('/etc/TZ', $timezone);
185
            putenv("TZ={$timezone}");
186
187
            // Execute the export TZ command and configure PHP's timezone
188
            Processes::mwExec("export TZ;");
189
            PHPConf::phpTimeZoneConfigure();
190
        }
191
192
    }
193
194
    /**
195
     * Setup locales
196
     * @return void
197
     */
198
    public static function setupLocales(): void
199
    {
200
        $mountPath = Util::which('mount');
201
        shell_exec("$mountPath -o remount,rw /offload 2> /dev/null");
202
        $locales = ['en_US', 'en_GB', 'ru_RU'];
203
        $localeDefPath = Util::which('localedef');
204
        $localePath = Util::which('locale');
205
        foreach ($locales as $locale){
206
            if(Processes::mwExec("$localePath -a | grep $locale") === 0){
207
                continue;
208
            }
209
            shell_exec("$localeDefPath -i $locale -f UTF-8 $locale.UTF-8");
210
        }
211
        shell_exec("$mountPath -o remount,ro /offload 2> /dev/null");
212
    }
213
214
    /**
215
     * Calculate the hash of SSL certificates and extract them from ca-certificates.crt.
216
     *
217
     * @return void
218
     */
219
    public static function sslRehash(): void
220
    {
221
        // Paths to system commands
222
        $openSslPath = Util::which('openssl');
223
        $cutPath     = Util::which('cut');
224
225
        // Get OpenSSL directory and cert file
226
        $openSslDir  = trim(shell_exec("$openSslPath version -d | $cutPath -d '\"' -f 2"));
227
        $certFile    = "$openSslDir/certs/ca-certificates.crt";
228
        $tmpFile     = tempnam('/tmp', 'cert-');
229
        $rawData     = file_get_contents($certFile);
230
        $certs       = explode(PHP_EOL.PHP_EOL, $rawData);
231
        foreach ($certs as $cert){
232
            if(strpos($cert, '-----BEGIN CERTIFICATE-----') === false){
233
                continue;
234
            }
235
            file_put_contents($tmpFile, $cert);
236
            $hash = trim(shell_exec("$openSslPath x509 -subject_hash -noout -in '$tmpFile'"));
237
            rename($tmpFile, "$openSslDir/certs/$hash.0");
238
        }
239
        if(file_exists($tmpFile)){
240
            unlink($tmpFile);
241
        }
242
    }
243
}
244