Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 121 |
|
0.00% |
0 / 3 |
CRAP | |
0.00% |
0 / 1 |
PFFormLink | |
0.00% |
0 / 121 |
|
0.00% |
0 / 3 |
2550 | |
0.00% |
0 / 1 |
run | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
createFormLink | |
0.00% |
0 / 115 |
|
0.00% |
0 / 1 |
2352 | |||
loadScriptsForPopupForm | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | use MediaWiki\MediaWikiServices; |
3 | |
4 | /** |
5 | * '#formlink' is called as: |
6 | * |
7 | * {{#formlink:form=|link text=|link type=|tooltip=|query string=|target= |
8 | * |popup|reload|...additional query string values...}} |
9 | * |
10 | * This function returns HTML representing a link to a form; given that |
11 | * no page name is entered by the user, the form must be one that |
12 | * creates an automatic page name, or else it will display an error |
13 | * message when the user clicks on the link. |
14 | * |
15 | * The first two arguments are mandatory: |
16 | * 'form' is the name of the PF form, and 'link text' is the text of the link. |
17 | * 'link type' is the type of the link: if set to 'button', the link will be |
18 | * a button; if set to 'post button', the link will be a button that uses the |
19 | * 'POST' method to send other values to the form; if set to anything else or |
20 | * not called, it will be a standard hyperlink. |
21 | * 'tooltip' sets a hovering tooltip text, if it's an actual link. |
22 | * 'query string' is the text to be added to the generated URL's query string |
23 | * (or, in the case of 'post button', to be sent as hidden inputs). |
24 | * 'target' is an optional value, setting the name of the page to be |
25 | * edited by the form. |
26 | * 'reload' is an optional parameter that can be used alongside either |
27 | * 'popup' or 'returnto'; it causes the page that the user ends up on after |
28 | * submitting the form to get reloaded with 'action=purge'. |
29 | * |
30 | * Example: to create a link to add data with a form called |
31 | * 'User' within a namespace also called 'User', and to have the form |
32 | * preload with the page called 'UserStub', you could call the following: |
33 | * |
34 | * {{#formlink:form=User|link text=Add a user |
35 | * |query string=namespace=User&preload=UserStub}} |
36 | */ |
37 | |
38 | class PFFormLink { |
39 | |
40 | public static function run( Parser $parser ) { |
41 | $params = func_get_args(); |
42 | // We don't need the parser. |
43 | array_shift( $params ); |
44 | $str = self::createFormLink( $parser, $params ); |
45 | return [ $str, 'noparse' => true, 'isHTML' => true ]; |
46 | } |
47 | |
48 | protected static function createFormLink( Parser $parser, $params ) { |
49 | // Set defaults. |
50 | $inFormName = $inLinkStr = $inExistingPageLinkStr = $inLinkType = |
51 | $inTooltip = $inTargetName = ''; |
52 | $hasPopup = $hasReturnTo = false; |
53 | $className = static::class; |
54 | if ( $className == 'PFQueryFormLink' ) { |
55 | $inLinkStr = wfMessage( 'runquery' )->parse(); |
56 | } |
57 | $inCreatePage = false; |
58 | $classStr = ''; |
59 | $inQueryArr = []; |
60 | $targetWindow = '_self'; |
61 | |
62 | // Needed for the 'next' icon. |
63 | $parser->getOutput()->addModules( [ 'oojs-ui.styles.icons-movement' ] ); |
64 | |
65 | // assign params |
66 | // - support unlabelled params, for backwards compatibility |
67 | // - parse and sanitize all parameter values |
68 | foreach ( $params as $i => $param ) { |
69 | $elements = explode( '=', $param, 2 ); |
70 | |
71 | // set param_name and value |
72 | if ( count( $elements ) > 1 ) { |
73 | $param_name = trim( $elements[0] ); |
74 | |
75 | // parse (and sanitize) parameter values |
76 | $value = trim( $parser->recursiveTagParse( $elements[1] ) ); |
77 | } else { |
78 | $param_name = null; |
79 | |
80 | // parse (and sanitize) parameter values |
81 | $value = trim( $parser->recursiveTagParse( $param ) ); |
82 | } |
83 | |
84 | if ( $param_name == 'form' ) { |
85 | $inFormName = $value; |
86 | } elseif ( $param_name == 'link text' ) { |
87 | $inLinkStr = $value; |
88 | } elseif ( $param_name == 'existing page link text' ) { |
89 | $inExistingPageLinkStr = $value; |
90 | } elseif ( $param_name == 'link type' ) { |
91 | $inLinkType = $value; |
92 | } elseif ( $param_name == 'query string' ) { |
93 | $inQueryArr = PFAutoEdit::convertQueryString( $value, $inQueryArr ); |
94 | } elseif ( $param_name == 'tooltip' ) { |
95 | $inTooltip = Sanitizer::decodeCharReferences( $value ); |
96 | } elseif ( $param_name == 'target' ) { |
97 | $inTargetName = Sanitizer::decodeCharReferences( $value ); |
98 | } elseif ( $param_name == null && $value == 'popup' ) { |
99 | self::loadScriptsForPopupForm( $parser ); |
100 | $classStr = 'popupformlink'; |
101 | $hasPopup = true; |
102 | } elseif ( $param_name == null && $value == 'reload' ) { |
103 | $classStr .= ' reload'; |
104 | $inQueryArr['reload'] = '1'; |
105 | } elseif ( $param_name == null && $value == 'new window' ) { |
106 | $targetWindow = '_blank'; |
107 | } elseif ( $param_name == null && $value == 'create page' ) { |
108 | $inCreatePage = true; |
109 | } elseif ( $param_name !== null ) { |
110 | $value = urlencode( $value ); |
111 | parse_str( "$param_name=$value", $arr ); |
112 | $inQueryArr = PFUtils::arrayMergeRecursiveDistinct( $inQueryArr, $arr ); |
113 | if ( $param_name == 'returnto' ) { |
114 | $hasReturnTo = true; |
115 | } |
116 | } |
117 | } |
118 | |
119 | if ( $hasPopup && $hasReturnTo ) { |
120 | return '<div class="error">Error: \'popup\' and \'returnto\' cannot be set in the same function.</div>'; |
121 | } |
122 | |
123 | // Not the most graceful way to do this, but it is the |
124 | // easiest - if this is the #formredlink function, just |
125 | // ignore whatever values were passed in for these params. |
126 | if ( $className == 'PFFormRedLink' ) { |
127 | $inLinkType = $inTooltip = null; |
128 | } |
129 | |
130 | // If "red link only" was specified, and a target page was |
131 | // specified, and it exists, just link to the page. |
132 | if ( $inTargetName != '' ) { |
133 | // Call urldecode() on it, in case the target was |
134 | // set via {{PAGENAMEE}}, and the page name contains |
135 | // an apostrophe or other unusual character. |
136 | $targetTitle = Title::newFromText( urldecode( $inTargetName ) ); |
137 | $targetPageExists = ( $targetTitle != '' && $targetTitle->exists() ); |
138 | } else { |
139 | $targetPageExists = false; |
140 | } |
141 | |
142 | if ( $className == 'PFFormRedLink' && $targetPageExists ) { |
143 | $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer(); |
144 | if ( $inExistingPageLinkStr == '' ) { |
145 | return $linkRenderer->makeKnownLink( $targetTitle ); |
146 | } else { |
147 | return $linkRenderer->makeKnownLink( $targetTitle, $inExistingPageLinkStr ); |
148 | } |
149 | } |
150 | |
151 | // The page doesn't exist, so if 'create page' was |
152 | // specified, create the page now. |
153 | if ( $className == 'PFFormRedLink' && |
154 | $inCreatePage && $inTargetName != '' ) { |
155 | $targetTitle = Title::newFromText( $inTargetName ); |
156 | PFFormLinker::createPageWithForm( $targetTitle, $inFormName, $inQueryArr ); |
157 | } |
158 | |
159 | if ( $className == 'PFQueryFormLink' ) { |
160 | $formSpecialPage = PFUtils::getSpecialPage( 'RunQuery' ); |
161 | } else { |
162 | $formSpecialPage = PFUtils::getSpecialPage( 'FormEdit' ); |
163 | } |
164 | $formSpecialPageTitle = $formSpecialPage->getPageTitle(); |
165 | |
166 | if ( $inFormName == '' ) { |
167 | $query = [ 'target' => $inTargetName ]; |
168 | $link_url = $formSpecialPageTitle->getLocalURL( $query ); |
169 | } elseif ( strpos( $inFormName, '/' ) == true ) { |
170 | $query = [ 'form' => $inFormName, 'target' => $inTargetName ]; |
171 | $link_url = $formSpecialPageTitle->getLocalURL( $query ); |
172 | } else { |
173 | $link_url = $formSpecialPageTitle->getLocalURL() . "/$inFormName"; |
174 | if ( !empty( $inTargetName ) ) { |
175 | $link_url .= "/$inTargetName"; |
176 | } |
177 | $link_url = str_replace( ' ', '_', $link_url ); |
178 | } |
179 | $hidden_inputs = ""; |
180 | if ( !empty( $inQueryArr ) ) { |
181 | // Special handling for the buttons - query string |
182 | // has to be turned into hidden inputs. |
183 | if ( $inLinkType == 'button' || $inLinkType == 'post button' ) { |
184 | $query_components = explode( '&', http_build_query( $inQueryArr, '', '&' ) ); |
185 | |
186 | foreach ( $query_components as $query_component ) { |
187 | $var_and_val = explode( '=', $query_component, 2 ); |
188 | if ( count( $var_and_val ) == 2 ) { |
189 | $hidden_inputs .= Html::hidden( urldecode( $var_and_val[0] ), urldecode( $var_and_val[1] ) ); |
190 | } |
191 | } |
192 | } else { |
193 | $link_url .= ( strstr( $link_url, '?' ) ) ? '&' : '?'; |
194 | $link_url .= str_replace( '+', '%20', http_build_query( $inQueryArr, '', '&' ) ); |
195 | } |
196 | } |
197 | if ( $inLinkType == 'button' || $inLinkType == 'post button' ) { |
198 | $parser->getOutput()->setEnableOOUI( true ); |
199 | OutputPage::setupOOUI(); |
200 | $buttonAttrs = [ |
201 | 'type' => 'submit', |
202 | 'label' => $inLinkStr, |
203 | 'title' => $inTooltip, |
204 | 'flags' => 'progressive', |
205 | 'icon' => 'next' |
206 | ]; |
207 | $buttonHTML = new OOUI\ButtonInputWidget( $buttonAttrs ); |
208 | $formAttrs = [ |
209 | 'action' => $link_url, |
210 | 'method' => ( $inLinkType == 'button' ) ? 'get' : 'post', |
211 | 'class' => $classStr, |
212 | 'target' => $targetWindow |
213 | ]; |
214 | $str = Html::rawElement( 'form', $formAttrs, $buttonHTML . $hidden_inputs ); |
215 | } else { |
216 | // If a target page has been specified but it doesn't |
217 | // exist, make it a red link. |
218 | if ( !empty( $inTargetName ) ) { |
219 | if ( !$targetPageExists ) { |
220 | $classStr .= " new"; |
221 | } |
222 | // If no link string was specified, make it |
223 | // the name of the page. |
224 | if ( $inLinkStr == '' ) { |
225 | $inLinkStr = $inTargetName; |
226 | } |
227 | } |
228 | $str = Html::rawElement( 'a', [ 'href' => $link_url, 'class' => $classStr, 'title' => $inTooltip, 'target' => $targetWindow ], $inLinkStr ); |
229 | } |
230 | |
231 | return $str; |
232 | } |
233 | |
234 | public static function loadScriptsForPopupForm( Parser $parser ) { |
235 | $parser->getOutput()->addModules( [ 'ext.pageforms.popupformedit' ] ); |
236 | return true; |
237 | } |
238 | } |