trim($path, '/'), $paths); $paths = array_filter($paths, fn (string $path) => strlen($path) > 0); if (empty($base)) { return implode('/', $paths); } return $base . '/' . implode('/', $paths); } } if (!function_exists('resolve_path')) { function resolve_path(string $path): string { $parts = array_filter(explode('/', $path), fn (string $p) => strlen($p) > 0); $absolutes = []; foreach ($parts as $part) { if ($part == '.') { continue; } if ($part == '..') { array_pop($absolutes); } else { $absolutes[] = $part; } } return implode('/', $absolutes); } } if (!function_exists('plugin_path')) { function plugin_path(string $plugin, string ...$paths): string { return join_paths(base_path('plugins'), $plugin, implode('/', $paths)); } } if (!function_exists('get_ip_from_hostname')) { function get_ip_from_hostname(string $hostname): string|bool { $validARecords = @dns_get_record($hostname, DNS_A); if ($validARecords) { return collect($validARecords)->first()['ip']; } $validAAAARecords = @dns_get_record($hostname, DNS_AAAA); if ($validAAAARecords) { return collect($validAAAARecords)->first()['ipv6']; } return false; } } if (!function_exists('format_number')) { function format_number(int|float $number, ?int $precision = null, ?int $maxPrecision = null): false|string { try { return Number::format($number, $precision, $maxPrecision, user()->language ?? 'en'); } catch (Throwable) { // User language is invalid, so default to english return Number::format($number, $precision, $maxPrecision, 'en'); } } } if (!function_exists('encode_path')) { function encode_path(string $path): string { return implode('/', array_map('rawurlencode', explode('/', $path))); } } if (!function_exists('convert_to_utf8')) { /** * Convert a string to UTF-8 from an unknown encoding */ function convert_to_utf8(string $contents): string { // Valid UTF-8 passes through unchanged if (mb_check_encoding($contents, 'UTF-8')) { return $contents; } // Only detect UTF-16 by BOM instead of mb_check_encoding('UTF-16') which can cause false positives if (str_starts_with($contents, "\xFF\xFE") || str_starts_with($contents, "\xFE\xFF")) { return mb_convert_encoding($contents, 'UTF-8', 'UTF-16'); } // ISO-8859-1 serves as a universal fallback since any byte sequence is valid in it return mb_convert_encoding($contents, 'UTF-8', 'ISO-8859-1'); } } if (!function_exists('user')) { function user(): ?User { return auth(config('auth.defaults.guard', 'web'))->user(); } }