Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 23 |
|
0.00% |
0 / 6 |
CRAP | |
0.00% |
0 / 1 |
KV | |
0.00% |
0 / 23 |
|
0.00% |
0 / 6 |
182 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
lookupKV | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
30 | |||
lookup | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
keyOffset | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
valueOffset | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
jsonSerialize | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
20 |
1 | <?php |
2 | // phpcs:disable MediaWiki.Commenting.FunctionComment.DefaultNullTypeParam -- T218324, T218816 |
3 | declare( strict_types = 1 ); |
4 | |
5 | namespace Wikimedia\Parsoid\Tokens; |
6 | |
7 | /** |
8 | * Represents a Key-value pair. |
9 | */ |
10 | class KV implements \JsonSerializable { |
11 | /** |
12 | * Commonly a string, but where the key might be templated, |
13 | * this can be an array of tokens even. |
14 | * |
15 | * @var string|Token|array<Token|string> |
16 | */ |
17 | public $k; |
18 | |
19 | /** @var string|Token|array<Token|string>|KV[] */ |
20 | public $v; |
21 | |
22 | /** Wikitext source offsets */ |
23 | public ?KVSourceRange $srcOffsets; |
24 | |
25 | /** Wikitext source */ |
26 | public ?string $ksrc; |
27 | |
28 | /** Wikitext source */ |
29 | public ?string $vsrc; |
30 | |
31 | /** |
32 | * @param string|Token|array<Token|string> $k |
33 | * Commonly a string, but where the key might be templated, |
34 | * this can be an array of tokens even. |
35 | * @param string|Token|array<Token|string>|KV[] $v |
36 | * The value: string, token, of an array of tokens |
37 | * @param ?KVSourceRange $srcOffsets wikitext source offsets |
38 | * @param ?string $ksrc |
39 | * @param ?string $vsrc |
40 | */ |
41 | public function __construct( |
42 | $k, $v, ?KVSourceRange $srcOffsets = null, ?string $ksrc = null, |
43 | ?string $vsrc = null |
44 | ) { |
45 | $this->k = $k; |
46 | $this->v = $v; |
47 | $this->srcOffsets = $srcOffsets; |
48 | $this->ksrc = $ksrc; |
49 | $this->vsrc = $vsrc; |
50 | } |
51 | |
52 | /** |
53 | * BUG: When there are multiple matching attributes, Sanitizer lets the last one win |
54 | * whereas this method is letting the first one win. This can introduce subtle bugs! |
55 | * |
56 | * Lookup a string key in a KV array and return the first matching KV object |
57 | * |
58 | * @param KV[]|null $kvs |
59 | * @param string $key |
60 | * @return ?KV |
61 | */ |
62 | public static function lookupKV( ?array $kvs, string $key ): ?KV { |
63 | if ( $kvs === null ) { |
64 | return null; |
65 | } |
66 | |
67 | foreach ( $kvs as $kv ) { |
68 | // PORT-FIXME: JS trim() will remove non-ASCII spaces (such as NBSP) too, |
69 | // while PHP's won't. Does that matter? |
70 | if ( is_string( $kv->k ) && trim( $kv->k ) === $key ) { |
71 | return $kv; |
72 | } |
73 | } |
74 | |
75 | return null; |
76 | } |
77 | |
78 | /** |
79 | * Lookup a string key (first occurrence) in a KV array |
80 | * and return the value of the KV object |
81 | * |
82 | * @param KV[]|null $kvs |
83 | * @param string $key |
84 | * @return string|Token|array<Token|string>|null |
85 | */ |
86 | public static function lookup( ?array $kvs, string $key ) { |
87 | $kv = self::lookupKV( $kvs, $key ); |
88 | // PORT_FIXME: Potential bug lurking here ... if $kv->v is an array |
89 | // this will return a copy, which if modified will not reflect |
90 | // in the original KV object. |
91 | return $kv->v ?? null; |
92 | } |
93 | |
94 | /** |
95 | * Return the key portion of the KV's source offsets, or else null |
96 | * if no source offsets are known. |
97 | * @return SourceRange|null |
98 | */ |
99 | public function keyOffset(): ?SourceRange { |
100 | // @phan-suppress-next-line PhanCoalescingNeverNull $this->srcOffsets is nullable |
101 | return $this->srcOffsets->key ?? null; |
102 | } |
103 | |
104 | /** |
105 | * Return the value portion of the KV's source offsets, or else null |
106 | * if no source offsets are known. |
107 | * @return SourceRange|null |
108 | */ |
109 | public function valueOffset(): ?SourceRange { |
110 | // @phan-suppress-next-line PhanCoalescingNeverNull $this->srcOffsets is nullable |
111 | return $this->srcOffsets->value ?? null; |
112 | } |
113 | |
114 | /** |
115 | * @inheritDoc |
116 | */ |
117 | public function jsonSerialize(): array { |
118 | $ret = [ "k" => $this->k, "v" => $this->v ]; |
119 | if ( $this->srcOffsets ) { |
120 | $ret["srcOffsets"] = $this->srcOffsets; |
121 | } |
122 | if ( isset( $this->ksrc ) ) { |
123 | $ret["ksrc"] = $this->ksrc; |
124 | } |
125 | if ( isset( $this->vsrc ) ) { |
126 | $ret["vsrc"] = $this->vsrc; |
127 | } |
128 | return $ret; |
129 | } |
130 | } |