| 
<?php
 /*
 * This file is part of Chevere.
 *
 * (c) Rodolfo Berrios <[email protected]>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
 
 declare(strict_types=1);
 
 namespace Chevere\Xr;
 
 use Chevere\ThrowableHandler\Formats\ThrowableHandlerHtmlFormat;
 use Chevere\Trace\TraceDocument;
 use Chevere\VarDump\Formats\VarDumpHtmlFormat;
 use Chevere\VarDump\VarDump;
 use Chevere\Writer\Interfaces\WriterInterface;
 use Chevere\Writer\NullWriter;
 use Chevere\Xr\Interfaces\XrMessageInterface;
 use Chevere\Xr\VarDump\Output\XrVarDumpHtmlOutput;
 use Ramsey\Uuid\Provider\Node\RandomNodeProvider;
 use Ramsey\Uuid\Uuid;
 
 final class XrMessage implements XrMessageInterface
 {
 private string $body = '';
 
 private string $topic = '';
 
 private string $emote = '';
 
 private string $filePath = '';
 
 private int $fileLine = 0;
 
 private bool $isFlagBacktrace = false;
 
 private array $vars = [];
 
 private WriterInterface $writer;
 
 private string $id;
 
 public function __construct(private array $backtrace = [])
 {
 if ($backtrace === []) {
 $this->backtrace = debug_backtrace();
 }
 $this->writer = new NullWriter();
 $this->filePath = strval($this->backtrace[0]['file'] ?? '');
 $this->fileLine = intval($this->backtrace[0]['line'] ?? 0);
 $node = (new RandomNodeProvider())->getNode();
 $this->id = Uuid::uuid1($node)->__toString();
 }
 
 public function body(): string
 {
 return $this->body;
 }
 
 public function topic(): string
 {
 return $this->topic;
 }
 
 public function emote(): string
 {
 return $this->emote;
 }
 
 public function filePath(): string
 {
 return $this->filePath;
 }
 
 public function fileLine(): int
 {
 return $this->fileLine;
 }
 
 public function isEnableBacktrace(): bool
 {
 return $this->isFlagBacktrace;
 }
 
 public function vars(): array
 {
 return $this->vars;
 }
 
 public function id(): string
 {
 return $this->id;
 }
 
 public function writer(): WriterInterface
 {
 return $this->writer;
 }
 
 public function withBody(string $body): self
 {
 $new = clone $this;
 $new->body = $body;
 
 return $new;
 }
 
 public function withTopic(string $topic): self
 {
 $new = clone $this;
 $new->topic = $topic;
 
 return $new;
 }
 
 public function withEmote(string $emote): self
 {
 $new = clone $this;
 $new->emote = $emote;
 
 return $new;
 }
 
 public function withWriter(WriterInterface $writer): self
 {
 $new = clone $this;
 $new->writer = $writer;
 
 return $new;
 }
 
 public function withVars(...$vars): self
 {
 $new = clone $this;
 $new->vars = $vars;
 
 return $new;
 }
 
 public function withFlags(int $flags): self
 {
 $new = clone $this;
 if ($flags & XR_BACKTRACE) {
 $new->isFlagBacktrace = true;
 }
 
 return $new;
 }
 
 public function toArray(): array
 {
 $this->handleDumpVars();
 $this->handleBacktrace();
 
 return [
 'body' => $this->body,
 'file_path' => $this->filePath,
 'file_line' => strval($this->fileLine),
 'emote' => $this->emote,
 'topic' => $this->topic,
 'id' => $this->id,
 ];
 }
 
 private function handleDumpVars(): void
 {
 if ($this->vars === []) {
 return;
 }
 (new VarDump(
 new VarDumpHtmlFormat(),
 new XrVarDumpHtmlOutput()
 ))
 ->withVars(...$this->vars)
 ->process($this->writer);
 $dumpString = $this->writer->__toString();
 if ($dumpString !== '') {
 $this->body .= '<div class="dump">' . $dumpString . '</div>';
 }
 }
 
 private function handleBacktrace(): void
 {
 if ($this->isFlagBacktrace) {
 $traceDocument = new TraceDocument(
 $this->backtrace,
 new ThrowableHandlerHtmlFormat()
 );
 $this->body .= '<div class="backtrace">'
 . "\n"
 . $traceDocument->__toString()
 . '</div>';
 }
 }
 }
 
 |