221 lines
5.0 KiB
PHP
221 lines
5.0 KiB
PHP
<?php
|
|
|
|
|
|
error_reporting(E_ERROR | E_PARSE);
|
|
|
|
define('LARAVEL_START', microtime(true));
|
|
|
|
require_once __DIR__ . '/../autoload.php';
|
|
|
|
class LaravelVsCode
|
|
{
|
|
public static function relativePath($path)
|
|
{
|
|
if (!str_contains($path, base_path())) {
|
|
return (string) $path;
|
|
}
|
|
|
|
return ltrim(str_replace(base_path(), '', realpath($path) ?: $path), DIRECTORY_SEPARATOR);
|
|
}
|
|
|
|
public static function isVendor($path)
|
|
{
|
|
return str_contains($path, base_path("vendor"));
|
|
}
|
|
|
|
public static function outputMarker($key)
|
|
{
|
|
return '__VSCODE_LARAVEL_' . $key . '__';
|
|
}
|
|
|
|
public static function startupError(\Throwable $e)
|
|
{
|
|
throw new Error(self::outputMarker('STARTUP_ERROR') . ': ' . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
try {
|
|
$app = require_once __DIR__ . '/../../bootstrap/app.php';
|
|
} catch (\Throwable $e) {
|
|
LaravelVsCode::startupError($e);
|
|
exit(1);
|
|
}
|
|
|
|
$app->register(new class($app) extends \Illuminate\Support\ServiceProvider
|
|
{
|
|
public function boot()
|
|
{
|
|
config([
|
|
'logging.channels.null' => [
|
|
'driver' => 'monolog',
|
|
'handler' => \Monolog\Handler\NullHandler::class,
|
|
],
|
|
'logging.default' => 'null',
|
|
]);
|
|
}
|
|
});
|
|
|
|
try {
|
|
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
|
|
$kernel->bootstrap();
|
|
} catch (\Throwable $e) {
|
|
LaravelVsCode::startupError($e);
|
|
exit(1);
|
|
}
|
|
|
|
echo LaravelVsCode::outputMarker('START_OUTPUT');
|
|
|
|
$local = collect(\Illuminate\Support\Facades\File::allFiles(config_path()))
|
|
->filter(fn(\Symfony\Component\Finder\SplFileInfo $file) => $file->getExtension() === 'php')
|
|
->map(fn (\Symfony\Component\Finder\SplFileInfo $file) => $file->getPathname())
|
|
->map(fn ($path) => [
|
|
(string) str($path)
|
|
->replace([config_path(DIRECTORY_SEPARATOR), ".php"], "")
|
|
->replace(DIRECTORY_SEPARATOR, "."),
|
|
$path
|
|
]);
|
|
|
|
$vendor = collect(glob(base_path("vendor/**/**/config/*.php")))->map(fn (
|
|
$path
|
|
) => [
|
|
(string) str($path)
|
|
->afterLast(DIRECTORY_SEPARATOR . "config" . DIRECTORY_SEPARATOR)
|
|
->replace(".php", "")
|
|
->replace(DIRECTORY_SEPARATOR, "."),
|
|
$path
|
|
]);
|
|
|
|
$configPaths = $local
|
|
->merge($vendor)
|
|
->groupBy(0)
|
|
->map(fn ($items)=>$items->pluck(1));
|
|
|
|
$cachedContents = [];
|
|
$cachedParsed = [];
|
|
|
|
function vsCodeGetConfigValue($value, $key, $configPaths) {
|
|
$parts = explode(".", $key);
|
|
$toFind = $key;
|
|
$found = null;
|
|
|
|
while (count($parts) > 0) {
|
|
$toFind = implode(".", $parts);
|
|
|
|
if ($configPaths->has($toFind)) {
|
|
$found = $toFind;
|
|
break;
|
|
}
|
|
|
|
array_pop($parts);
|
|
}
|
|
|
|
if ($found === null) {
|
|
return null;
|
|
}
|
|
|
|
$file = null;
|
|
$line = null;
|
|
|
|
if ($found === $key) {
|
|
$file = $configPaths->get($found)[0];
|
|
} else {
|
|
foreach ($configPaths->get($found) as $path) {
|
|
$cachedContents[$path] ??= file_get_contents($path);
|
|
$cachedParsed[$path] ??= token_get_all($cachedContents[$path]);
|
|
|
|
$keysToFind = str($key)
|
|
->replaceFirst($found, "")
|
|
->ltrim(".")
|
|
->explode(".");
|
|
|
|
if (is_numeric($keysToFind->last())) {
|
|
$index = $keysToFind->pop();
|
|
|
|
if ($index !== "0") {
|
|
return null;
|
|
}
|
|
|
|
$key = collect(explode(".", $key));
|
|
$key->pop();
|
|
$key = $key->implode(".");
|
|
$value = "array(...)";
|
|
}
|
|
|
|
$nextKey = $keysToFind->shift();
|
|
$expectedDepth = 1;
|
|
|
|
$depth = 0;
|
|
|
|
foreach ($cachedParsed[$path] as $token) {
|
|
if ($token === "[") {
|
|
$depth++;
|
|
}
|
|
|
|
if ($token === "]") {
|
|
$depth--;
|
|
}
|
|
|
|
if (!is_array($token)) {
|
|
continue;
|
|
}
|
|
|
|
$str = trim($token[1], '"\'');
|
|
|
|
if (
|
|
$str === $nextKey &&
|
|
$depth === $expectedDepth &&
|
|
$token[0] === T_CONSTANT_ENCAPSED_STRING
|
|
) {
|
|
$nextKey = $keysToFind->shift();
|
|
$expectedDepth++;
|
|
|
|
if ($nextKey === null) {
|
|
$file = $path;
|
|
$line = $token[2];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($file) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (is_object($value)) {
|
|
$value = get_class($value);
|
|
}
|
|
|
|
return [
|
|
"name" => $key,
|
|
"value" => $value,
|
|
"file" => $file === null ? null : str_replace(base_path(DIRECTORY_SEPARATOR), '', $file),
|
|
"line" => $line
|
|
];
|
|
}
|
|
|
|
function vsCodeUnpackDottedKey($value, $key) {
|
|
$arr = [$key => $value];
|
|
$parts = explode('.', $key);
|
|
array_pop($parts);
|
|
|
|
while (count($parts)) {
|
|
$arr[implode('.', $parts)] = 'array(...)';
|
|
array_pop($parts);
|
|
}
|
|
|
|
return $arr;
|
|
}
|
|
|
|
echo collect(\Illuminate\Support\Arr::dot(config()->all()))
|
|
->mapWithKeys(fn($value, $key) => vsCodeUnpackDottedKey($value, $key))
|
|
->map(fn ($value, $key) => vsCodeGetConfigValue($value, $key, $configPaths))
|
|
->filter()
|
|
->values()
|
|
->toJson();
|
|
|
|
echo LaravelVsCode::outputMarker('END_OUTPUT');
|
|
|
|
exit(0);
|