SECURITY: rate-limit and prevent blocked users from changing email
[lhc/web/wiklou.git] / includes / parser / PPTemplateFrame_DOM.php
1 <?php
2 /**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
17 *
18 * @file
19 * @ingroup Parser
20 */
21
22 /**
23 * Expansion frame with template arguments
24 * @ingroup Parser
25 */
26 // phpcs:ignore Squiz.Classes.ValidClassName.NotCamelCaps
27 class PPTemplateFrame_DOM extends PPFrame_DOM {
28
29 public $numberedArgs, $namedArgs;
30
31 /**
32 * @var PPFrame_DOM
33 */
34 public $parent;
35 public $numberedExpansionCache, $namedExpansionCache;
36
37 /**
38 * @param Preprocessor $preprocessor
39 * @param bool|PPFrame_DOM $parent
40 * @param array $numberedArgs
41 * @param array $namedArgs
42 * @param bool|Title $title
43 */
44 public function __construct( $preprocessor, $parent = false, $numberedArgs = [],
45 $namedArgs = [], $title = false
46 ) {
47 parent::__construct( $preprocessor );
48
49 $this->parent = $parent;
50 $this->numberedArgs = $numberedArgs;
51 $this->namedArgs = $namedArgs;
52 $this->title = $title;
53 $pdbk = $title ? $title->getPrefixedDBkey() : false;
54 $this->titleCache = $parent->titleCache;
55 $this->titleCache[] = $pdbk;
56 $this->loopCheckHash = /*clone*/ $parent->loopCheckHash;
57 if ( $pdbk !== false ) {
58 $this->loopCheckHash[$pdbk] = true;
59 }
60 $this->depth = $parent->depth + 1;
61 $this->numberedExpansionCache = $this->namedExpansionCache = [];
62 }
63
64 public function __toString() {
65 $s = 'tplframe{';
66 $first = true;
67 $args = $this->numberedArgs + $this->namedArgs;
68 foreach ( $args as $name => $value ) {
69 if ( $first ) {
70 $first = false;
71 } else {
72 $s .= ', ';
73 }
74 $s .= "\"$name\":\"" .
75 str_replace( '"', '\\"', $value->ownerDocument->saveXML( $value ) ) . '"';
76 }
77 $s .= '}';
78 return $s;
79 }
80
81 /**
82 * @throws MWException
83 * @param string|int $key
84 * @param string|PPNode_DOM|DOMDocument $root
85 * @param int $flags
86 * @return string
87 */
88 public function cachedExpand( $key, $root, $flags = 0 ) {
89 if ( isset( $this->parent->childExpansionCache[$key] ) ) {
90 return $this->parent->childExpansionCache[$key];
91 }
92 $retval = $this->expand( $root, $flags );
93 if ( !$this->isVolatile() ) {
94 $this->parent->childExpansionCache[$key] = $retval;
95 }
96 return $retval;
97 }
98
99 /**
100 * Returns true if there are no arguments in this frame
101 *
102 * @return bool
103 */
104 public function isEmpty() {
105 return !count( $this->numberedArgs ) && !count( $this->namedArgs );
106 }
107
108 public function getArguments() {
109 $arguments = [];
110 foreach ( array_merge(
111 array_keys( $this->numberedArgs ),
112 array_keys( $this->namedArgs ) ) as $key ) {
113 $arguments[$key] = $this->getArgument( $key );
114 }
115 return $arguments;
116 }
117
118 public function getNumberedArguments() {
119 $arguments = [];
120 foreach ( array_keys( $this->numberedArgs ) as $key ) {
121 $arguments[$key] = $this->getArgument( $key );
122 }
123 return $arguments;
124 }
125
126 public function getNamedArguments() {
127 $arguments = [];
128 foreach ( array_keys( $this->namedArgs ) as $key ) {
129 $arguments[$key] = $this->getArgument( $key );
130 }
131 return $arguments;
132 }
133
134 /**
135 * @param int $index
136 * @return string|bool
137 */
138 public function getNumberedArgument( $index ) {
139 if ( !isset( $this->numberedArgs[$index] ) ) {
140 return false;
141 }
142 if ( !isset( $this->numberedExpansionCache[$index] ) ) {
143 # No trimming for unnamed arguments
144 $this->numberedExpansionCache[$index] = $this->parent->expand(
145 $this->numberedArgs[$index],
146 PPFrame::STRIP_COMMENTS
147 );
148 }
149 return $this->numberedExpansionCache[$index];
150 }
151
152 /**
153 * @param string $name
154 * @return string|bool
155 */
156 public function getNamedArgument( $name ) {
157 if ( !isset( $this->namedArgs[$name] ) ) {
158 return false;
159 }
160 if ( !isset( $this->namedExpansionCache[$name] ) ) {
161 # Trim named arguments post-expand, for backwards compatibility
162 $this->namedExpansionCache[$name] = trim(
163 $this->parent->expand( $this->namedArgs[$name], PPFrame::STRIP_COMMENTS ) );
164 }
165 return $this->namedExpansionCache[$name];
166 }
167
168 /**
169 * @param int|string $name
170 * @return string|bool
171 */
172 public function getArgument( $name ) {
173 $text = $this->getNumberedArgument( $name );
174 if ( $text === false ) {
175 $text = $this->getNamedArgument( $name );
176 }
177 return $text;
178 }
179
180 /**
181 * Return true if the frame is a template frame
182 *
183 * @return bool
184 */
185 public function isTemplate() {
186 return true;
187 }
188
189 public function setVolatile( $flag = true ) {
190 parent::setVolatile( $flag );
191 $this->parent->setVolatile( $flag );
192 }
193
194 public function setTTL( $ttl ) {
195 parent::setTTL( $ttl );
196 $this->parent->setTTL( $ttl );
197 }
198 }