116 lines
3.0 KiB
PHP
116 lines
3.0 KiB
PHP
<?php
|
|
|
|
namespace App\Support\Filament;
|
|
|
|
use Illuminate\Support\Facades\Vite;
|
|
|
|
class PanelThemeAsset
|
|
{
|
|
/**
|
|
* @var array<string, bool>
|
|
*/
|
|
private static array $hotAssetReachability = [];
|
|
|
|
public static function resolve(string $entry): ?string
|
|
{
|
|
if (app()->runningUnitTests()) {
|
|
return static::resolveFromManifest($entry);
|
|
}
|
|
|
|
if (static::shouldUseHotAsset($entry)) {
|
|
return Vite::asset($entry);
|
|
}
|
|
|
|
return static::resolveFromManifest($entry);
|
|
}
|
|
|
|
private static function shouldUseHotAsset(string $entry): bool
|
|
{
|
|
$hotFile = public_path('hot');
|
|
|
|
if (! is_file($hotFile)) {
|
|
return false;
|
|
}
|
|
|
|
$hotUrl = trim((string) file_get_contents($hotFile));
|
|
|
|
if ($hotUrl === '') {
|
|
return false;
|
|
}
|
|
|
|
$assetUrl = Vite::asset($entry);
|
|
|
|
if ($assetUrl === '') {
|
|
return false;
|
|
}
|
|
|
|
if (array_key_exists($assetUrl, static::$hotAssetReachability)) {
|
|
return static::$hotAssetReachability[$assetUrl];
|
|
}
|
|
|
|
$parts = parse_url($assetUrl);
|
|
|
|
if (! is_array($parts)) {
|
|
return static::$hotAssetReachability[$assetUrl] = false;
|
|
}
|
|
|
|
$host = $parts['host'] ?? null;
|
|
|
|
if (! is_string($host) || $host === '') {
|
|
return static::$hotAssetReachability[$assetUrl] = false;
|
|
}
|
|
|
|
$scheme = $parts['scheme'] ?? 'http';
|
|
$port = $parts['port'] ?? ($scheme === 'https' ? 443 : 80);
|
|
$transport = $scheme === 'https' ? 'ssl://' : '';
|
|
$connection = @fsockopen($transport.$host, $port, $errorNumber, $errorMessage, 0.2);
|
|
|
|
if (! is_resource($connection)) {
|
|
return static::$hotAssetReachability[$assetUrl] = false;
|
|
}
|
|
|
|
$path = ($parts['path'] ?? '/').(isset($parts['query']) ? '?'.$parts['query'] : '');
|
|
$hostHeader = isset($parts['port']) ? $host.':'.$port : $host;
|
|
|
|
stream_set_timeout($connection, 0, 200000);
|
|
fwrite(
|
|
$connection,
|
|
"HEAD {$path} HTTP/1.1\r\nHost: {$hostHeader}\r\nConnection: close\r\n\r\n",
|
|
);
|
|
|
|
$statusLine = fgets($connection);
|
|
|
|
fclose($connection);
|
|
|
|
if (! is_string($statusLine)) {
|
|
return static::$hotAssetReachability[$assetUrl] = false;
|
|
}
|
|
|
|
return static::$hotAssetReachability[$assetUrl] = preg_match('/^HTTP\/\d\.\d\s+[23]\d\d\b/', $statusLine) === 1;
|
|
}
|
|
|
|
private static function resolveFromManifest(string $entry): ?string
|
|
{
|
|
$manifest = public_path('build/manifest.json');
|
|
|
|
if (! is_file($manifest)) {
|
|
return null;
|
|
}
|
|
|
|
/** @var array<string, array{file?: string}>|null $decoded */
|
|
$decoded = json_decode((string) file_get_contents($manifest), true);
|
|
|
|
if (! is_array($decoded)) {
|
|
return null;
|
|
}
|
|
|
|
$file = $decoded[$entry]['file'] ?? null;
|
|
|
|
if (! is_string($file) || $file === '') {
|
|
return null;
|
|
}
|
|
|
|
return asset('build/'.$file);
|
|
}
|
|
}
|