1: <?php
2:
3: declare(strict_types=1);
4:
5: namespace LaravelUi5\OData\Service;
6:
7: /**
8: * A single read-authorization message — the standard OData / SAP message shape
9: * (`code`, `message`, `numericSeverity`, `target`, `longtextUrl`).
10: *
11: * `numericSeverity` follows `com.sap.vocabularies.Common.v1.NumericMessageSeverity`:
12: * 1 = success, 2 = info, 3 = warning, 4 = error. A root (hard) denial is an error (4)
13: * carried in the 403 error envelope; a dropped `$expand` is a warning (3) carried in the
14: * `sap-messages` header (the honest-partial model — added in the next slice).
15: *
16: * **Unbound messages MUST carry an empty `target`** — a non-resolvable target is silently
17: * dropped by the UI5 v4 model.
18: */
19: final readonly class ReadMessage
20: {
21: public function __construct(
22: public string $code,
23: public string $message,
24: public int $numericSeverity = 4,
25: public string $target = '',
26: public ?string $longtextUrl = null,
27: ) {}
28:
29: public function isError(): bool
30: {
31: return $this->numericSeverity >= 4;
32: }
33:
34: /**
35: * The standard SAP message array (for the `sap-messages` header — consumed by the
36: * honest-partial model in the next slice).
37: *
38: * @return array<string, mixed>
39: */
40: public function toArray(): array
41: {
42: return array_filter(
43: [
44: 'code' => $this->code,
45: 'message' => $this->message,
46: 'numericSeverity' => $this->numericSeverity,
47: 'target' => $this->target,
48: 'longtextUrl' => $this->longtextUrl,
49: ],
50: static fn ($v) => $v !== null,
51: );
52: }
53: }
54: