mirror of
https://github.com/HDInnovations/UNIT3D.git
synced 2026-01-31 01:35:31 +01:00
There are no valid cases in the contexts where this function is used where the float will be greater than the range of the int (which is why the `min` functionr returns `mixed`)
220 lines
5.5 KiB
PHP
220 lines
5.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* NOTICE OF LICENSE.
|
|
*
|
|
* UNIT3D Community Edition is open-sourced software licensed under the GNU Affero General Public License v3.0
|
|
* The details is bundled with this project in the file LICENSE.txt.
|
|
*
|
|
* @project UNIT3D Community Edition
|
|
*
|
|
* @author HDVinnie <hdinnovations@protonmail.com>
|
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
|
|
*/
|
|
|
|
namespace App\Helpers;
|
|
|
|
use Illuminate\Support\Facades\DB;
|
|
use Exception;
|
|
|
|
class SystemInformation
|
|
{
|
|
/**
|
|
* @var string[]
|
|
*/
|
|
private const UNITS = ['B', 'KiB', 'MiB', 'GiB', 'TiB'];
|
|
|
|
/**
|
|
* @var string[]
|
|
*/
|
|
private const KNOWN_DATABASES = [
|
|
'sqlite',
|
|
'mysql',
|
|
'pgsql',
|
|
'sqlsrv',
|
|
];
|
|
|
|
/**
|
|
* @return null|array{
|
|
* '1-minute': string,
|
|
* '5-minute': string,
|
|
* '15-minute': string,
|
|
* }
|
|
*/
|
|
public function avg(): ?array
|
|
{
|
|
// cspell:ignore loadavg
|
|
if (is_readable('/proc/loadavg')) {
|
|
$file = file_get_contents('/proc/loadavg');
|
|
|
|
if ($file === false) {
|
|
return null;
|
|
}
|
|
|
|
$loads = explode(' ', $file);
|
|
|
|
return [
|
|
'1-minute' => $loads[0],
|
|
'5-minute' => $loads[1],
|
|
'15-minute' => $loads[2],
|
|
];
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @return null|array{
|
|
* total: string,
|
|
* available: string,
|
|
* used: string,
|
|
* }
|
|
*/
|
|
public function memory(): ?array
|
|
{
|
|
if (is_readable('/proc/meminfo')) {
|
|
$content = file_get_contents('/proc/meminfo');
|
|
|
|
if ($content === false) {
|
|
return null;
|
|
}
|
|
|
|
preg_match('#^MemTotal: \s*(\d*)#m', $content, $matches);
|
|
$total = ((int) $matches[1]) * 1_024;
|
|
preg_match('/^MemAvailable: \s*(\d*)/m', $content, $matches);
|
|
$available = ((int) $matches[1]) * 1_024;
|
|
|
|
return [
|
|
'total' => $this->formatBytes($total),
|
|
'available' => $this->formatBytes($available),
|
|
'used' => $this->formatBytes($total - $available),
|
|
];
|
|
}
|
|
|
|
return [
|
|
'total' => '0',
|
|
'available' => '0',
|
|
'used' => '0',
|
|
];
|
|
}
|
|
|
|
protected function formatBytes(int|float $bytes, int $precision = 2): string
|
|
{
|
|
$bytes = max($bytes, 0);
|
|
$pow = (int) floor(($bytes ? log($bytes) : 0) / log(1_024));
|
|
$pow = min($pow, (\count(self::UNITS)) - 1);
|
|
// Uncomment one of the following alternatives
|
|
$bytes /= 1_024 ** $pow;
|
|
// $bytes /= (1 << (10 * $pow));
|
|
|
|
return round($bytes, $precision).' '.self::UNITS[$pow];
|
|
}
|
|
|
|
/**
|
|
* @return array{
|
|
* total: string,
|
|
* free: string,
|
|
* used: string,
|
|
* }
|
|
*/
|
|
public function disk(): array
|
|
{
|
|
$total = disk_total_space(base_path());
|
|
$free = disk_free_space(base_path());
|
|
|
|
return [
|
|
'total' => $this->formatBytes($total ?: 0),
|
|
'free' => $this->formatBytes($free ?: 0),
|
|
'used' => $this->formatBytes(($total ?: 0) - ($free ?: 0)),
|
|
];
|
|
}
|
|
|
|
public function uptime(): ?float
|
|
{
|
|
if (is_readable('/proc/uptime')) {
|
|
return (float) file_get_contents('/proc/uptime');
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @return array{
|
|
* os: string,
|
|
* php: string,
|
|
* database: string,
|
|
* laravel: string,
|
|
* }
|
|
*/
|
|
public function basic(): array
|
|
{
|
|
return [
|
|
'os' => PHP_OS,
|
|
'php' => PHP_VERSION,
|
|
'database' => $this->getDatabase(),
|
|
'laravel' => app()->version(),
|
|
];
|
|
}
|
|
|
|
private function getDatabase(): string
|
|
{
|
|
if (!\in_array(config('database.default'), self::KNOWN_DATABASES, true)) {
|
|
return 'Unknown';
|
|
}
|
|
|
|
return DB::select('select version()')[0]->{'version()'};
|
|
}
|
|
|
|
/**
|
|
* Get all the directory permissions as well as the recommended ones.
|
|
*
|
|
* @return array<
|
|
* int,
|
|
* array{
|
|
* directory: string,
|
|
* permission: string,
|
|
* recommended: string,
|
|
* }
|
|
* >
|
|
*/
|
|
public function directoryPermissions(): array
|
|
{
|
|
return [
|
|
[
|
|
'directory' => base_path('bootstrap/cache'),
|
|
'permission' => $this->getDirectoryPermission('bootstrap/cache'),
|
|
'recommended' => '0775',
|
|
],
|
|
[
|
|
'directory' => base_path('public'),
|
|
'permission' => $this->getDirectoryPermission('public'),
|
|
'recommended' => '0775',
|
|
],
|
|
[
|
|
'directory' => base_path('storage'),
|
|
'permission' => $this->getDirectoryPermission('storage'),
|
|
'recommended' => '0775',
|
|
],
|
|
[
|
|
'directory' => base_path('vendor'),
|
|
'permission' => $this->getDirectoryPermission('vendor'),
|
|
'recommended' => '0775',
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Get the file permissions for a specific path/file.
|
|
*/
|
|
private function getDirectoryPermission(string $path): string
|
|
{
|
|
try {
|
|
return substr(\sprintf('%o', fileperms(base_path($path))), -4);
|
|
} catch (Exception) {
|
|
return trans('site.error');
|
|
}
|
|
}
|
|
}
|