Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 140 |
|
0.00% |
0 / 2 |
CRAP | |
0.00% |
0 / 1 |
PFAutoEdit | |
0.00% |
0 / 140 |
|
0.00% |
0 / 2 |
1560 | |
0.00% |
0 / 1 |
run | |
0.00% |
0 / 134 |
|
0.00% |
0 / 1 |
1482 | |||
convertQueryString | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | /** |
4 | * '#autoedit' is called as: |
5 | * |
6 | * {{#autoedit:form=|target=|link text=|link type=|tooltip=|query string= |
7 | * |minor|reload}} |
8 | * |
9 | * This function creates a link or button that, when clicked on, |
10 | * automatically modifies the specified page according to the values in the |
11 | * 'query string' variable. |
12 | * |
13 | * The parameters of #autoedit are called in the same format as those |
14 | * of #formlink. T The two additions are: |
15 | * 'minor' - sets this to be a "minor edit" |
16 | * 'reload' - causes the page to reload after the user clicks the button |
17 | * or link. |
18 | */ |
19 | |
20 | use MediaWiki\MediaWikiServices; |
21 | |
22 | class PFAutoEdit { |
23 | public static function run( Parser $parser ) { |
24 | global $wgPageFormsAutoeditNamespaces; |
25 | |
26 | $parser->getOutput()->addModules( [ 'ext.pageforms.autoedit' ] ); |
27 | if ( method_exists( $parser->getOutput(), 'setPreventClickjacking' ) ) { |
28 | // MW 1.38+ |
29 | $parser->getOutput()->setPreventClickjacking( true ); |
30 | } else { |
31 | $parser->getOutput()->preventClickjacking( true ); |
32 | } |
33 | |
34 | // Set defaults. |
35 | $formcontent = ''; |
36 | $linkString = null; |
37 | $linkType = 'span'; |
38 | $summary = null; |
39 | $minorEdit = false; |
40 | $classString = 'autoedit-trigger'; |
41 | $inTooltip = null; |
42 | $inQueryArr = []; |
43 | $editTime = null; |
44 | $latestRevId = null; |
45 | $confirmEdit = false; |
46 | $redirect = ''; |
47 | $bringToPage = false; |
48 | $linkToPage = '#'; |
49 | |
50 | // Parse parameters. |
51 | $params = func_get_args(); |
52 | // We don't need the parser. |
53 | array_shift( $params ); |
54 | |
55 | $wikiPageFactory = MediaWikiServices::getInstance()->getWikiPageFactory(); |
56 | |
57 | foreach ( $params as $param ) { |
58 | $elements = explode( '=', $param, 2 ); |
59 | |
60 | $key = trim( $elements[ 0 ] ); |
61 | $value = ( count( $elements ) > 1 ) ? trim( $elements[ 1 ] ) : ''; |
62 | |
63 | switch ( $key ) { |
64 | case 'link text': |
65 | $linkString = $parser->recursiveTagParse( $value ); |
66 | break; |
67 | case 'link type': |
68 | $linkType = $parser->recursiveTagParse( $value ); |
69 | break; |
70 | case 'reload': |
71 | $classString .= ' reload'; |
72 | break; |
73 | case 'summary': |
74 | $summary = $parser->recursiveTagParse( $value ); |
75 | break; |
76 | case 'minor': |
77 | $minorEdit = true; |
78 | break; |
79 | case 'confirm': |
80 | $confirmEdit = true; |
81 | break; |
82 | case 'query string': |
83 | $inQueryArr = self::convertQueryString( $value, $inQueryArr ); |
84 | break; |
85 | |
86 | case 'ok text': |
87 | case 'error text': |
88 | // do not parse ok text or error text yet. Will be parsed on api call |
89 | $arr = [ $key => $value ]; |
90 | $inQueryArr = PFUtils::arrayMergeRecursiveDistinct( $inQueryArr, $arr ); |
91 | break; |
92 | case 'tooltip': |
93 | $inTooltip = Sanitizer::decodeCharReferences( $value ); |
94 | break; |
95 | |
96 | case 'target': |
97 | case 'title': |
98 | $value = $parser->recursiveTagParse( $value ); |
99 | $arr = [ $key => $value ]; |
100 | $inQueryArr = PFUtils::arrayMergeRecursiveDistinct( $inQueryArr, $arr ); |
101 | |
102 | $targetTitle = Title::newFromText( $value ); |
103 | |
104 | if ( $targetTitle !== null ) { |
105 | $allowedNamespaces = array_merge( |
106 | $wgPageFormsAutoeditNamespaces, |
107 | [ NS_CATEGORY ] |
108 | ); |
109 | if ( !in_array( $targetTitle->getNamespace(), $allowedNamespaces ) ) { |
110 | $errorMsg = wfMessage( 'pf-autoedit-invalidnamespace', $targetTitle->getNsText() )->parse(); |
111 | return Html::element( 'div', [ 'class' => 'error' ], $errorMsg ); |
112 | } |
113 | $targetWikiPage = $wikiPageFactory->newFromTitle( $targetTitle ); |
114 | $targetWikiPage->clear(); |
115 | $editTime = $targetWikiPage->getTimestamp(); |
116 | $latestRevId = $targetWikiPage->getLatest(); |
117 | } |
118 | break; |
119 | case 'redirect': |
120 | $redirect = $value; |
121 | break; |
122 | case 'bring to page': |
123 | $bringToPage = true; |
124 | break; |
125 | |
126 | default: |
127 | $value = $parser->recursiveTagParse( $value ); |
128 | $arr = [ $key => $value ]; |
129 | $inQueryArr = PFUtils::arrayMergeRecursiveDistinct( $inQueryArr, $arr ); |
130 | } |
131 | } |
132 | |
133 | if ( $redirect != '' && $bringToPage ) { |
134 | $errorMsg = wfMessage( 'pf_autoedit_notsettogether', 'redirect', 'bring to page' )->parse(); |
135 | return Html::element( 'div', [ 'class' => 'error' ], $errorMsg ); |
136 | } |
137 | |
138 | if ( $redirect != '' ) { |
139 | $linkToPage = $redirect; |
140 | } elseif ( $bringToPage ) { |
141 | $linkToPage = $targetTitle->getFullURL(); |
142 | } |
143 | |
144 | // query string has to be turned into hidden inputs. |
145 | if ( !empty( $inQueryArr ) ) { |
146 | $query_components = explode( '&', http_build_query( $inQueryArr, '', '&' ) ); |
147 | |
148 | foreach ( $query_components as $query_component ) { |
149 | $var_and_val = explode( '=', $query_component, 2 ); |
150 | if ( count( $var_and_val ) == 2 ) { |
151 | $formcontent .= Html::hidden( urldecode( $var_and_val[0] ), urldecode( $var_and_val[1] ) ); |
152 | } |
153 | } |
154 | } |
155 | |
156 | if ( $linkString == null ) { |
157 | return null; |
158 | } |
159 | |
160 | if ( $linkType == 'button' ) { |
161 | $attrs = [ |
162 | 'flags' => 'progressive', |
163 | 'label' => $linkString, |
164 | 'classes' => [ $classString ], |
165 | 'href' => $linkToPage |
166 | ]; |
167 | if ( $inTooltip != null ) { |
168 | $attrs['title'] = $inTooltip; |
169 | } |
170 | $parser->getOutput()->setEnableOOUI( true ); |
171 | OutputPage::setupOOUI(); |
172 | $linkElement = new OOUI\ButtonWidget( $attrs ); |
173 | } elseif ( $linkType == 'link' ) { |
174 | $attrs = [ 'class' => $classString, 'href' => $linkToPage ]; |
175 | if ( $inTooltip != null ) { |
176 | $attrs['title'] = $inTooltip; |
177 | } |
178 | $linkElement = Html::rawElement( 'a', $attrs, $linkString ); |
179 | } else { |
180 | $linkElement = Html::rawElement( 'span', [ 'class' => $classString ], $linkString ); |
181 | } |
182 | |
183 | if ( $summary == null ) { |
184 | $summary = wfMessage( 'pf_autoedit_summary', "[[{$parser->getTitle()}]]" )->text(); |
185 | } |
186 | |
187 | $formcontent .= Html::hidden( 'wpSummary', $summary ); |
188 | |
189 | if ( $minorEdit ) { |
190 | $formcontent .= Html::hidden( 'wpMinoredit', true ); |
191 | } |
192 | |
193 | if ( $editTime !== null ) { |
194 | $formcontent .= Html::hidden( 'wpEdittime', $editTime ); |
195 | } |
196 | if ( $latestRevId !== null ) { |
197 | $formcontent .= Html::hidden( 'editRevId', $latestRevId ); |
198 | } |
199 | |
200 | if ( $confirmEdit ) { |
201 | $formAttrs = [ 'class' => [ 'autoedit-data', 'confirm-edit' ] ]; |
202 | } else { |
203 | $formAttrs = [ 'class' => 'autoedit-data' ]; |
204 | } |
205 | |
206 | $form = Html::rawElement( 'form', $formAttrs, $formcontent ); |
207 | |
208 | $output = Html::rawElement( 'div', [ 'class' => 'autoedit' ], |
209 | $linkElement . |
210 | Html::rawElement( 'span', [ 'class' => "autoedit-result" ], null ) . |
211 | $form |
212 | ); |
213 | |
214 | // Return output HTML. |
215 | return [ $output, 'noparse' => true, 'isHTML' => true ]; |
216 | } |
217 | |
218 | public static function convertQueryString( $queryString, $inQueryArr ) { |
219 | // Change HTML-encoded ampersands directly to URL-encoded |
220 | // ampersands, so that the string doesn't get split up on the '&'. |
221 | $queryString = str_replace( '&', '%26', $queryString ); |
222 | // "Decode" any other HTML tags. |
223 | $queryString = html_entity_decode( $queryString, ENT_QUOTES ); |
224 | // next, replace Foo[Bar] += Baz with Foo[Bar+] = Baz |
225 | // and do the same for -= |
226 | // This way, parse_str won't strip out the += and -= |
227 | $queryString = preg_replace( "/\[([^\]]+)\]\s*(\+|-)=/", "[$1$2]=", $queryString ); |
228 | // Prevent "decoding" + into a space character |
229 | $queryString = str_replace( '+', '%2B', $queryString ); |
230 | |
231 | parse_str( $queryString, $arr ); |
232 | |
233 | return PFUtils::arrayMergeRecursiveDistinct( $inQueryArr, $arr ); |
234 | } |
235 | } |