From a24ea7d34e8eea64880e0818cea4e5b68648a733 Mon Sep 17 00:00:00 2001 From: Joe Tannenbaum Date: Fri, 25 Jul 2025 12:49:57 -0400 Subject: [PATCH 1/4] fix filtering for possible filepaths --- .../Foundation/Console/BroadcastingInstallCommand.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Illuminate/Foundation/Console/BroadcastingInstallCommand.php b/src/Illuminate/Foundation/Console/BroadcastingInstallCommand.php index 6cc442e8c3c7..237c53960077 100644 --- a/src/Illuminate/Foundation/Console/BroadcastingInstallCommand.php +++ b/src/Illuminate/Foundation/Console/BroadcastingInstallCommand.php @@ -312,9 +312,7 @@ protected function injectFrameworkSpecificConfiguration() ]; } - $filePath = array_filter($filePaths, function ($path) { - return file_exists($path); - })[0] ?? null; + $filePath = collect($filePaths)->filter(fn ($path) => file_exists($path))->first(); if (! $filePath) { $this->components->warn("Could not find file [{$filePaths[0]}]. Skipping automatic Echo configuration."); From 40623a6d602bc7c689e0c65f92d203ea587447b8 Mon Sep 17 00:00:00 2001 From: Joe Tannenbaum Date: Fri, 25 Jul 2025 13:58:46 -0400 Subject: [PATCH 2/4] fix import detection and add router before with socket id --- .../Console/BroadcastingInstallCommand.php | 146 +++++++++++++++--- 1 file changed, 127 insertions(+), 19 deletions(-) diff --git a/src/Illuminate/Foundation/Console/BroadcastingInstallCommand.php b/src/Illuminate/Foundation/Console/BroadcastingInstallCommand.php index 237c53960077..ab3ce4e97c9d 100644 --- a/src/Illuminate/Foundation/Console/BroadcastingInstallCommand.php +++ b/src/Illuminate/Foundation/Console/BroadcastingInstallCommand.php @@ -5,6 +5,7 @@ use Composer\InstalledVersions; use Illuminate\Console\Command; use Illuminate\Filesystem\Filesystem; +use Illuminate\Support\Collection; use Illuminate\Support\Env; use Illuminate\Support\Facades\Process; use Symfony\Component\Console\Attribute\AsCommand; @@ -322,36 +323,125 @@ protected function injectFrameworkSpecificConfiguration() $contents = file_get_contents($filePath); - $echoCode = <<driver}', + }); + JS + ]; + + $lines = explode(PHP_EOL, $contents); + + $lastImportLine = 0; + $importOpen = false; + $configureEchoExists = false; + $currentImport = ''; + $imports = []; + + foreach ($lines as $index => $line) { + if (str_contains($line, 'configureEcho')) { + // If the Echo configuration already exists, skip... + $this->components->warn('Echo configuration already exists in ['.basename($filePath).']. Skipping.'); + $configureEchoExists = true; + } + + if (str_starts_with($line, 'import ')) { + $lastImportLine = $index; + $currentImport = $line; + $importOpen = true; + } + + if ($importOpen) { + if ($line !== $currentImport) { + // If the current import line is different from the last one, add it to the imports array... + $currentImport .= ' '.$line; + } + } - configureEcho({ - broadcaster: '{$this->driver}', + if ($importOpen && str_contains($line, ' from ')) { + $importOpen = false; + $lastImportLine = $index; + + $imports[] = $currentImport; + } + } + + $imports = collect($imports)->map( + fn ($import) => str($import)->replace(PHP_EOL, ' ')->trim()->replace('"', "'")->rtrim(';')->toString() + )->mapWithKeys(function ($import) { + $imported = str($import) + ->before(' from ') + ->after('import') + ->trim('{} ') + ->explode(',') + ->map(fn ($part) => trim($part)) + ->filter(); + $from = str($import)->after(' from ')->trim("' ")->toString(); + + return [$from => $imported]; }); - JS; - preg_match_all('/^import .+;$/m', $contents, $matches); + $added = $this->addInertiaRouterBefore($lines, $imports, $lastImportLine); + + if ($added) { + $lastImportLine++; + } - if (empty($matches[0])) { - // Add the Echo configuration to the top of the file if no import statements are found... - $newContents = $echoCode.PHP_EOL.$contents; + if (! $configureEchoExists) { + array_splice($lines, $lastImportLine + 1, 0, $echoLines); + $lastImportLine++; + } - file_put_contents($filePath, $newContents); - } else { - // Add Echo configuration after the last import... - $lastImport = end($matches[0]); + file_put_contents($filePath, implode(PHP_EOL, $lines)); - $positionOfLastImport = strrpos($contents, $lastImport); + $this->components->info('Echo configuration added to ['.basename($filePath).'].'); + } - if ($positionOfLastImport !== false) { - $insertPosition = $positionOfLastImport + strlen($lastImport); - $newContents = substr($contents, 0, $insertPosition).PHP_EOL.$echoCode.substr($contents, $insertPosition); + /** + * Add Inertia router import if Inertia is used. + * + * @param array $lines + * @param \Illuminate\Support\Collection $imports + * @return bool + */ + protected function addInertiaRouterBefore(array &$lines, Collection $imports, int $lastImportLine): bool + { + $inertiaImport = $this->inertiaImport(); - file_put_contents($filePath, $newContents); + if (! $inertiaImport) { + return false; + } + + $routerImport = "import { router } from '{$inertiaImport}';"; + + $content = <<<'JS' + + router.on('before', (event) => { + const id = echo().socketId(); + + if (id) { + event.detail.visit.headers['X-Socket-ID'] = id; } + }); + JS; + + if (! $imports->has($inertiaImport) || ! in_array('router', $imports->get($inertiaImport)->all())) { + array_splice($lines, $lastImportLine + 1, 0, [ + $routerImport, + $content, + ]); + + return true; } - $this->components->info('Echo configuration added to ['.basename($filePath).'].'); + array_splice($lines, $lastImportLine + 1, 0, [ + $content, + ]); + + return true; } /** @@ -493,6 +583,24 @@ protected function appUsesVue(): bool return $this->packageDependenciesInclude('vue'); } + /** + * Detect if the user is using Vue. + * + * @return bool + */ + protected function inertiaImport(): ?string + { + $packages = ['@inertiajs/vue3', '@inertiajs/react', '@inertiajs/svelte']; + + foreach ($packages as $package) { + if ($this->packageDependenciesInclude($package)) { + return $package; + } + } + + return null; + } + /** * Detect if the package is installed. * From 7582168d1876ae768677a3a4eaa7223363569cac Mon Sep 17 00:00:00 2001 From: Joe Tannenbaum Date: Sun, 27 Jul 2025 07:49:24 -0400 Subject: [PATCH 3/4] Update BroadcastingInstallCommand.php --- .../Foundation/Console/BroadcastingInstallCommand.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Illuminate/Foundation/Console/BroadcastingInstallCommand.php b/src/Illuminate/Foundation/Console/BroadcastingInstallCommand.php index ab3ce4e97c9d..92f727f367e6 100644 --- a/src/Illuminate/Foundation/Console/BroadcastingInstallCommand.php +++ b/src/Illuminate/Foundation/Console/BroadcastingInstallCommand.php @@ -584,9 +584,9 @@ protected function appUsesVue(): bool } /** - * Detect if the user is using Vue. + * Detect if the user is using Inertia and return the import path if so. * - * @return bool + * @return string */ protected function inertiaImport(): ?string { From c7d8168d1869342c91ee6cebbf49438e123f4548 Mon Sep 17 00:00:00 2001 From: Joe Tannenbaum Date: Sun, 27 Jul 2025 11:40:56 -0400 Subject: [PATCH 4/4] Update BroadcastingInstallCommand.php --- .../Foundation/Console/BroadcastingInstallCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Foundation/Console/BroadcastingInstallCommand.php b/src/Illuminate/Foundation/Console/BroadcastingInstallCommand.php index 92f727f367e6..db9d5885e1e0 100644 --- a/src/Illuminate/Foundation/Console/BroadcastingInstallCommand.php +++ b/src/Illuminate/Foundation/Console/BroadcastingInstallCommand.php @@ -586,7 +586,7 @@ protected function appUsesVue(): bool /** * Detect if the user is using Inertia and return the import path if so. * - * @return string + * @return string|null */ protected function inertiaImport(): ?string {