Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 48
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
TemplateInfo
0.00% covered (danger)
0.00%
0 / 48
0.00% covered (danger)
0.00%
0 / 4
156
0.00% covered (danger)
0.00%
0 / 1
 __clone
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 newFromJsonArray
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
6
 jsonClassHintFor
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
6
 toJsonArray
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 1
42
1<?php
2declare( strict_types = 1 );
3
4namespace Wikimedia\Parsoid\NodeData;
5
6use stdClass;
7use Wikimedia\JsonCodec\Hint;
8use Wikimedia\JsonCodec\JsonCodecable;
9use Wikimedia\JsonCodec\JsonCodecableTrait;
10
11class TemplateInfo implements JsonCodecable {
12    use JsonCodecableTrait;
13
14    /**
15     * The target wikitext
16     */
17    public ?string $targetWt = null;
18
19    /**
20     * The parser function name
21     */
22    public ?string $func = null;
23
24    /**
25     * The URL of the target
26     */
27    public ?string $href = null;
28
29    /**
30     * Param infos indexed by key (ParamInfo->k)
31     * @var list<ParamInfo>
32     */
33    public array $paramInfos = [];
34
35    /**
36     * The type of template (template, templatearg, parserfunction).
37     * @note For backward-compatibility reasons, this property is
38     * not serialized/deserialized.
39     * @var 'template'|'templatearg'|'parserfunction'|null
40     */
41    public ?string $type = null;
42
43    /**
44     * The index into data-parsoid.pi
45     */
46    public ?int $i = null;
47
48    public function __clone() {
49        foreach ( $this->paramInfos as &$pi ) {
50            $pi = clone $pi;
51        }
52    }
53
54    /** @inheritDoc */
55    public static function newFromJsonArray( array $json ): TemplateInfo {
56        $ti = new TemplateInfo;
57        $ti->targetWt = $json['target']['wt'] ?? null;
58        $ti->href = $json['target']['href'] ?? null;
59        $ti->func = $json['target']['function'] ?? null;
60        $ti->paramInfos = [];
61        $params = (array)( $json['params'] ?? null );
62        foreach ( $params as $k => $v ) {
63            // Converting $params to an array can turn the keys into ints,
64            // so we need to explicitly cast them back to string.
65            $info = new ParamInfo( (string)$k );
66            $info->valueWt = $v->wt ?? null;
67            $info->html = $v->html ?? null;
68            $info->keyWt = $v->key->wt ?? null;
69            $ti->paramInfos[] = $info;
70        }
71        $ti->i = $json['i'] ?? null;
72        return $ti;
73    }
74
75    /** @inheritDoc */
76    public static function jsonClassHintFor( string $keyname ) {
77        static $hints = null;
78        if ( $hints === null ) {
79            $hints = [
80                // The most deeply nested stdClass structure is "wt" inside
81                // "key" inside a parameter:
82                //     "params":{"1":{"key":{"wt":"..."}}}
83                'params' => Hint::build(
84                    stdClass::class, Hint::ALLOW_OBJECT,
85                    Hint::STDCLASS, Hint::ALLOW_OBJECT,
86                    Hint::STDCLASS, Hint::ALLOW_OBJECT
87                ),
88            ];
89        }
90        return $hints[$keyname] ?? null;
91    }
92
93    /** @inheritDoc */
94    public function toJsonArray(): array {
95        // This is a complicated serialization, but necessary for
96        // backward compatibility with existing data-mw
97        $target = [ 'wt' => $this->targetWt ];
98        if ( $this->func !== null ) {
99            $target['function'] = $this->func;
100        }
101        if ( $this->href !== null ) {
102            $target['href'] = $this->href;
103        }
104        $params = [];
105        foreach ( $this->paramInfos as $info ) {
106            // Non-standard serialization of ParamInfo, alas.
107            $param = [
108                'wt' => $info->valueWt,
109            ];
110            if ( $info->html !== null ) {
111                $param['html'] = $info->html;
112            }
113            if ( $info->keyWt !== null ) {
114                $param['key'] = (object)[
115                    'wt' => $info->keyWt,
116                ];
117            }
118            $params[$info->k] = (object)$param;
119        }
120        return [
121            'target' => $target,
122            'params' => (object)$params,
123            'i' => $this->i,
124        ];
125    }
126}