diff --git a/app/modules/Ray/Application/Handlers/RemoveSfDumpScriptHandler.php b/app/modules/Ray/Application/Handlers/RemoveSfDumpScriptHandler.php new file mode 100644 index 00000000..b71529fe --- /dev/null +++ b/app/modules/Ray/Application/Handlers/RemoveSfDumpScriptHandler.php @@ -0,0 +1,56 @@ + $payload) { + if (isset($payload['content']) && \is_array($payload['content'])) { + foreach ($payload['content'] as $k => $value) { + if ($k === 'values') { + foreach ($value as $j => $val) { + if (!\str_contains($val, 'Sfdump')) { + continue; + } + $event['payloads'][$i]['content'][$k][$j] = $this->cleanHtml($val); + } + continue; + } + + if (\is_array($value) || !\str_contains($value, 'Sfdump')) { + continue; + } + $event['payloads'][$i]['content'][$k] = $this->cleanHtml($value); + } + } + } + + return $event; + } + + private function cleanHtml(string $html): string + { + // Regex to find all instances of sf-dump- followed by digits + $pattern = '/sf-dump-\d+/'; + // Perform the search + \preg_match($pattern, $html, $matches); + + $sfDumpId = $matches[0] ?? null; + // Remove everything except
tags and their content + return \preg_replace( + '/(?s)(.*?)(]*>.*?<\/pre>)(.*)|(?s)(.*)/', + '$2', + $html, + ) . ''; + } +} diff --git a/app/modules/Ray/Application/RayBootloader.php b/app/modules/Ray/Application/RayBootloader.php index 38bd7bf4..c5eefaaa 100644 --- a/app/modules/Ray/Application/RayBootloader.php +++ b/app/modules/Ray/Application/RayBootloader.php @@ -6,6 +6,7 @@ use App\Application\Service\HttpHandler\HandlerRegistryInterface; use Modules\Ray\Application\Handlers\MergeEventsHandler; +use Modules\Ray\Application\Handlers\RemoveSfDumpScriptHandler; use Modules\Ray\EventHandler; use Modules\Ray\Interfaces\Http\Handler\EventHandler as HttpEventHandler; use Psr\Container\ContainerInterface; @@ -20,6 +21,7 @@ public function defineSingletons(): array ContainerInterface $container, ): EventHandlerInterface => new EventHandler($container, [ MergeEventsHandler::class, + RemoveSfDumpScriptHandler::class, ]), ]; } diff --git a/app/modules/VarDumper/Interfaces/TCP/Service.php b/app/modules/VarDumper/Interfaces/TCP/Service.php index 20780703..71ef532e 100644 --- a/app/modules/VarDumper/Interfaces/TCP/Service.php +++ b/app/modules/VarDumper/Interfaces/TCP/Service.php @@ -50,10 +50,7 @@ private function fireEvent(ParsedPayload $payload): void new HandleReceivedEvent( type: 'var-dump', payload: [ - 'payload' => [ - 'type' => $payload->data->getType(), - 'value' => $this->convertToPrimitive($payload->data), - ], + 'payload' => $this->prepareContent($payload), 'context' => $payload->context, ], project: $payload->context['project'] ?? null, @@ -78,4 +75,19 @@ private function convertToPrimitive(Data $data): BodyInterface|null value: $dumper->dump($data, true), ); } + + private function prepareContent(ParsedPayload $payload): array + { + $payloadContent = [ + 'type' => $payload->data->getType(), + 'value' => $this->convertToPrimitive($payload->data), + ]; + + if ($payload->data->getType() === 'string' && isset($payload->context['language'])) { + $payloadContent['type'] = 'code'; + $payloadContent['language'] = $payload->context['language']; + } + + return $payloadContent; + } } diff --git a/tests/Feature/Interfaces/Http/Ray/RayActionTest.php b/tests/Feature/Interfaces/Http/Ray/RayActionTest.php index f52728bb..98571038 100644 --- a/tests/Feature/Interfaces/Http/Ray/RayActionTest.php +++ b/tests/Feature/Interfaces/Http/Ray/RayActionTest.php @@ -11,7 +11,7 @@ final class RayActionTest extends ControllerTestCase { public const PAYLOAD = <<<'JSON' -{"uuid":"11325003-b9cf-4c06-83d0-8a18fe368ac4","payloads":[{"type":"log","content":{"values":["foo"],"meta":[{"clipboard_data":"foo"}]},"origin":{"file":"\/root\/repos\/buggreagtor\/spiral-app\/tests\/Feature\/Interfaces\/Http\/Ray\/RayActionTest.php","line_number":13,"hostname":"ButschsterLpp"}}],"meta":{"php_version":"8.2.5","php_version_id":80205,"project_name":"","ray_package_version":"1.40.1.0"}} +{"uuid":"11325003-b9cf-4c06-83d0-8a18fe368ac4","payloads": [{"type": "log","content": {"content": "array:2 [\n \"a\" => 1\n \"b\" => array:1 [\n \"c\" => 3\n ]\n]\n\n","label": ""},"origin": {"file": "/app/Modules/Ray/RayCommon.php","line_number": 176,"hostname": "ButschsterLpp"}}],"meta":{"php_version":"8.2.5","php_version_id":80205,"project_name":"","ray_package_version":"1.40.1.0"}} JSON; public function testSendDump(): void @@ -81,7 +81,9 @@ public function testSendDumpViaUserAgent(): void public function testSendDumpWithMerge(): void { - $payload = self::PAYLOAD; + $payload = <<<'JSON' +{"uuid":"11325003-b9cf-4c06-83d0-8a18fe368ac4","payloads":[{"type":"log","content":{"values":["foo"],"meta":[{"clipboard_data":"foo"}]},"origin":{"file":"\/root\/repos\/buggreagtor\/spiral-app\/tests\/Feature\/Interfaces\/Http\/Ray\/RayActionTest.php","line_number":13,"hostname":"ButschsterLpp"}}],"meta":{"php_version":"8.2.5","php_version_id":80205,"project_name":"","ray_package_version":"1.40.1.0"}} +JSON; $color = <<<'JSON' {"uuid":"11325003-b9cf-4c06-83d0-8a18fe368ac4","payloads":[{"type":"color","content":{"color":"red"},"origin":{"file":"\/root\/repos\/buggreagtor\/spiral-app\/tests\/Feature\/Interfaces\/Http\/Ray\/RayActionTest.php","line_number":47,"hostname":"ButschsterLpp"}}],"meta":{"php_version":"8.2.5","php_version_id":80205,"project_name":"","ray_package_version":"1.40.1.0"}} JSON; @@ -125,7 +127,7 @@ public function testSendDumpWithMerge(): void public function assertEventSent(?string $project = null): void { - $this->broadcastig->assertPushed((string)new EventsChannel($project), function (array $data) use ($project) { + $this->broadcastig->assertPushed((string) new EventsChannel($project), function (array $data) use ($project) { $this->assertSame('event.received', $data['event']); $this->assertSame('ray', $data['data']['type']); $this->assertSame($project, $data['data']['project']); @@ -135,7 +137,16 @@ public function assertEventSent(?string $project = null): void $this->assertSame('1.40.1.0', $data['data']['payload']['meta']['ray_package_version']); $this->assertSame('log', $data['data']['payload']['payloads'][0]['type']); - $this->assertSame(['foo'], $data['data']['payload']['payloads'][0]['content']['values']); + $this->assertSame(<<<'HTML' +array:2 [ + "a" => 1 + "b" => array:1 [ + "c" => 3 + ] +] ++HTML +, $data['data']['payload']['payloads'][0]['content']['content']); $this->assertNotEmpty($data['data']['uuid']); $this->assertNotEmpty($data['data']['timestamp']); diff --git a/tests/Feature/Interfaces/TCP/VarDumper/SymfonyV7Test.php b/tests/Feature/Interfaces/TCP/VarDumper/SymfonyV7Test.php index 40ca93d0..ec793fd5 100644 --- a/tests/Feature/Interfaces/TCP/VarDumper/SymfonyV7Test.php +++ b/tests/Feature/Interfaces/TCP/VarDumper/SymfonyV7Test.php @@ -70,6 +70,25 @@ public function testSendObjectDump(): void }); } + public function testSendDumpWithCodeHighlighting(): void + { + $message = $this->buildPayload(var: 'foo', context: ['language' => 'php']); + $this->handleVarDumperRequest($message); + + $this->broadcastig->assertPushed(new EventsChannel(), function (array $data) { + $this->assertSame('event.received', $data['event']); + $this->assertSame('var-dump', $data['data']['type']); + + $this->assertSame([ + 'type' => 'code', + 'value' => 'foo', + 'language' => 'php' + ], $data['data']['payload']['payload']); + + return true; + }); + } + public function testSendDumpWithProject(): void { $this->createProject('default'); @@ -102,13 +121,12 @@ public function testSendInvalidDump(): void $this->handleVarDumperRequest('invalid'); } - private function buildPayload(mixed $var = 'string', ?string $project = null): string + private function buildPayload(mixed $var = 'string', ?string $project = null, array $context = []): string { $cloner = new VarCloner(); $cloner->addCasters(ReflectionCaster::UNSET_CLOSURE_FILE_INFO); $data = $cloner->cloneVar($var); - $context = []; if ($project !== null) { $context['project'] = $project; }