Passed
Push — develop ( 210fde...35e312 )
by Nikolay
04:58
created

SystemMessages::getCountCols()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 6
c 1
b 0
f 0
dl 0
loc 12
rs 10
cc 2
nc 2
nop 0
1
<?php
2
/*
3
 * MikoPBX - free phone system for small business
4
 * Copyright © 2017-2024 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 MikoPBX\Common\Providers\LoggerProvider;
23
use Phalcon\Di;
24
25
/**
26
 * SystemMessages class
27
 *
28
 * @package MikoPBX\Core\System
29
 *
30
 */
31
class SystemMessages extends Di\Injectable
32
{
33
    public const RESULT_DONE = 'Done';
34
    public const RESULT_FAILED = 'Failed';
35
    public const RESULT_SKIPPED = 'Skipped';
36
37
    private static array $defaultTexts = [
38
        self::RESULT_DONE => " \033[32;1mDONE\033[0m \n", // Green for DONE
39
        self::RESULT_FAILED => " \033[31;1mFAIL\033[0m \n",  // Red for FAILED
40
        self::RESULT_SKIPPED => " \033[33;1mSKIP\033[0m \n", // Yellow for SKIPPED
41
    ];
42
43
    /**
44
     * Echoes a result message with progress dots.
45
     *
46
     * @param string $message The result message to echo.
47
     * @param string $result The result status (DONE by default).
48
     *
49
     * @return void
50
     */
51
    public static function teletypeEchoResult(string $message, string $result = self::RESULT_DONE): void
52
    {
53
        $len = max(0, 80 - strlen($message) - 9);
54
        $spaces = str_repeat('.', $len);
55
        $formattedResult = self::getFormattedResult($result);
56
        self::echoToTeletype($spaces.$formattedResult);
57
    }
58
59
    /**
60
     * Echoes a message and logs it to the ttyS0-ttyS5.
61
     *
62
     * @param string $message The message to echo in a serial console.
63
     *
64
     * @return void
65
     */
66
    public static function echoToTeletype(string $message): void
67
    {
68
        // Log to serial tty
69
        for ($i = 0; $i <= 5; $i++) {
70
            $device = "/dev/ttyS$i";
71
            $busyboxPath = Util::which('busybox');
72
            // Get the result of the command execution
73
            $result = shell_exec("$busyboxPath setserial -g \"$device\" | $busyboxPath grep -v unknown 2> /dev/null");
74
            // If the result is not empty
75
            if (!empty($result)) {
76
                // Perform the same
77
                file_put_contents($device, $message, FILE_APPEND);
78
            }
79
        }
80
    }
81
82
    /**
83
     * Prepares formatted result string.
84
     *
85
     * @param string $result The result status.
86
     *
87
     * @return string Formatted result status.
88
     */
89
    private static function getFormattedResult(string $result = self::RESULT_DONE): string
90
    {
91
        if ($result === '1') {
92
            $result = self::RESULT_DONE;
93
        } elseif ($result === '0') {
94
            $result = self::RESULT_FAILED;
95
        }
96
        if (array_key_exists($result, self::$defaultTexts)) {
97
            $resultMessage = self::$defaultTexts[$result];
98
        } else {
99
            $resultMessage = "\033[90m$result\033[0m \n"; // Grey for unknown results
100
        }
101
        return $resultMessage;
102
    }
103
104
    /**
105
     * Echoes a result message with progress dots.
106
     *
107
     * @param string $message The result message to echo.
108
     * @param string $result The result status (DONE by default).
109
     *
110
     * @return void
111
     */
112
    public static function echoResult(string $message, string $result = self::RESULT_DONE): void
113
    {
114
        $cols = self::getCountCols();
115
        if (!is_numeric($cols)) {
116
            // Failed to retrieve the screen width.
117
            return;
118
        }
119
        $len = $cols - strlen($message) - 8;
120
        if ($len < 2) {
121
            // Incorrect screen width.
122
            return;
123
        }
124
125
        $spaces = str_repeat('.', $len);
126
        $formattedResult = self::getFormattedResult($result);
127
        echo $spaces. $formattedResult;
128
    }
129
130
    /**
131
     * Gets the count of columns in the terminal window.
132
     *
133
     * @return string The count of columns.
134
     */
135
    public static function getCountCols(): string
136
    {
137
        $len = 1 * trim(shell_exec('tput cols'));
138
139
        // If the count of columns is zero, set it to a default value of 80
140
        if ($len === 0) {
141
            $len = 80;
142
        } else {
143
            // Limit the count of columns to a maximum of 80
144
            $len = min($len, 80);
145
        }
146
        return $len;
147
    }
148
149
    /**
150
     * Echoes a message and logs it to the system log.
151
     *
152
     * @param string $message The message to echo and log.
153
     *
154
     * @return void
155
     */
156
    public static function echoWithSyslog(string $message): void
157
    {
158
        echo $message;
159
        // Log the message to the system log with LOG_INFO level
160
        self::sysLogMsg(static::class, $message, LOG_INFO);
161
    }
162
163
    /**
164
     * Adds messages to Syslog.
165
     *
166
     * @param string $ident The category, class, or method identification.
167
     * @param string $message The log message.
168
     * @param int $level The log level (default: LOG_WARNING).
169
     *
170
     * @return void
171
     */
172
    public static function sysLogMsg(string $ident, string $message, int $level = LOG_WARNING): void
173
    {
174
        /** @var \Phalcon\Logger $logger */
175
        $logger = Di::getDefault()->getShared(LoggerProvider::SERVICE_NAME);
176
        $logger->log($level, "{$message} on {$ident}");
177
    }
178
179
180
    /**
181
     * Echoes the starting message for a stage.
182
     *
183
     * @param string $message The message to echo.
184
     */
185
    public static function echoStartMsg(string $message): void
186
    {
187
        SystemMessages::echoToTeletype($message);
188
        SystemMessages::echoWithSyslog($message);
189
    }
190
191
    /**
192
     * Echoes the result message for a stage.
193
     *
194
     * @param string $result The result of the stage.
195
     */
196
    public static function echoResultMsg(string $message, string $result = SystemMessages::RESULT_DONE): void
197
    {
198
        SystemMessages::teletypeEchoResult($message, $result);
199
        SystemMessages::echoResult($message, $result);
200
    }
201
}