From fd5da62d662c6e94f6f27f28f8a3f50c63d913a6 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Mon, 14 Sep 2026 15:14:20 -0300 Subject: [PATCH 1/2] feat(view): add the shared comparison captions to `ViewMessage` and the capture guidance to `DbMessage`, so adapters stop carrying those literals. --- composer.json | 2 +- src/Collector/CollectorCoordinator.php | 6 +- src/Comparison/SummaryMetricComparison.php | 28 +-- src/Helper/SensitiveDataRedactor.php | 9 +- src/Helper/Trace.php | 16 +- src/Panel/Asset/AssetPanel.php | 5 +- src/Panel/Config/ConfigSnapshot.php | 5 + src/Panel/Db/DbMessage.php | 8 + src/Panel/Event/EventInspection.php | 10 +- src/Panel/Mail/MailEntry.php | 7 +- src/Panel/PanelRenderContext.php | 6 +- src/Panel/PanelRenderer.php | 2 +- src/Panel/Profile/ProfilingSnapshot.php | 7 +- src/Panel/Queue/QueuePanel.php | 10 +- src/Panel/Request/RequestHeadersRenderer.php | 7 +- src/Panel/Request/RequestHero.php | 103 +++++++++- src/Panel/Request/RequestRenderer.php | 10 +- src/Panel/Request/RequestSectionRenderer.php | 14 +- src/Panel/Request/RequestServerRenderer.php | 7 +- .../Request/Routing/RequestRoutingView.php | 9 +- src/Panel/Request/Routing/RouteBadge.php | 9 +- src/Panel/Request/Routing/RouteDefinition.php | 192 ++++++++++++++++-- src/Panel/Request/Routing/RouteTraceRow.php | 5 + src/Panel/Request/ServerVariableGroup.php | 5 +- src/Panel/Router/CurrentRouteLogRow.php | 15 +- src/Panel/Timeline/TimelineSnapshot.php | 26 +-- src/Panel/User/UserPanel.php | 5 +- src/PhpInfo/PhpInfoDataNormalizer.php | 21 +- src/PhpInfo/PhpInfoTile.php | 18 ++ src/Storage/ArrayPayloadSnapshot.php | 4 +- src/Storage/DebugArray.php | 8 +- src/Storage/DebugSnapshot.php | 15 +- src/Storage/DebugValue.php | 85 +++----- src/Storage/Json.php | 1 + src/Storage/Manifest.php | 12 +- src/Storage/ManifestReadResult.php | 5 +- src/Storage/PanelFailure.php | 26 +-- src/Storage/Payload.php | 5 +- src/Storage/SnapshotReadResult.php | 9 +- src/Storage/SnapshotStore.php | 5 +- src/Storage/SnapshotWriteResult.php | 5 +- src/Toolbar/ToolbarData.php | 8 +- src/Toolbar/ToolbarPanel.php | 39 ++-- src/View/History/CaptureLabel.php | 13 ++ src/View/Sidebar/SidebarRenderer.php | 149 ++++++-------- src/View/ViewMessage.php | 15 ++ tests/Provider/DbMessageProvider.php | 5 + tests/View/Sidebar/SidebarRendererTest.php | 78 ++++++- 48 files changed, 611 insertions(+), 443 deletions(-) diff --git a/composer.json b/composer.json index 5413d88..823529f 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "ext-intl": "*", "ext-mbstring": "*", "ui-awesome/html": "^0.6", - "ui-awesome/html-core-component": "^0.4", + "ui-awesome/html-core-component": "^0.5@dev", "ui-awesome/html-helper": "^0.7", "ui-awesome/html-interop": "^0.4", "ui-awesome/html-mixin": "^0.8.2", diff --git a/src/Collector/CollectorCoordinator.php b/src/Collector/CollectorCoordinator.php index 1507ff5..786bd4c 100644 --- a/src/Collector/CollectorCoordinator.php +++ b/src/Collector/CollectorCoordinator.php @@ -87,11 +87,7 @@ public function capture(RequestSummary $summary): DebugSnapshot } } - return new DebugSnapshot( - $summary, - $panels, - $failures, - ); + return new DebugSnapshot($summary, $panels, $failures); } /** diff --git a/src/Comparison/SummaryMetricComparison.php b/src/Comparison/SummaryMetricComparison.php index 121098a..fc83c7b 100644 --- a/src/Comparison/SummaryMetricComparison.php +++ b/src/Comparison/SummaryMetricComparison.php @@ -133,21 +133,9 @@ private static function formatNumber(float|int $value, string $unit, int $precis * * @return self Metric comparison for the two counters. */ - private static function integerMetric( - string $label, - int $baseline, - int $target, - string|null $panelId = null, - ): self { - return self::numericMetric( - $label, - $baseline, - $target, - 1, - '', - $panelId, - 0, - ); + private static function integerMetric(string $label, int $baseline, int $target, string|null $panelId = null): self + { + return self::numericMetric($label, $baseline, $target, 1, '', $panelId, 0); } /** @@ -181,15 +169,7 @@ private static function nullableFloatMetric( ); } - return self::numericMetric( - $label, - $baseline, - $target, - $scale, - $unit, - $panelId, - 2, - ); + return self::numericMetric($label, $baseline, $target, $scale, $unit, $panelId, 2); } /** diff --git a/src/Helper/SensitiveDataRedactor.php b/src/Helper/SensitiveDataRedactor.php index 2e13fdf..66a8b30 100644 --- a/src/Helper/SensitiveDataRedactor.php +++ b/src/Helper/SensitiveDataRedactor.php @@ -155,14 +155,7 @@ public static function redact( [$keyMap, $prefixes, $patterns] = self::rules($sensitiveKeys, $sensitiveKeyPrefixes, $sensitiveKeyPatterns); - return self::walk( - $value, - $keyMap, - $prefixes, - $patterns, - 0, - $nodes, - ); + return self::walk($value, $keyMap, $prefixes, $patterns, 0, $nodes); } /** diff --git a/src/Helper/Trace.php b/src/Helper/Trace.php index 3e47f72..20afcf4 100644 --- a/src/Helper/Trace.php +++ b/src/Helper/Trace.php @@ -37,10 +37,7 @@ private function __construct(private Closure|string|false $template, private arr */ public static function create(): self { - return new self( - self::DEFAULT_TEMPLATE, - [], - ); + return new self(self::DEFAULT_TEMPLATE, []); } /** @@ -69,6 +66,7 @@ public function render(array $frame): string } $file = $this->mapPath(str_replace('\\', '/', $file)); + $template = $this->template; if ($template === false) { @@ -122,10 +120,7 @@ public function withPathMappings(array $pathMappings): self $normalized[self::normalizePrefix((string) $remote)] = self::normalizePrefix($target); } - return new self( - template: $this->template, - pathMappings: $normalized, - ); + return new self(template: $this->template, pathMappings: $normalized); } /** @@ -140,10 +135,7 @@ public function withPathMappings(array $pathMappings): self */ public function withTemplate(Closure|string|false $template): self { - return new self( - template: $template, - pathMappings: $this->pathMappings, - ); + return new self(template: $template, pathMappings: $this->pathMappings); } /** diff --git a/src/Panel/Asset/AssetPanel.php b/src/Panel/Asset/AssetPanel.php index 8bff2a7..19d8519 100644 --- a/src/Panel/Asset/AssetPanel.php +++ b/src/Panel/Asset/AssetPanel.php @@ -39,10 +39,7 @@ final class AssetPanel extends Panel */ public function present(array $data): PanelView { - $snapshot = AssetSnapshot::fromArray( - $data, - '$.asset', - ); + $snapshot = AssetSnapshot::fromArray($data, '$.asset'); $bundles = $snapshot->bundles(); $vite = $snapshot->vite(); diff --git a/src/Panel/Config/ConfigSnapshot.php b/src/Panel/Config/ConfigSnapshot.php index fd81fc2..b05a7dc 100644 --- a/src/Panel/Config/ConfigSnapshot.php +++ b/src/Panel/Config/ConfigSnapshot.php @@ -23,6 +23,11 @@ public function data(): array return $this->values(); } + /** + * Returns the key under which the configuration payload is stored. + * + * @return string Payload key. + */ protected static function payloadKey(): string { return 'data'; diff --git a/src/Panel/Db/DbMessage.php b/src/Panel/Db/DbMessage.php index 0a5e59b..da232fe 100644 --- a/src/Panel/Db/DbMessage.php +++ b/src/Panel/Db/DbMessage.php @@ -9,6 +9,14 @@ */ enum DbMessage: string { + /** + * Guidance of the empty state, naming the profiler the adapter must wire so statements are captured. + * + * Format: "Configure the development connection with %s. ..." + */ + case CAPTURE_GUIDANCE = 'Configure the development connection with %s. Rows are shown only when the driver ' + . 'reports them. After a redirect, open the previous request from History.'; + /** * Header of the column counting how many times the exact same statement ran. */ diff --git a/src/Panel/Event/EventInspection.php b/src/Panel/Event/EventInspection.php index adcc216..8147cf8 100644 --- a/src/Panel/Event/EventInspection.php +++ b/src/Panel/Event/EventInspection.php @@ -57,7 +57,10 @@ public static function fromArray(mixed $data, string $path): self foreach ($payload->map('context') as $key => $value) { if (!is_string($value) || strlen($value) > 2048 || strlen($key) > 128) { - throw HydrationException::at("{$path}.context.{$key}", 'bounded text'); + throw HydrationException::at( + "{$path}.context.{$key}", + 'bounded text', + ); } $context[$key] = $value; @@ -67,7 +70,10 @@ public static function fromArray(mixed $data, string $path): self foreach ($payload->list('trace') as $index => $value) { if (!is_string($value) || strlen($value) > 2048) { - throw HydrationException::at("{$path}.trace[{$index}]", 'bounded text'); + throw HydrationException::at( + "{$path}.trace[{$index}]", + 'bounded text', + ); } $trace[] = $value; diff --git a/src/Panel/Mail/MailEntry.php b/src/Panel/Mail/MailEntry.php index a4d4a2b..0cbe814 100644 --- a/src/Panel/Mail/MailEntry.php +++ b/src/Panel/Mail/MailEntry.php @@ -79,12 +79,7 @@ private function __construct( */ public static function create(string $from, array $to, string $subject, bool $isSuccessful): self { - return new self( - $from, - $to, - $subject, - $isSuccessful, - ); + return new self($from, $to, $subject, $isSuccessful); } /** diff --git a/src/Panel/PanelRenderContext.php b/src/Panel/PanelRenderContext.php index d78a1ea..0b71ace 100644 --- a/src/Panel/PanelRenderContext.php +++ b/src/Panel/PanelRenderContext.php @@ -46,10 +46,6 @@ public function panelPayload(string $panel): array|null */ public function panelUrl(string|null $panel = null, array|null $queryParams = null): string { - return $this->urls->panel( - $this->tag, - $panel ?? $this->panel, - $queryParams ?? $this->queryParams, - ); + return $this->urls->panel($this->tag, $panel ?? $this->panel, $queryParams ?? $this->queryParams); } } diff --git a/src/Panel/PanelRenderer.php b/src/Panel/PanelRenderer.php index 9505b89..e9bedae 100644 --- a/src/Panel/PanelRenderer.php +++ b/src/Panel/PanelRenderer.php @@ -264,7 +264,7 @@ private function panel(string $name, PanelView $view): string ->html(...$summary) ->render(); - return $heading . $strip . $this->blocks($view->blocks()); + return "{$heading}{$strip}" . $this->blocks($view->blocks()); } /** diff --git a/src/Panel/Profile/ProfilingSnapshot.php b/src/Panel/Profile/ProfilingSnapshot.php index 4440b5b..96e227e 100644 --- a/src/Panel/Profile/ProfilingSnapshot.php +++ b/src/Panel/Profile/ProfilingSnapshot.php @@ -56,12 +56,7 @@ public static function capture(int $memory, float $time, array $messages): self $entries[] = ProfileRow::fromTiming($timing, count($entries)); } - return new self( - $memory, - $time, - $entries, - $samples, - ); + return new self($memory, $time, $entries, $samples); } /** diff --git a/src/Panel/Queue/QueuePanel.php b/src/Panel/Queue/QueuePanel.php index 90bf30d..574f31f 100644 --- a/src/Panel/Queue/QueuePanel.php +++ b/src/Panel/Queue/QueuePanel.php @@ -219,10 +219,7 @@ private function detail(JobRecord $record, int $index): PanelView $url = $this->jobUrls[$index] ?? null; if ($url !== null) { - $fields[QueueMessage::DETAILS->value] = PanelView::link( - QueueMessage::JOB_LINK->value, - $url, - ); + $fields[QueueMessage::DETAILS->value] = PanelView::link(QueueMessage::JOB_LINK->value, $url); } $view = PanelView::create()->overview($fields, true); @@ -324,9 +321,6 @@ private static function status(JobRecord $record): array { $status = self::STATUS[$record->eventType] ?? self::STATUS[JobRecord::TYPE_PUSH]; - return PanelView::badge( - $status['label']->value, - $status['tone'], - ); + return PanelView::badge($status['label']->value, $status['tone']); } } diff --git a/src/Panel/Request/RequestHeadersRenderer.php b/src/Panel/Request/RequestHeadersRenderer.php index 3106328..913443c 100644 --- a/src/Panel/Request/RequestHeadersRenderer.php +++ b/src/Panel/Request/RequestHeadersRenderer.php @@ -39,7 +39,7 @@ public static function render(array $request, array $response): string ->html( H2::tag() ->id('yii-debug-header-exchange-title') - ->content(RequestMessage::HEADER_EXCHANGE->value), + ->content(RequestMessage::HEADER_EXCHANGE), Div::tag() ->class('yii-debug-diagnostic-counts') ->html( @@ -187,9 +187,6 @@ private static function renderLedger(array $entries, bool $response): string ); } - return RequestDiagnosticLedger::render( - 'yii-debug-header-ledger', - ...$rows, - ); + return RequestDiagnosticLedger::render('yii-debug-header-ledger', ...$rows); } } diff --git a/src/Panel/Request/RequestHero.php b/src/Panel/Request/RequestHero.php index e766a76..f4b8b6c 100644 --- a/src/Panel/Request/RequestHero.php +++ b/src/Panel/Request/RequestHero.php @@ -9,72 +9,139 @@ */ final class RequestHero { + /** + * Formatted processing time, in milliseconds; empty when it was not captured. + */ private string $durationMs = ''; - /** + * Boolean flags surfaced as chips on the meta strip, in display order. + * * @var list */ private array $flags = []; - + /** + * Client address of the request; empty when it was not captured. + */ private string $ip = ''; + /** + * Response status code; `0` when no response was captured. + */ private int $statusCode = 0; - + /** + * Status-pill CSS modifier derived from the status code: `'2xx'` to `'5xx'`, or `'none'` when uncaptured. + */ private string $statusVariant = 'none'; - + /** + * Formatted wall-clock time of the request; empty when it was not captured. + */ private string $time = ''; + /** + * @param string $method HTTP method of the request. + * @param string $url Full URL of the request. + */ public function __construct(private string $method, private string $url) {} + /** + * Creates a hero carrying the request identity, ready for immutable enrichment. + * + * @param string $method HTTP method of the request. + * @param string $url Full URL of the request. + * + * @return self Hero carrying only the request identity. + */ public static function create(string $method, string $url): self { return new self($method, $url); } + /** + * Returns the processing time of the request. + * + * @return string Formatted processing time, in milliseconds; empty when it was not captured. + */ public function getDurationMs(): string { return $this->durationMs; } /** - * @return list + * Returns the flags shown on the meta strip. + * + * @return list Boolean flags surfaced as chips on the meta strip, in display order. */ public function getFlags(): array { return $this->flags; } + /** + * Returns the client address of the request. + * + * @return string Client address of the request; empty when it was not captured. + */ public function getIp(): string { return $this->ip; } + /** + * Returns the HTTP method of the request. + * + * @return string HTTP method of the request. + */ public function getMethod(): string { return $this->method; } + /** + * Returns the response status code. + * + * @return int Response status code; `0` when no response was captured. + */ public function getStatusCode(): int { return $this->statusCode; } + /** + * Returns the status-pill modifier of the response. + * + * @return string Status-pill CSS modifier derived from the status code: `'2xx'` to `'5xx'`, or + * `'none'` when uncaptured. + */ public function getStatusVariant(): string { return $this->statusVariant; } + /** + * Returns the wall-clock time of the request. + * + * @return string Formatted wall-clock time of the request; empty when it was not captured. + */ public function getTime(): string { return $this->time; } + /** + * Returns the full URL of the request. + * + * @return string Full URL of the request. + */ public function getUrl(): string { return $this->url; } /** - * @param list $flags + * Returns a copy carrying another set of flags. + * + * @param list $flags Boolean flags surfaced as chips on the meta strip, in display order. + * + * @return self Hero with the flags applied. */ public function withFlags(array $flags): self { @@ -84,6 +151,13 @@ public function withFlags(array $flags): self return $clone; } + /** + * Returns a copy carrying the client address. + * + * @param string $ip Client address of the request; empty when it was not captured. + * + * @return self Hero with the address applied. + */ public function withIp(string $ip): self { $clone = clone $this; @@ -92,6 +166,15 @@ public function withIp(string $ip): self return $clone; } + /** + * Returns a copy carrying the captured response status. + * + * @param int $statusCode Response status code; `0` when no response was captured. + * @param string $statusVariant Status-pill CSS modifier derived from the status code: `'2xx'` to + * `'5xx'`, or `'none'` when uncaptured. + * + * @return self Hero with the status applied. + */ public function withStatus(int $statusCode, string $statusVariant): self { $clone = clone $this; @@ -101,6 +184,14 @@ public function withStatus(int $statusCode, string $statusVariant): self return $clone; } + /** + * Returns a copy carrying the captured timing. + * + * @param string $time Formatted wall-clock time of the request; empty when it was not captured. + * @param string $durationMs Formatted processing time, in milliseconds; empty when it was not captured. + * + * @return self Hero with the timing applied. + */ public function withTiming(string $time, string $durationMs): self { $clone = clone $this; diff --git a/src/Panel/Request/RequestRenderer.php b/src/Panel/Request/RequestRenderer.php index ffb37a8..e78acb0 100644 --- a/src/Panel/Request/RequestRenderer.php +++ b/src/Panel/Request/RequestRenderer.php @@ -127,10 +127,7 @@ private static function renderHeaders(RequestTab|null $tab): string return self::renderSections($tab->sections); } - return RequestHeadersRenderer::render( - $request->entries, - $response->entries, - ); + return RequestHeadersRenderer::render($request->entries, $response->entries); } /** @@ -398,10 +395,7 @@ private static function renderServer(RequestTab $tab, RequestView $view): string return self::renderSections($tab->sections); } - return RequestServerRenderer::renderForRequest( - $tab->sections[0]->entries, - $view, - ); + return RequestServerRenderer::renderForRequest($tab->sections[0]->entries, $view); } /** diff --git a/src/Panel/Request/RequestSectionRenderer.php b/src/Panel/Request/RequestSectionRenderer.php index af54fac..1b41b4b 100644 --- a/src/Panel/Request/RequestSectionRenderer.php +++ b/src/Panel/Request/RequestSectionRenderer.php @@ -26,7 +26,7 @@ public static function renderDisclosureSection(RequestSection $section): string if ($section->entries === []) { $content = P::tag() ->class('yii-debug-table-empty') - ->content(RequestMessage::NO_DATA->value) + ->content(RequestMessage::NO_DATA) ->render(); } else { $filter = self::renderFilter($section); @@ -41,11 +41,7 @@ public static function renderDisclosureSection(RequestSection $section): string $content = $toolbar . self::renderSectionTable($section); } - return Disclosure::render( - $section->caption, - $content, - $section->entries !== [], - ); + return Disclosure::render($section->caption, $content, $section->entries !== []); } /** @@ -159,11 +155,7 @@ public static function renderTabs(array $tabs): string $items[] = ['label' => $tab->label, 'content' => $content]; } - return Tabs::render( - 'request', - RequestMessage::REQUEST_DATA->value, - $items, - ); + return Tabs::render('request', RequestMessage::REQUEST_DATA->value, $items); } /** diff --git a/src/Panel/Request/RequestServerRenderer.php b/src/Panel/Request/RequestServerRenderer.php index 6e757e1..9e66d57 100644 --- a/src/Panel/Request/RequestServerRenderer.php +++ b/src/Panel/Request/RequestServerRenderer.php @@ -198,10 +198,7 @@ private static function renderLedger(array $entries): string ); } - return RequestDiagnosticLedger::render( - 'yii-debug-server-ledger', - ...$rows, - ); + return RequestDiagnosticLedger::render('yii-debug-server-ledger', ...$rows); } /** @@ -247,7 +244,7 @@ private static function renderView(array $entries, array $additional): string ->html( H2::tag() ->id('yii-debug-server-environment-title') - ->content(RequestMessage::SERVER_DETAILS->value), + ->content(RequestMessage::SERVER_DETAILS), Span::tag() ->class('yii-debug-diagnostic-total') ->content(count($additional) . ' additional / ' . count($entries) . ' captured'), diff --git a/src/Panel/Request/Routing/RequestRoutingView.php b/src/Panel/Request/Routing/RequestRoutingView.php index 186ec6d..3e26fb1 100644 --- a/src/Panel/Request/Routing/RequestRoutingView.php +++ b/src/Panel/Request/Routing/RequestRoutingView.php @@ -9,8 +9,9 @@ */ final readonly class RequestRoutingView { - public function __construct( - public CurrentRouteView $current, - public RouteInventoryView|null $inventory = null, - ) {} + /** + * @param CurrentRouteView $current Current route view. + * @param RouteInventoryView|null $inventory Route inventory view, or null if not available. + */ + public function __construct(public CurrentRouteView $current, public RouteInventoryView|null $inventory = null) {} } diff --git a/src/Panel/Request/Routing/RouteBadge.php b/src/Panel/Request/Routing/RouteBadge.php index 6baaa66..2e96486 100644 --- a/src/Panel/Request/Routing/RouteBadge.php +++ b/src/Panel/Request/Routing/RouteBadge.php @@ -9,8 +9,9 @@ */ final readonly class RouteBadge { - public function __construct( - public string $label, - public string $variant = 'muted', - ) {} + /** + * @param string $label Badge label. + * @param string $variant Badge variant, defaults to 'muted'. + */ + public function __construct(public string $label, public string $variant = 'muted') {} } diff --git a/src/Panel/Request/Routing/RouteDefinition.php b/src/Panel/Request/Routing/RouteDefinition.php index b7cf799..3a8e8c4 100644 --- a/src/Panel/Request/Routing/RouteDefinition.php +++ b/src/Panel/Request/Routing/RouteDefinition.php @@ -12,6 +12,7 @@ use function array_key_exists; use function array_keys; use function array_values; +use function is_array; use function is_string; /** @@ -22,32 +23,59 @@ */ final class RouteDefinition { + /** + * Handler the route dispatches to, or `null` when unsupported. + */ private string|null $action = null; - /** + * Hosts the route is restricted to; empty when it is unrestricted. + * * @var list */ private array $hosts = []; /** + * HTTP methods the route accepts; empty when it accepts any. + * * @var list */ private array $methods = []; - /** + * Middleware labels applied to the route; empty when it has none, or `null` when unsupported. + * * @var list|null */ private array|null $middlewares = null; - + /** + * Parsing mode the rule runs in, or `null` when unsupported. + */ private string|null $mode = null; - + /** + * URL suffix the rule appends, or `null` when unsupported. + */ private string|null $suffix = null; - + /** + * Route the rule resolves to, or `null` when unsupported. + */ private string|null $target = null; - + /** + * Rule class or category reported by the adapter, or `null` when unsupported. + */ private string|null $type = null; + /** + * @param string $name Route name as the application declares it. + * @param string $pattern URL pattern the route matches. + */ public function __construct(private string $name = '', private string $pattern = '') {} + /** + * Creates a route definition ready for immutable enrichment. + * + * @param string $name Route name as the application declares it. + * @param string $pattern URL pattern the route matches. + * + * @return self Definition carrying only the route identity. + */ public static function create(string $name = '', string $pattern = ''): self { return new self($name, $pattern); @@ -60,6 +88,11 @@ public static function create(string $name = '', string $pattern = ''): self * optional so old snapshots keep hydrating without schema migration. * * @param array $data Persisted route definition. + * + * @throws InvalidArgumentException when a required field is missing, a field is declared but unknown, or a value + * does not match its persisted type. + * + * @return self Definition restored from the persisted shape. */ public static function fromArray(array $data): self { @@ -104,13 +137,20 @@ public static function fromArray(array $data): self ->withType(self::optionalNullableString($data, 'type')); } + /** + * Returns the handler the route dispatches to. + * + * @return string|null Handler the route dispatches to, or `null` when unsupported. + */ public function getAction(): string|null { return $this->action; } /** - * @return list + * Returns the hosts the route is restricted to. + * + * @return list Hosts the route is restricted to; empty when it is unrestricted. */ public function getHosts(): array { @@ -118,7 +158,9 @@ public function getHosts(): array } /** - * @return list + * Returns the HTTP methods the route accepts. + * + * @return list HTTP methods the route accepts; empty when it accepts any. */ public function getMethods(): array { @@ -126,38 +168,71 @@ public function getMethods(): array } /** - * @return list|null + * Returns the middleware chain applied to the route. + * + * @return list|null Middleware labels applied to the route; empty when it has none, or `null` + * when unsupported. */ public function getMiddlewares(): array|null { return $this->middlewares; } + /** + * Returns the parsing mode the rule runs in. + * + * @return string|null Parsing mode the rule runs in, or `null` when unsupported. + */ public function getMode(): string|null { return $this->mode; } + /** + * Returns the route name. + * + * @return string Route name as the application declares it. + */ public function getName(): string { return $this->name; } + /** + * Returns the URL pattern the route matches. + * + * @return string URL pattern the route matches. + */ public function getPattern(): string { return $this->pattern; } + /** + * Returns the URL suffix the rule appends. + * + * @return string|null URL suffix the rule appends, or `null` when unsupported. + */ public function getSuffix(): string|null { return $this->suffix; } + /** + * Returns the route the rule resolves to. + * + * @return string|null Route the rule resolves to, or `null` when unsupported. + */ public function getTarget(): string|null { return $this->target; } + /** + * Returns the rule class or category. + * + * @return string|null Rule class or category reported by the adapter, or `null` when unsupported. + */ public function getType(): string|null { return $this->type; @@ -177,7 +252,7 @@ public function getType(): string|null * suffix?: string, * mode?: string, * type?: string - * } + * } Route fields; the optional ones appear only when the adapter exposed them. */ public function toArray(): array { @@ -199,6 +274,13 @@ public function toArray(): array return $data; } + /** + * Returns a copy carrying another action. + * + * @param string|null $action Handler the route dispatches to, or `null` when unsupported. + * + * @return self Definition with the action applied. + */ public function withAction(string|null $action): self { $clone = clone $this; @@ -208,7 +290,11 @@ public function withAction(string|null $action): self } /** - * @param list $hosts + * Returns a copy restricted to another set of hosts. + * + * @param list $hosts Hosts the route is restricted to; empty to leave it unrestricted. + * + * @return self Definition with the hosts applied. */ public function withHosts(array $hosts): self { @@ -219,7 +305,11 @@ public function withHosts(array $hosts): self } /** - * @param list $methods + * Returns a copy accepting another set of HTTP methods. + * + * @param list $methods HTTP methods the route accepts; empty to accept any. + * + * @return self Definition with the methods applied. */ public function withMethods(array $methods): self { @@ -230,7 +320,12 @@ public function withMethods(array $methods): self } /** - * @param list|null $middlewares + * Returns a copy carrying another middleware chain. + * + * @param list|null $middlewares Middleware labels applied to the route; empty when it has none, + * or `null` when unsupported. + * + * @return self Definition with the middlewares applied. */ public function withMiddlewares(array|null $middlewares): self { @@ -240,6 +335,13 @@ public function withMiddlewares(array|null $middlewares): self return $clone; } + /** + * Returns a copy carrying another mode. + * + * @param string|null $mode Parsing mode the rule runs in, or `null` when unsupported. + * + * @return self Definition with the mode applied. + */ public function withMode(string|null $mode): self { $clone = clone $this; @@ -248,6 +350,13 @@ public function withMode(string|null $mode): self return $clone; } + /** + * Returns a copy carrying another suffix. + * + * @param string|null $suffix URL suffix the rule appends, or `null` when unsupported. + * + * @return self Definition with the suffix applied. + */ public function withSuffix(string|null $suffix): self { $clone = clone $this; @@ -256,6 +365,13 @@ public function withSuffix(string|null $suffix): self return $clone; } + /** + * Returns a copy carrying another target. + * + * @param string|null $target Route the rule resolves to, or `null` when unsupported. + * + * @return self Definition with the target applied. + */ public function withTarget(string|null $target): self { $clone = clone $this; @@ -264,6 +380,13 @@ public function withTarget(string|null $target): self return $clone; } + /** + * Returns a copy carrying another type. + * + * @param string|null $type Rule class or category reported by the adapter, or `null` when unsupported. + * + * @return self Definition with the type applied. + */ public function withType(string|null $type): self { $clone = clone $this; @@ -272,6 +395,13 @@ public function withType(string|null $type): self return $clone; } + /** + * Names the persisted type a field must carry, for the failure message. + * + * @param string $key Field the value belongs to, named in the failure message. + * + * @return string Human-readable description of the expected type. + */ private static function expectedFor(string $key): string { return match ($key) { @@ -283,6 +413,14 @@ private static function expectedFor(string $key): string }; } + /** + * Builds the failure raised when a persisted field is missing, unknown, or of the wrong type. + * + * @param string $key Field the value belongs to, named in the failure message. + * @param string $expected Description of the type the field must carry. + * + * @return InvalidArgumentException Failure naming the field and the expected type. + */ private static function invalid(string $key, string $expected): InvalidArgumentException { return new InvalidArgumentException( @@ -290,6 +428,16 @@ private static function invalid(string $key, string $expected): InvalidArgumentE ); } + /** + * Narrows a persisted value to a nullable string. + * + * @param mixed $value Persisted value of unknown type. + * @param string $key Field the value belongs to, named in the failure message. + * + * @throws InvalidArgumentException when the value is neither a `string` nor `null`. + * + * @return string|null Value as persisted. + */ private static function nullableString(mixed $value, string $key): string|null { if ($value !== null && !is_string($value)) { @@ -300,7 +448,14 @@ private static function nullableString(mixed $value, string $key): string|null } /** - * @param array $data + * Narrows an optional persisted field to a nullable string, treating an absent field as `null`. + * + * @param array $data Persisted route definition. + * @param string $key Field the value belongs to, named in the failure message. + * + * @throws InvalidArgumentException when the field is present and is neither a `string` nor `null`. + * + * @return string|null Value as persisted, or `null` when the field is absent. */ private static function optionalNullableString(array $data, string $key): string|null { @@ -308,7 +463,14 @@ private static function optionalNullableString(array $data, string $key): string } /** - * @return list + * Narrows a persisted value to a list of strings. + * + * @param mixed $value Persisted value of unknown type. + * @param string $key Field the value belongs to, named in the failure message. + * + * @throws InvalidArgumentException when the value is not a list, or any entry is not a `string`. + * + * @return list Value as persisted. */ private static function stringList(mixed $value, string $key): array { diff --git a/src/Panel/Request/Routing/RouteTraceRow.php b/src/Panel/Request/Routing/RouteTraceRow.php index b401977..66d9107 100644 --- a/src/Panel/Request/Routing/RouteTraceRow.php +++ b/src/Panel/Request/Routing/RouteTraceRow.php @@ -9,5 +9,10 @@ */ final readonly class RouteTraceRow { + /** + * @param string $rule Routing rule inspected. + * @param string $parent Parent rule, if any. + * @param bool $matched Whether this rule matched the current request. + */ public function __construct(public string $rule, public string $parent = '', public bool $matched = false) {} } diff --git a/src/Panel/Request/ServerVariableGroup.php b/src/Panel/Request/ServerVariableGroup.php index baf3ba0..8c93d43 100644 --- a/src/Panel/Request/ServerVariableGroup.php +++ b/src/Panel/Request/ServerVariableGroup.php @@ -10,7 +10,10 @@ final readonly class ServerVariableGroup { /** - * @param array $entries + * @param string $id Identifier for the server variable group. + * @param string $label Human-readable label for the server variable group. + * @param array $entries Captured server variables within the group. + * @param bool $collapsed Whether the group should be initially collapsed. */ public function __construct( public string $id, diff --git a/src/Panel/Router/CurrentRouteLogRow.php b/src/Panel/Router/CurrentRouteLogRow.php index 7414f70..30370b4 100644 --- a/src/Panel/Router/CurrentRouteLogRow.php +++ b/src/Panel/Router/CurrentRouteLogRow.php @@ -33,14 +33,7 @@ public function __construct( public static function fromArray(mixed $data, string $path): self { - $payload = Payload::object($data, $path) - ->shape( - [ - 'rule', - 'parent', - 'match', - ], - ); + $payload = Payload::object($data, $path)->shape(['rule', 'parent', 'match']); return new self( $payload->string('rule'), @@ -67,11 +60,7 @@ public static function fromLogMessage(mixed $message): self|null $parent = $message['parent'] ?? null; - return new self( - $message['rule'], - Coerce::string($parent), - $message['match'], - ); + return new self($message['rule'],Coerce::string($parent), $message['match']); } /** diff --git a/src/Panel/Timeline/TimelineSnapshot.php b/src/Panel/Timeline/TimelineSnapshot.php index 4b9bba0..4ce701b 100644 --- a/src/Panel/Timeline/TimelineSnapshot.php +++ b/src/Panel/Timeline/TimelineSnapshot.php @@ -11,28 +11,18 @@ */ final readonly class TimelineSnapshot implements PanelSnapshot { - public function __construct( - public float $start, - public float $end, - public int $memory, - ) {} + /** + * @param float $start The start time of the timeline snapshot. + * @param float $end The end time of the timeline snapshot. + * @param int $memory The peak memory usage at the time of the snapshot. + */ + public function __construct(public float $start, public float $end, public int $memory) {} public static function fromArray(mixed $data, string $path): self { - $payload = Payload::object($data, $path) - ->shape( - [ - 'start', - 'end', - 'memory', - ], - ); + $payload = Payload::object($data, $path)->shape(['start', 'end', 'memory']); - return new self( - $payload->number('start'), - $payload->number('end'), - $payload->int('memory'), - ); + return new self($payload->number('start'), $payload->number('end'), $payload->int('memory')); } /** diff --git a/src/Panel/User/UserPanel.php b/src/Panel/User/UserPanel.php index 4252e9b..7617b0e 100644 --- a/src/Panel/User/UserPanel.php +++ b/src/Panel/User/UserPanel.php @@ -249,10 +249,7 @@ private static function status(UserIdentityHero $hero): array { $label = $hero->statusLabel === '' ? UserMessage::STATUS_UNKNOWN->value : $hero->statusLabel; - return PanelView::badge( - $label, - self::STATUS_TONES[$hero->statusVariant] ?? Tone::MUTED, - ); + return PanelView::badge($label, self::STATUS_TONES[$hero->statusVariant] ?? Tone::MUTED); } /** diff --git a/src/PhpInfo/PhpInfoDataNormalizer.php b/src/PhpInfo/PhpInfoDataNormalizer.php index 9f86f89..9fc81d8 100644 --- a/src/PhpInfo/PhpInfoDataNormalizer.php +++ b/src/PhpInfo/PhpInfoDataNormalizer.php @@ -324,11 +324,7 @@ private static function buildSections( continue; } - $sections[] = new PhpInfoSection( - eyebrow: $spec['eyebrow'], - tiles: $tiles, - headline: $spec['headline'], - ); + $sections[] = new PhpInfoSection(eyebrow: $spec['eyebrow'], tiles: $tiles, headline: $spec['headline']); } return $sections; @@ -414,12 +410,7 @@ private static function buildTile(string $label, string $value, string $home): P ); } - return new PhpInfoTile( - label: $label, - displayValue: $value, - rawValue: $value, - kind: PhpInfoTile::KIND_TEXT, - ); + return new PhpInfoTile(label: $label, displayValue: $value, rawValue: $value, kind: PhpInfoTile::KIND_TEXT); } /** @@ -583,11 +574,7 @@ private static function extractCompactModule( return null; } - return new PhpInfoCompactModule( - title: $title, - slug: $slug, - tiles: $tiles, - ); + return new PhpInfoCompactModule(title: $title, slug: $slug, tiles: $tiles); } /** @@ -753,7 +740,7 @@ static function (array $row): string { $attributes = self::addRowClass($row['attributes'], $class); - return '' . self::renderFactStatusPills($row['body']) . ''; + return "" . self::renderFactStatusPills($row['body']) . ''; }, $tableBody, ); diff --git a/src/PhpInfo/PhpInfoTile.php b/src/PhpInfo/PhpInfoTile.php index 0a503c2..f1d305f 100644 --- a/src/PhpInfo/PhpInfoTile.php +++ b/src/PhpInfo/PhpInfoTile.php @@ -12,11 +12,29 @@ */ final readonly class PhpInfoTile { + /** + * Renders a single shortened path as ``, with the full value as its hover title. + */ public const string KIND_PATH = 'path'; + /** + * Renders every entry of {@see $tokens} as a `` chip, each carrying its full path as a hover title. + */ public const string KIND_PATH_LIST = 'path-list'; + /** + * Renders a pill in its muted variant, used for an off or unavailable status. + */ public const string KIND_PILL_MUTED = 'pill-muted'; + /** + * Renders a pill in its success variant, used for an on or available status. + */ public const string KIND_PILL_SUCCESS = 'pill-success'; + /** + * Renders the display value as plain `` text, without a hover title. + */ public const string KIND_TEXT = 'text'; + /** + * Renders every entry of {@see $tokens} as a `` chip; unlike {@see KIND_PATH_LIST}, the tokens are not paths. + */ public const string KIND_TOKEN_LIST = 'token-list'; public function __construct( diff --git a/src/Storage/ArrayPayloadSnapshot.php b/src/Storage/ArrayPayloadSnapshot.php index a5ace4e..67e7762 100644 --- a/src/Storage/ArrayPayloadSnapshot.php +++ b/src/Storage/ArrayPayloadSnapshot.php @@ -26,9 +26,7 @@ final public function __construct(private readonly DebugArray $payload) {} */ public static function capture(array $values): self { - return new self( - DebugArray::capture($values), - ); + return new self(DebugArray::capture($values)); } /** diff --git a/src/Storage/DebugArray.php b/src/Storage/DebugArray.php index 3eae368..55b5b5b 100644 --- a/src/Storage/DebugArray.php +++ b/src/Storage/DebugArray.php @@ -28,9 +28,7 @@ private function __construct(private DebugValue $value) {} */ public static function capture(#[SensitiveParameter] array $value): self { - return new self( - DebugValue::capture($value), - ); + return new self(DebugValue::capture($value)); } /** @@ -52,9 +50,7 @@ public static function fromArray(mixed $value, string $path): self ); } - return new self( - $debugValue, - ); + return new self($debugValue); } /** diff --git a/src/Storage/DebugSnapshot.php b/src/Storage/DebugSnapshot.php index 88f53ee..f6a2184 100644 --- a/src/Storage/DebugSnapshot.php +++ b/src/Storage/DebugSnapshot.php @@ -16,8 +16,6 @@ public const int VERSION = 4; /** - * Creates an envelope from request metadata, panel payloads, and capture failures. - * * @param RequestSummary $summary Captured request metadata. * @param array> $panels Serialized panel payloads indexed by panel ID. * @param array $failures Panel failures indexed by panel ID. @@ -33,15 +31,7 @@ public function __construct(public RequestSummary $summary, public array $panels */ public static function fromArray(mixed $data): self { - $payload = Payload::object($data) - ->shape( - [ - 'version', - 'summary', - 'panels', - 'failures', - ], - ); + $payload = Payload::object($data)->shape(['version', 'summary', 'panels', 'failures']); if ($payload->int('version') !== self::VERSION) { throw HydrationException::at( @@ -53,8 +43,7 @@ public static function fromArray(mixed $data): self $panels = []; foreach ($payload->map('panels') as $id => $panel) { - $panels[$id] = Payload::object($panel, "$.panels.{$id}") - ->all(); + $panels[$id] = Payload::object($panel, "$.panels.{$id}")->all(); } $failures = []; diff --git a/src/Storage/DebugValue.php b/src/Storage/DebugValue.php index 8ac5bde..9115f30 100644 --- a/src/Storage/DebugValue.php +++ b/src/Storage/DebugValue.php @@ -318,11 +318,17 @@ private static function hydrate(mixed $data, string $path, int $depth, int &$nod $payload = self::taggedObject($data, $path, $type); if (++$nodes > self::MAX_NODES + 1) { - throw HydrationException::at($path, 'at most 10000 captured nodes'); + throw HydrationException::at( + $path, + 'at most 10000 captured nodes', + ); } if ($depth > self::MAX_DEPTH && $type !== 'truncated') { - throw HydrationException::at($path, 'at most 10 nested levels'); + throw HydrationException::at( + $path, + 'at most 10 nested levels', + ); } return match ($type) { @@ -373,7 +379,10 @@ private static function hydrateEntries(Payload $payload, string $path, int $dept $key = $entry['key']; if (!is_string($keyType)) { - throw HydrationException::at("{$entryPath}.keyType", 'a string'); + throw HydrationException::at( + "{$entryPath}.keyType", + 'a string', + ); } if ( @@ -390,12 +399,7 @@ private static function hydrateEntries(Payload $payload, string $path, int $dept $entries[] = [ 'keyType' => $keyType, 'key' => $key, - 'value' => self::hydrate( - $entry['value'], - "{$entryPath}.value", - $depth + 1, - $nodes, - ), + 'value' => self::hydrate($entry['value'], "{$entryPath}.value", $depth + 1, $nodes), ]; } @@ -419,47 +423,28 @@ private static function normalize( SplObjectStorage $objects, ): self { if (++$nodes > self::MAX_NODES) { - return new self( - 'truncated', - value: '*SKIPPED over 10000 nodes*', - reason: 'size', - ); + return new self('truncated', value: '*SKIPPED over 10000 nodes*', reason: 'size'); } if ($depth > self::MAX_DEPTH) { - return new self( - 'truncated', - value: '*DEEP NESTED VALUE*', - reason: 'depth', - ); + return new self('truncated', value: '*DEEP NESTED VALUE*', reason: 'depth'); } if ($value === null) { - return new self( - 'null', - ); + return new self('null'); } if (is_bool($value)) { - return new self( - 'bool', - $value, - ); + return new self('bool', $value); } if (is_int($value)) { - return new self( - 'int', - $value, - ); + return new self('int', $value); } if (is_float($value)) { return is_finite($value) - ? new self( - 'float', - $value, - ) + ? new self('float', $value) : new self( 'special-float', match (true) { @@ -472,14 +457,8 @@ private static function normalize( if (is_string($value)) { return mb_check_encoding($value, 'UTF-8') - ? new self( - 'string', - $value, - ) - : new self( - 'binary', - $value, - ); + ? new self('string', $value) + : new self('binary', $value); } if (is_array($value)) { @@ -497,19 +476,12 @@ private static function normalize( } } - return new self( - 'array', - entries: $entries, - ); + return new self('array', entries: $entries); } if (is_object($value)) { if ($objects->offsetExists($value)) { - return new self( - 'recursion', - value: $value::class, - reason: 'object-cycle', - ); + return new self('recursion', value: $value::class, reason: 'object-cycle'); } $objects->offsetSet($value); @@ -539,18 +511,11 @@ className: $value::class, } if (is_resource($value)) { - return new self( - 'resource', - resourceType: get_resource_type($value), - ); + return new self('resource', resourceType: get_resource_type($value)); } // Closed resources report `false` from is_resource(), so they land here rather than in the branch above. - return new self( - 'unsupported', - value: '(unsupported)', - reason: 'unknown-type', - ); + return new self('unsupported', value: '(unsupported)', reason: 'unknown-type'); } /** diff --git a/src/Storage/Json.php b/src/Storage/Json.php index eaaecd0..d465049 100644 --- a/src/Storage/Json.php +++ b/src/Storage/Json.php @@ -33,6 +33,7 @@ private function __construct() {} public static function payload(array $payload): array { $json = json_encode($payload, JSON_THROW_ON_ERROR | JSON_PRESERVE_ZERO_FRACTION, self::PAYLOAD_DEPTH); + return Payload::object(json_decode($json, true, self::PAYLOAD_DEPTH, JSON_THROW_ON_ERROR))->all(); } diff --git a/src/Storage/Manifest.php b/src/Storage/Manifest.php index c8c0fd7..89a105b 100644 --- a/src/Storage/Manifest.php +++ b/src/Storage/Manifest.php @@ -29,13 +29,7 @@ public function __construct(public array $entries) {} */ public static function fromArray(mixed $data): self { - $payload = Payload::object($data) - ->shape( - [ - 'version', - 'entries', - ], - ); + $payload = Payload::object($data)->shape(['version', 'entries']); if ($payload->int('version') !== DebugSnapshot::VERSION) { throw HydrationException::at( @@ -59,9 +53,7 @@ public static function fromArray(mixed $data): self $entries[$tag] = $summary; } - return new self( - $entries, - ); + return new self($entries); } /** diff --git a/src/Storage/ManifestReadResult.php b/src/Storage/ManifestReadResult.php index daa6c5f..f1cf556 100644 --- a/src/Storage/ManifestReadResult.php +++ b/src/Storage/ManifestReadResult.php @@ -13,8 +13,5 @@ * @param array $entries Newest entries first, or an empty list after a failed read. * @param StorageException|null $error Filesystem, recovery, decoding, or hydration failure. */ - public function __construct( - public array $entries, - public StorageException|null $error, - ) {} + public function __construct(public array $entries, public StorageException|null $error) {} } diff --git a/src/Storage/PanelFailure.php b/src/Storage/PanelFailure.php index 36c3c50..7786eb4 100644 --- a/src/Storage/PanelFailure.php +++ b/src/Storage/PanelFailure.php @@ -12,12 +12,16 @@ */ final readonly class PanelFailure implements JsonSerializable { + /** + * Lifecycle stage indicating the panel was captured. + */ public const string CAPTURE = 'capture'; + /** + * Lifecycle stage indicating the panel was hydrated. + */ public const string HYDRATE = 'hydrate'; /** - * Creates a failure record for a panel lifecycle stage. - * * @param 'capture'|'hydrate' $stage Lifecycle stage the panel failed in. * @param ExceptionSnapshot $exception Captured panel exception. */ @@ -33,13 +37,7 @@ public function __construct(public string $stage, public ExceptionSnapshot $exce */ public static function fromArray(mixed $data, string $path): self { - $payload = Payload::object($data, $path) - ->shape( - [ - 'stage', - 'exception', - ], - ); + $payload = Payload::object($data, $path)->shape(['stage', 'exception']); $stage = $payload->string('stage'); @@ -50,10 +48,7 @@ public static function fromArray(mixed $data, string $path): self ); } - return new self( - $stage, - ExceptionSnapshot::fromArray($payload->raw('exception'), "{$path}.exception"), - ); + return new self($stage, ExceptionSnapshot::fromArray($payload->raw('exception'), "{$path}.exception")); } /** @@ -66,10 +61,7 @@ public static function fromArray(mixed $data, string $path): self */ public static function fromThrowable(string $stage, Throwable $throwable): self { - return new self( - $stage, - ExceptionSnapshot::fromThrowable($throwable), - ); + return new self($stage, ExceptionSnapshot::fromThrowable($throwable)); } /** diff --git a/src/Storage/Payload.php b/src/Storage/Payload.php index 8be88d9..ac37e68 100644 --- a/src/Storage/Payload.php +++ b/src/Storage/Payload.php @@ -300,10 +300,7 @@ public static function object(mixed $value, string $path = '$'): self } /** @var array $value */ - return new self( - $value, - $path, - ); + return new self($value, $path); } /** diff --git a/src/Storage/SnapshotReadResult.php b/src/Storage/SnapshotReadResult.php index c7cf505..c13215d 100644 --- a/src/Storage/SnapshotReadResult.php +++ b/src/Storage/SnapshotReadResult.php @@ -9,8 +9,9 @@ */ final readonly class SnapshotReadResult { - public function __construct( - public DebugSnapshot|null $snapshot, - public StorageException|null $error, - ) {} + /** + * @param DebugSnapshot|null $snapshot The read snapshot, if available. + * @param StorageException|null $error The storage error, if any. + */ + public function __construct(public DebugSnapshot|null $snapshot, public StorageException|null $error) {} } diff --git a/src/Storage/SnapshotStore.php b/src/Storage/SnapshotStore.php index 7339e3e..7524d93 100644 --- a/src/Storage/SnapshotStore.php +++ b/src/Storage/SnapshotStore.php @@ -313,10 +313,7 @@ public function writeSnapshotResult(DebugSnapshot $snapshot, int $historySize): $this->removeStaleSnapshots($entries); - return new SnapshotWriteResult( - array_reverse($entries, true), - $removed, - ); + return new SnapshotWriteResult(array_reverse($entries, true), $removed); } finally { fclose($lock); } diff --git a/src/Storage/SnapshotWriteResult.php b/src/Storage/SnapshotWriteResult.php index 1302e40..7790a49 100644 --- a/src/Storage/SnapshotWriteResult.php +++ b/src/Storage/SnapshotWriteResult.php @@ -13,8 +13,5 @@ * @param array $entries Committed manifest entries, newest first. * @param list $removed Entries evicted from the manifest. */ - public function __construct( - public array $entries, - public array $removed, - ) {} + public function __construct(public array $entries, public array $removed) {} } diff --git a/src/Toolbar/ToolbarData.php b/src/Toolbar/ToolbarData.php index 5ced4ef..40f7b93 100644 --- a/src/Toolbar/ToolbarData.php +++ b/src/Toolbar/ToolbarData.php @@ -49,13 +49,7 @@ public function __construct( */ public static function create(string $tag, string $title): self { - return new self( - tag: $tag, - title: $title, - indexUrl: '', - configUrl: '', - items: [], - ); + return new self(tag: $tag, title: $title, indexUrl: '', configUrl: '', items: []); } /** diff --git a/src/Toolbar/ToolbarPanel.php b/src/Toolbar/ToolbarPanel.php index e0cc538..c8d818c 100644 --- a/src/Toolbar/ToolbarPanel.php +++ b/src/Toolbar/ToolbarPanel.php @@ -31,6 +31,11 @@ private function __construct( /** * Creates a panel with no metrics or optional navigation. + * + * @param string $id Stable panel identifier. + * @param string $title Display title. + * + * @return self Panel carrying only its identity. */ public static function create(string $id, string $title): self { @@ -68,45 +73,37 @@ public function jsonSerialize(): array /** * Returns a copy with the specified icon. + * + * @param string|null $icon Shared icon name, or `null` when no icon is available. + * + * @return self Panel with the icon applied. */ public function withIcon(string|null $icon): self { - return new self( - id: $this->id, - title: $this->title, - url: $this->url, - icon: $icon, - items: $this->items, - ); + return new self(id: $this->id, title: $this->title, url: $this->url, icon: $icon, items: $this->items); } /** * Returns a copy with the replacement metric list. * * @param list $items Panel metrics in display order; `[]` removes all metrics. + * + * @return self Panel with the metrics applied. */ public function withItems(array $items): self { - return new self( - id: $this->id, - title: $this->title, - url: $this->url, - icon: $this->icon, - items: $items, - ); + return new self(id: $this->id, title: $this->title, url: $this->url, icon: $this->icon, items: $items); } /** * Returns a copy with the specified URL. + * + * @param string|null $url Debug page URL, or `null` when only individual metrics are navigable. + * + * @return self Panel with the URL applied. */ public function withUrl(string|null $url): self { - return new self( - id: $this->id, - title: $this->title, - url: $url, - icon: $this->icon, - items: $this->items, - ); + return new self(id: $this->id, title: $this->title, url: $url, icon: $this->icon, items: $this->items); } } diff --git a/src/View/History/CaptureLabel.php b/src/View/History/CaptureLabel.php index 8f4303b..27149dc 100644 --- a/src/View/History/CaptureLabel.php +++ b/src/View/History/CaptureLabel.php @@ -14,6 +14,19 @@ */ final class CaptureLabel { + /** + * Builds the label identifying one capture in a selection control. + * + * Joins the time, HTTP method, URL, and tag with a middot. The URL is trimmed to 72 columns, while the tag is + * never shortened, so two captures of the same request stay distinguishable. Missing time or method fall back to + * a placeholder instead of collapsing the label. + * + * The result is unescaped, so the caller encodes it. + * + * @param RequestSummary $summary Capture the label describes. + * + * @return string Unescaped label for a capture-selection control. + */ public static function fromSummary(RequestSummary $summary): string { $time = $summary->time > 0 ? date('H:i:s', (int) $summary->time) : 'time unavailable'; diff --git a/src/View/Sidebar/SidebarRenderer.php b/src/View/Sidebar/SidebarRenderer.php index c262f3e..56d8e96 100644 --- a/src/View/Sidebar/SidebarRenderer.php +++ b/src/View/Sidebar/SidebarRenderer.php @@ -8,9 +8,7 @@ use PHPForge\Debug\View\ViewMessage; use UIAwesome\Html\Core\Component\{Item, Menu}; use UIAwesome\Html\Flow\Div; -use UIAwesome\Html\Form\Button; use UIAwesome\Html\Interop\Inline; -use UIAwesome\Html\Palpable\A; use UIAwesome\Html\Phrasing\Span; use UIAwesome\Html\Root\Header; use UIAwesome\Html\Sectioning\{Aside, Section}; @@ -95,7 +93,7 @@ private static function renderMetaStrip(SidebarSnapshot $snapshot): Div $ajax = Span::tag() ->class('yii-debug-snapshot-tag') ->addDataAttribute('snapshot-field', 'ajax') - ->content(ViewMessage::AJAX->value); + ->content(ViewMessage::AJAX); if ($snapshot->isAjax === false) { $ajax = $ajax->addAttribute('hidden', true); @@ -113,48 +111,13 @@ private static function renderMetaStrip(SidebarSnapshot $snapshot): Div ); } - /** - * Renders one navigator button (either an anchor link or a cursor ` + + + + @@ -124,7 +135,18 @@ public function testRenderEmitsHistoryCursorMarkerWhenSnapshotIsCursor(): void
20012:34:56AJAX
- + + + +
@@ -255,7 +277,18 @@ public function testRenderShowsDashWhenStatusCodeIsZero(): void
12:34:56AJAX
- + + + + + + + +
@@ -323,7 +356,18 @@ public function testRenderTintsSnapshotMethodAndStatusWithVocabularyClasses(): v
20012:34:56AJAX
- + + + + + + + +
@@ -345,7 +389,18 @@ public function testRenderTintsSnapshotMethodAndStatusWithVocabularyClasses(): v
50012:34:56AJAX
- + + + + + + + +
@@ -374,7 +429,18 @@ public function testRenderWiresNavigationAnchorsInViewMode(): void
20012:34:56AJAX
- + + + + + + + +
From e3bd38743a1d56255859156799f9e03a274853cf Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Mon, 14 Sep 2026 15:15:51 -0300 Subject: [PATCH 2/2] Fix ECS ci. --- src/Panel/Router/CurrentRouteLogRow.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Panel/Router/CurrentRouteLogRow.php b/src/Panel/Router/CurrentRouteLogRow.php index 30370b4..3482041 100644 --- a/src/Panel/Router/CurrentRouteLogRow.php +++ b/src/Panel/Router/CurrentRouteLogRow.php @@ -60,7 +60,7 @@ public static function fromLogMessage(mixed $message): self|null $parent = $message['parent'] ?? null; - return new self($message['rule'],Coerce::string($parent), $message['match']); + return new self($message['rule'], Coerce::string($parent), $message['match']); } /**