From ace5829386ae4704674729b50bf3c1221e7ede7a Mon Sep 17 00:00:00 2001 From: Murshal Akhtar Date: Thu, 10 Jul 2025 22:11:23 +0300 Subject: [PATCH] [12.x] Add support for APP_LOCAL_SITES_PATH and APP_REMOTE_SITES_PATH to map editor file paths Update ResolvesDumpSource.php Update ResolvesDumpSourceTest.php Update ResolvesDumpSource.php Update ResolvesDumpSource.php Update ResolvesDumpSourceTest.php --- config/app.php | 27 +++++ .../Concerns/ResolvesDumpSource.php | 27 +++++ .../Concerns/ResolvesDumpSourceTest.php | 98 +++++++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 tests/Foundation/Concerns/ResolvesDumpSourceTest.php diff --git a/config/app.php b/config/app.php index 1ced8bef0a14..1174c6afc237 100644 --- a/config/app.php +++ b/config/app.php @@ -61,6 +61,33 @@ 'asset_url' => env('ASSET_URL'), + /* + |-------------------------------------------------------------------------- + | Application Remote Path Mapping + |-------------------------------------------------------------------------- + | + | If you are using a remote dev server, like Laravel Homestead, Docker, or + | even a remote VPS, it will be necessary to specify your path mapping. + | + | Leaving one, or both of these, empty or null will not trigger the remote + | URL changes and Ignition will treat your editor links as local files. + | + | "remote_sites_path" is an absolute base path for your sites or projects + | in Homestead, Vagrant, Docker, or another remote development server. + | + | Example value: "/home/vagrant/Code" + | + | "local_sites_path" is an absolute base path for your sites or projects + | on your local computer where your IDE or code editor is running on. + | + | Example values: "/Users//Code", "C:\Users\\Documents\Code" + | + */ + + 'remote_sites_path' => env('APP_REMOTE_SITES_PATH', base_path()), + + 'local_sites_path' => env('APP_LOCAL_SITES_PATH', null), + /* |-------------------------------------------------------------------------- | Application Timezone diff --git a/src/Illuminate/Foundation/Concerns/ResolvesDumpSource.php b/src/Illuminate/Foundation/Concerns/ResolvesDumpSource.php index 318ec6c57f3b..5b9a3914da74 100644 --- a/src/Illuminate/Foundation/Concerns/ResolvesDumpSource.php +++ b/src/Illuminate/Foundation/Concerns/ResolvesDumpSource.php @@ -158,6 +158,8 @@ protected function resolveSourceHref($file, $line) return; } + $file = $this->mapToLocalPath($file); + $href = is_array($editor) && isset($editor['href']) ? $editor['href'] : ($this->editorHrefs[$editor['name'] ?? $editor] ?? sprintf('%s://open?file={file}&line={line}', $editor['name'] ?? $editor)); @@ -173,6 +175,31 @@ protected function resolveSourceHref($file, $line) ); } + /** + * Map a remote path to a local path. + * + * This method is used to convert paths from a remote server to the local environment. + * It uses configuration values for the remote and local site paths. + * + * @param string $path + * @return string + */ + public function mapToLocalPath($path) + { + $remoteRoot = config('app.remote_sites_path'); + $hostRoot = config('app.local_sites_path'); + + if (! $remoteRoot || ! $hostRoot || ! $path) { + return $path; // Return original path if config is not set + } + + if (str_starts_with($path, $remoteRoot)) { + return $hostRoot.substr($path, strlen($remoteRoot)); + } + + return $path; + } + /** * Set the resolver that resolves the source of the dump call. * diff --git a/tests/Foundation/Concerns/ResolvesDumpSourceTest.php b/tests/Foundation/Concerns/ResolvesDumpSourceTest.php new file mode 100644 index 000000000000..2553eb52a772 --- /dev/null +++ b/tests/Foundation/Concerns/ResolvesDumpSourceTest.php @@ -0,0 +1,98 @@ +singleton('config', function () { + return $this->createConfig(); + }); + } + + protected function getEnvironmentSetUp($app) + { + // Set config values to simulate Docker path mapping + $app['config']->set('app.local_sites_path', '/path/to/my-app'); + $app['config']->set('app.remote_sites_path', '/var/www/html'); + } + + public function testItMapsRemotePathToLocalPath() + { + $mock = new class + { + use ResolvesDumpSource; + + public function testMap($path) + { + return $this->mapToLocalPath($path); + } + }; + + $originalPath = '/var/www/html/app/Http/Controllers/HomeController.php'; + $expectedPath = '/path/to/my-app/app/Http/Controllers/HomeController.php'; + + $mapped = $mock->testMap($originalPath); + $this->assertEquals($expectedPath, $mapped); + } + + public function testItReturnsOriginalPathWhenNoConfigIsSet() + { + config()->set('app.local_sites_path', null); + config()->set('app.remote_sites_path', null); + + $mock = new class + { + use ResolvesDumpSource; + + public function testMap($path) + { + return $this->mapToLocalPath($path); + } + }; + + $path = '/var/www/html/app/Console/Kernel.php'; + + $this->assertEquals($path, $mock->testMap($path)); + } + + public function testItReturnsOriginalPathWhenPathDoesNotMatchRemote() + { + $mock = new class + { + use ResolvesDumpSource; + + public function testMap($path) + { + return $this->mapToLocalPath($path); + } + }; + + $nonMatchingPath = '/srv/other/path/SomeFile.php'; + + $this->assertEquals($nonMatchingPath, $mock->testMap($nonMatchingPath)); + } + + /** + * Create a new config repository instance. + * + * @return \Illuminate\Config\Repository + */ + protected function createConfig() + { + return new Config([ + 'app' => [ + 'remote_sites_path' => '/var/www/html', + 'local_sites_path' => '/path/to/my-app', + ], + ]); + } +}