Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 38
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
AttributeTransformManager
0.00% covered (danger)
0.00%
0 / 38
0.00% covered (danger)
0.00%
0 / 2
272
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 process
0.00% covered (danger)
0.00%
0 / 36
0.00% covered (danger)
0.00%
0 / 1
240
1<?php
2declare( strict_types = 1 );
3
4namespace Wikimedia\Parsoid\Wt2Html\TT;
5
6use Wikimedia\Parsoid\Tokens\KV;
7use Wikimedia\Parsoid\Wt2Html\Frame;
8
9/**
10 * Utility transformation manager for expanding attributes
11 * whose keys and/or values are not plain strings.
12 */
13class AttributeTransformManager {
14    /**
15     * @var array
16     */
17    private $options;
18
19    /**
20     * @var Frame
21     */
22    private $frame;
23
24    /**
25     * @param Frame $frame
26     * @param array $options
27     *  - bool inTemplate (reqd) Is this being invoked while processing a template?
28     *  - bool expandTemplates (reqd) Should we expand templates encountered here?
29     */
30    public function __construct( Frame $frame, array $options ) {
31        $this->options = $options;
32        $this->frame = $frame;
33    }
34
35    /**
36     * Expand both key and values of all key/value pairs. Used for generic
37     * (non-template) tokens in the AttributeExpander handler, which runs after
38     * templates are already expanded.
39     *
40     * @param KV[] $attributes
41     * @return KV[] expanded attributes
42     */
43    public function process( array $attributes ): array {
44        // Transform each argument (key and value).
45        foreach ( $attributes as &$cur ) {
46            $k = $cur->k;
47            $v = $cur->v;
48            if ( $cur->v === null ) {
49                $cur->v = $v = '';
50            }
51
52            // fast path for string-only attributes
53            if ( is_string( $k ) && is_string( $v ) ) {
54                continue;
55            }
56
57            $expandV = false;
58            if ( is_array( $v ) ) {
59                foreach ( $v as $vv ) {
60                    if ( !is_string( $vv ) ) {
61                        $expandV = true;
62                        break;
63                    }
64                }
65
66                if ( $expandV ) {
67                    // transform the value
68                    $v = $this->frame->expand( $v, [
69                        'attrExpansion' => true,
70                        'expandTemplates' => $this->options['expandTemplates'],
71                        'inTemplate' => $this->options['inTemplate'],
72                        'srcOffsets' => $cur->srcOffsets->value,
73                    ] );
74                }
75            }
76
77            $expandK = false;
78            if ( is_array( $k ) ) {
79                foreach ( $k as $kk ) {
80                    if ( !is_string( $kk ) ) {
81                        $expandK = true;
82                        break;
83                    }
84                }
85
86                if ( $expandK ) {
87                    // transform the key
88                    $k = $this->frame->expand( $k, [
89                        'attrExpansion' => true,
90                        'expandTemplates' => $this->options['expandTemplates'],
91                        'inTemplate' => $this->options['inTemplate'],
92                        'srcOffsets' => $cur->srcOffsets->key,
93                    ] );
94                }
95            }
96
97            if ( $expandK || $expandV ) {
98                $cur = new KV( $k, $v, $cur->srcOffsets );
99            }
100        }
101
102        return $attributes;
103    }
104}