From 48515f32bf0bce15b110c4afa9dbc21f214ecc04 Mon Sep 17 00:00:00 2001 From: n0099 Date: Sat, 5 Oct 2024 16:17:26 +0000 Subject: [PATCH] + `App\Controller\AssetController` like `Route::get('/assets/{filename}', ...)` in `be/routes/web.php` + `PrettyJsonResponse` & `ShowReactJsonView` like `App\Http\Middleware\DumpJsonResponse` in `be` + `SerializeToJson` for allowing controller methods to return an array instead of instance of class `Response` directly like laravel @ `App\EventListener` + var `ASSETS_BASE_URL` for config `framework.assets.base_urls` in `config/framework.yaml` @ .env @ symfony --- symfony/.env | 2 + symfony/config/packages/framework.yaml | 4 ++ symfony/src/Controller/AssetController.php | 37 +++++++++++++ .../src/EventListener/PrettyJsonResponse.php | 20 +++++++ symfony/src/EventListener/SerializeToJson.php | 21 ++++++++ .../src/EventListener/ShowReactJsonView.php | 53 +++++++++++++++++++ 6 files changed, 137 insertions(+) create mode 100644 symfony/src/Controller/AssetController.php create mode 100644 symfony/src/EventListener/PrettyJsonResponse.php create mode 100644 symfony/src/EventListener/SerializeToJson.php create mode 100644 symfony/src/EventListener/ShowReactJsonView.php diff --git a/symfony/.env b/symfony/.env index 3dcc9f90..f6b4a514 100644 --- a/symfony/.env +++ b/symfony/.env @@ -14,6 +14,8 @@ # Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2). # https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration +ASSETS_BASE_URL= + ###> symfony/framework-bundle ### APP_ENV=dev APP_SECRET= diff --git a/symfony/config/packages/framework.yaml b/symfony/config/packages/framework.yaml index 877eb25d..8ac12321 100644 --- a/symfony/config/packages/framework.yaml +++ b/symfony/config/packages/framework.yaml @@ -9,6 +9,10 @@ framework: #esi: true #fragments: true + assets: + base_urls: + - '%env(ASSETS_BASE_URL)%' + when@test: framework: test: true diff --git a/symfony/src/Controller/AssetController.php b/symfony/src/Controller/AssetController.php new file mode 100644 index 00000000..c0392ecb --- /dev/null +++ b/symfony/src/Controller/AssetController.php @@ -0,0 +1,37 @@ + /** @lang JSRegexp */'(react(|-dom|-json-view)|scheduler)\.js' + ])] + public function getAsset(string $filename) : Response + { + return new Response( + preg_replace_callback_array([ + '#/npm/(?\w+)@(\d+\.?){3}/\+esm#' => + fn(array $m) => $this->assets->getUrl("assets/{$m['filename']}.js"), + '@^//# sourceMappingURL=.+$@m' => + static fn() => '', + ], $this->filesystem->readFile( + $this->parameterBag->get('kernel.project_dir') . "/public/react-json-view/$filename" + )), + headers: ['Content-Type' => 'text/javascript'] + ); + } +} diff --git a/symfony/src/EventListener/PrettyJsonResponse.php b/symfony/src/EventListener/PrettyJsonResponse.php new file mode 100644 index 00000000..36892d0f --- /dev/null +++ b/symfony/src/EventListener/PrettyJsonResponse.php @@ -0,0 +1,20 @@ +getResponse(); + if ($response instanceof JsonResponse) { + $response->setEncodingOptions(JSON_PRETTY_PRINT); + } + } +} diff --git a/symfony/src/EventListener/SerializeToJson.php b/symfony/src/EventListener/SerializeToJson.php new file mode 100644 index 00000000..534d2b11 --- /dev/null +++ b/symfony/src/EventListener/SerializeToJson.php @@ -0,0 +1,21 @@ +setResponse(JsonResponse::fromJsonString( + $this->serializer->serialize($event->getControllerResult(), 'json') + )); + } +} diff --git a/symfony/src/EventListener/ShowReactJsonView.php b/symfony/src/EventListener/ShowReactJsonView.php new file mode 100644 index 00000000..7d993b47 --- /dev/null +++ b/symfony/src/EventListener/ShowReactJsonView.php @@ -0,0 +1,53 @@ +getRequest(); + $response = $event->getResponse(); + if (!$response instanceof JsonResponse + || !in_array('text/html', $request->getAcceptableContentTypes(), true)) { + return; + } + $json = $response->getContent(); + $jsonLength = mb_strlen($json); + $assetsUrl = collect(['react-json-view', 'react', 'react-dom']) + ->mapWithKeys(fn($asset) => [$asset => $this->assets->getUrl("/assets/$asset.js")]); + $event->setResponse(new Response(<< + + $jsonLength bytes of json response for route {$request->getPathInfo()} + + +

$jsonLength bytes

+
+ + + + + HTML)); + } +}