Index: trunk/extensions/QPoll/qp_interpret.php |
— | — | @@ -1,119 +0,0 @@ |
2 | | -<?php |
3 | | -/** |
4 | | - * ***** BEGIN LICENSE BLOCK ***** |
5 | | - * This file is part of QPoll. |
6 | | - * Uses parts of code from Quiz extension (c) 2007 Louis-Rémi BABE. All rights reserved. |
7 | | - * |
8 | | - * QPoll is free software; you can redistribute it and/or modify |
9 | | - * it under the terms of the GNU General Public License as published by |
10 | | - * the Free Software Foundation; either version 2 of the License, or |
11 | | - * (at your option) any later version. |
12 | | - * |
13 | | - * QPoll is distributed in the hope that it will be useful, |
14 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | | - * GNU General Public License for more details. |
17 | | - * |
18 | | - * You should have received a copy of the GNU General Public License |
19 | | - * along with QPoll; if not, write to the Free Software |
20 | | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 | | - * |
22 | | - * ***** END LICENSE BLOCK ***** |
23 | | - * |
24 | | - * QPoll is a poll tool for MediaWiki. |
25 | | - * |
26 | | - * To activate this extension : |
27 | | - * * Create a new directory named QPoll into the directory "extensions" of MediaWiki. |
28 | | - * * Place the files from the extension archive there. |
29 | | - * * Add this line at the end of your LocalSettings.php file : |
30 | | - * require_once "$IP/extensions/QPoll/qp_user.php"; |
31 | | - * |
32 | | - * @version 0.8.0a |
33 | | - * @link http://www.mediawiki.org/wiki/Extension:QPoll |
34 | | - * @author QuestPC <questpc@rambler.ru> |
35 | | - */ |
36 | | - |
37 | | -if ( !defined( 'MEDIAWIKI' ) ) { |
38 | | - die( "This file is part of the QPoll extension. It is not a valid entry point.\n" ); |
39 | | -} |
40 | | - |
41 | | -class qp_Interpret { |
42 | | - |
43 | | - /** |
44 | | - * Glues the content of <qpinterpret> tags together, checks "lang" attribute |
45 | | - * and calls appropriate interpretator to evaluate the user answer |
46 | | - * |
47 | | - * @param $interpArticle _existing_ article with interpretation script enclosed in <qpinterp> tags |
48 | | - * @param $answers array of user selected categories for every proposal & question of the poll |
49 | | - * @return instance of qp_InterpAnswer class |
50 | | - */ |
51 | | - static function getAnswer( $interpArticle, $answers ) { |
52 | | - global $wgParser; |
53 | | - $matches = array(); |
54 | | - # extract <qpinterpret> tags from the article content |
55 | | - $wgParser->extractTagsAndParams( array( qp_Setup::$interpTag ), $interpArticle->getRawText(), $matches ); |
56 | | - $interpAnswer = new qp_InterpAnswer(); |
57 | | - # glue content of all <qpinterpret> tags at the page together |
58 | | - $interpretScript = ''; |
59 | | - $lang = ''; |
60 | | - foreach ( $matches as &$match ) { |
61 | | - list( $tagName, $content, $attrs ) = $match; |
62 | | - # basic checks for lang attribute (only lang="php" is implemented yet) |
63 | | - # however we do not want to limit interpretation language, |
64 | | - # so the attribute is enforced to use |
65 | | - if ( !isset( $attrs['lang'] ) ) { |
66 | | - return $interpAnswer->setError( wfMsg( 'qp_error_eval_missed_lang_attr' ) ); |
67 | | - } |
68 | | - if ( $lang == '' ) { |
69 | | - $lang = $attrs['lang']; |
70 | | - } elseif ( $attrs['lang'] != $lang ) { |
71 | | - return $interpAnswer->setError( wfMsg( 'qp_error_eval_mix_languages', $lang, $attrs['lang'] ) ); |
72 | | - } |
73 | | - if ( $tagName == qp_Setup::$interpTag ) { |
74 | | - $interpretScript .= $content; |
75 | | - } |
76 | | - } |
77 | | - switch ( $lang ) { |
78 | | - case 'php' : |
79 | | - $result = qp_Eval::interpretAnswer( $interpretScript, $answers, $interpAnswer ); |
80 | | - if ( $result instanceof qp_InterpAnswer ) { |
81 | | - # evaluation error (environment error) , return it; |
82 | | - return $interpAnswer; |
83 | | - } |
84 | | - break; |
85 | | - default : |
86 | | - return $interpAnswer->setError( wfMsg( 'qp_error_eval_unsupported_language', $lang ) ); |
87 | | - } |
88 | | - /*** process the result ***/ |
89 | | - if ( !is_array( $result ) ) { |
90 | | - return $interpAnswer->setError( wfMsg( 'qp_error_interpretation_no_return' ) ); |
91 | | - } |
92 | | - # initialize $interpAnswer->qpError[] member array |
93 | | - foreach ( $result as $qidx => $question ) { |
94 | | - if ( is_int( $qidx ) && is_array( $question ) ) { |
95 | | - foreach ( $question as $pidx => $error ) { |
96 | | - if ( is_int( $pidx ) ) { |
97 | | - # everywhere but interpretation scripts: |
98 | | - # question start from 1, proposals start from 0 |
99 | | - $interpAnswer->setQPerror( $qidx + 1, $pidx, $error ); |
100 | | - } |
101 | | - } |
102 | | - } |
103 | | - } |
104 | | - if ( isset( $result['error'] ) && trim( $result['error'] ) != '' ) { |
105 | | - # script-generated error for the whole answer |
106 | | - return $interpAnswer->setError( (string) $result['error'] ); |
107 | | - } |
108 | | - # if there were question/proposal errors, return them; |
109 | | - if ( $interpAnswer->isError() ) { |
110 | | - return $interpAnswer; |
111 | | - } |
112 | | - if ( !isset( $result['short'] ) || !isset( $result['long'] ) ) { |
113 | | - return $interpAnswer->setError( wfMsg( 'qp_error_interpretation_no_return' ) ); |
114 | | - } |
115 | | - $interpAnswer->short = (string) $result['short']; |
116 | | - $interpAnswer->long = (string) $result['long']; |
117 | | - return $interpAnswer; |
118 | | - } |
119 | | - |
120 | | -} /* end of qp_Interpret class */ |
Index: trunk/extensions/QPoll/qp_eval.php |
— | — | @@ -1,358 +0,0 @@ |
2 | | -<?php |
3 | | -/** |
4 | | - * ***** BEGIN LICENSE BLOCK ***** |
5 | | - * This file is part of QPoll. |
6 | | - * Uses parts of code from Quiz extension (c) 2007 Louis-Rémi BABE. All rights reserved. |
7 | | - * |
8 | | - * QPoll is free software; you can redistribute it and/or modify |
9 | | - * it under the terms of the GNU General Public License as published by |
10 | | - * the Free Software Foundation; either version 2 of the License, or |
11 | | - * (at your option) any later version. |
12 | | - * |
13 | | - * QPoll is distributed in the hope that it will be useful, |
14 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | | - * GNU General Public License for more details. |
17 | | - * |
18 | | - * You should have received a copy of the GNU General Public License |
19 | | - * along with QPoll; if not, write to the Free Software |
20 | | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 | | - * |
22 | | - * ***** END LICENSE BLOCK ***** |
23 | | - * |
24 | | - * QPoll is a poll tool for MediaWiki. |
25 | | - * |
26 | | - * To activate this extension : |
27 | | - * * Create a new directory named QPoll into the directory "extensions" of MediaWiki. |
28 | | - * * Place the files from the extension archive there. |
29 | | - * * Add this line at the end of your LocalSettings.php file : |
30 | | - * require_once "$IP/extensions/QPoll/qp_user.php"; |
31 | | - * |
32 | | - * @version 0.8.0a |
33 | | - * @link http://www.mediawiki.org/wiki/Extension:QPoll |
34 | | - * @author QuestPC <questpc@rambler.ru> |
35 | | - */ |
36 | | - |
37 | | -if ( !defined( 'MEDIAWIKI' ) ) { |
38 | | - die( "This file is part of the QPoll extension. It is not a valid entry point.\n" ); |
39 | | -} |
40 | | - |
41 | | -class qp_Eval { |
42 | | - |
43 | | - # the list of allowed PHP tokens |
44 | | - # filtered using the complete list at http://www.php.net/manual/ru/tokens.php |
45 | | - # is it bullet-proof enough? |
46 | | - static $allowedTokens = array( |
47 | | - T_AND_EQUAL, |
48 | | - T_ARRAY, |
49 | | - T_AS, |
50 | | - T_BOOLEAN_AND, |
51 | | - T_BOOLEAN_OR, |
52 | | - T_BOOL_CAST, |
53 | | - T_BREAK, |
54 | | - T_CASE, |
55 | | - T_COMMENT, |
56 | | - T_CONCAT_EQUAL, |
57 | | - T_CONSTANT_ENCAPSED_STRING, |
58 | | - T_CONTINUE, |
59 | | - T_DEC, |
60 | | - T_DEFAULT, |
61 | | - T_DIV_EQUAL, |
62 | | - T_DNUMBER, |
63 | | - T_DOC_COMMENT, |
64 | | - T_DOUBLE_ARROW, |
65 | | - T_DOUBLE_CAST, |
66 | | - T_ELSE, |
67 | | - T_ELSEIF, |
68 | | - T_EMPTY, |
69 | | - T_ENCAPSED_AND_WHITESPACE, |
70 | | - T_ENDFOREACH, |
71 | | - T_ENDIF, |
72 | | - T_ENDSWITCH, |
73 | | - T_END_HEREDOC, |
74 | | - T_FOREACH, |
75 | | - T_FUNCTION, |
76 | | - T_IF, |
77 | | - T_INC, |
78 | | - T_INT_CAST, |
79 | | - T_ISSET, |
80 | | - T_IS_EQUAL, |
81 | | - T_IS_GREATER_OR_EQUAL, |
82 | | - T_IS_IDENTICAL, |
83 | | - T_IS_NOT_EQUAL, |
84 | | - T_IS_NOT_IDENTICAL, |
85 | | - T_IS_SMALLER_OR_EQUAL, |
86 | | - T_LIST, |
87 | | - T_LNUMBER, |
88 | | - T_LOGICAL_AND, |
89 | | - T_LOGICAL_OR, |
90 | | - T_LOGICAL_XOR, |
91 | | - T_MINUS_EQUAL, |
92 | | - T_MOD_EQUAL, |
93 | | - T_MUL_EQUAL, |
94 | | - T_NUM_STRING, |
95 | | - T_OR_EQUAL, |
96 | | - T_PLUS_EQUAL, |
97 | | - T_RETURN, |
98 | | - T_SL, |
99 | | - T_SL_EQUAL, |
100 | | - T_SR, |
101 | | - T_SR_EQUAL, |
102 | | - T_START_HEREDOC, |
103 | | - T_STRING, |
104 | | - T_STRING_CAST, |
105 | | - T_SWITCH, |
106 | | - T_UNSET, |
107 | | - T_UNSET_CAST, |
108 | | - T_VARIABLE, |
109 | | - T_WHITESPACE, |
110 | | - T_XOR_EQUAL |
111 | | - ); |
112 | | - |
113 | | - # allowed functions |
114 | | - static $allowedCalls = array( |
115 | | - # math |
116 | | - 'round', 'trunc', 'ceil', 'floor', |
117 | | - # arrays |
118 | | - 'is_array', 'array_search', |
119 | | - # strings |
120 | | - 'preg_match', 'preg_split' |
121 | | - ); |
122 | | - |
123 | | - # disallowed superglobals |
124 | | - static $superGlobals = array( |
125 | | - '$GLOBALS', |
126 | | - '$_SERVER', |
127 | | - '$_GET', |
128 | | - '$_POST', |
129 | | - '$_FILES', |
130 | | - '$_REQUEST', |
131 | | - '$_SESSION', |
132 | | - '$_ENV', |
133 | | - '$_COOKIE', |
134 | | - '$php_errormsg', |
135 | | - '$HTTP_RAW_POST_DATA', |
136 | | - '$http_response_header', |
137 | | - '$argc', |
138 | | - '$argv' |
139 | | - ); |
140 | | - |
141 | | - # prefix added to local variable names which prevents |
142 | | - # from accessing local scope variables in eval'ed code |
143 | | - static $pseudoNamespace = 'qpv_'; |
144 | | - |
145 | | - # the list of disallowed code |
146 | | - # please add new entries, if needed. |
147 | | - # key 'badresult' means that formally the code is allowed, |
148 | | - # however the returned result has to be checked |
149 | | - # (eg. variable substitution is incorrect) |
150 | | - static $disallowedCode = array( |
151 | | - array( |
152 | | - 'code' => '$test = $_SERVER["REQUEST_URI"];', |
153 | | - 'desc' => 'Disallow reading from superglobals' |
154 | | - ), |
155 | | - array( |
156 | | - 'code' => '$GLOBALS["wgVersion"] = "test";', |
157 | | - 'desc' => 'Disallow writing to superglobals' |
158 | | - ), |
159 | | - array( |
160 | | - 'code' => 'global $wgVersion;', |
161 | | - 'desc' => 'Disallow visibility of globals in local scope' |
162 | | - ), |
163 | | - array( |
164 | | - 'code' => 'return isset( $selfCheck );', |
165 | | - 'badresult' => true, |
166 | | - 'desc' => 'Disallow access to extension\'s locals in the eval scope' |
167 | | - ), |
168 | | - array( |
169 | | - 'code' => '$writevar = 1; $var = "writevar"; $$var = "test";', |
170 | | - 'desc' => 'Disallow writing to variable variables' |
171 | | - ), |
172 | | - array( |
173 | | - 'code' => '$readvar = 1; $var = "readvar"; $test = $$var;', |
174 | | - 'desc' => 'Disallow reading from variable variables' |
175 | | - ), |
176 | | - array( |
177 | | - 'code' => '$readvar = 1; $var = "readvar"; $test = "my$$var 1";', |
178 | | - 'desc' => 'Disallow reading from complex variable variables' |
179 | | - ), |
180 | | - array( |
181 | | - 'code' => '$dh = opendir( "./" );', |
182 | | - 'desc' => 'Disallow illegal function calls' |
183 | | - ), |
184 | | - array( |
185 | | - 'code' => '$func = "opendir"; $dh=$func( "./" );', |
186 | | - 'desc' => 'Disallow variable function calls' |
187 | | - ), |
188 | | - array( |
189 | | - 'code' => 'return "test$selfCheck result";', |
190 | | - 'badresult' => 'test1 result', |
191 | | - 'desc' => 'Disallow extension\'s local scope variables in "simple" complex variables' |
192 | | - ), |
193 | | - array( |
194 | | - 'code' => '$curlydollar = "1"; $var = "test{$curlydollar}a";', |
195 | | - 'desc' => 'Disallow complex variables (curlydollar)' |
196 | | - ), |
197 | | - array( |
198 | | - 'code' => '$dollarcurly = "1"; $var = "test${dollarcurly}a";', |
199 | | - 'desc' => 'Disallow complex variables (dollarcurly)' |
200 | | - ), |
201 | | - array( |
202 | | - 'code' => '$obj = new stdClass; $obj = new stdClass(); $obj -> a = 1;', |
203 | | - 'desc' => 'Disallow creation of objects' |
204 | | - ), |
205 | | - array( |
206 | | - 'code' => '$obj -> a = 1;', |
207 | | - 'desc' => 'Disallow indirect creation of objects' |
208 | | - ), |
209 | | - array( |
210 | | - 'code' => '$obj = (object) array("a"=>1);', |
211 | | - 'desc' => 'Disallow cast to objects' |
212 | | - ), |
213 | | - array( |
214 | | - 'code' => 'for ( $i = 0; $i < 1; $i++ ) {};', |
215 | | - 'desc' => 'Disallow for loops, which easily can be made infinite' |
216 | | - ) |
217 | | - ); |
218 | | - |
219 | | - /** |
220 | | - * Check against the list of known disallowed code (for eval) |
221 | | - * should be executed before every eval, because PHP upgrade can introduce |
222 | | - * incompatibility leading to secure hole at any time |
223 | | - * @return |
224 | | - */ |
225 | | - static function selfCheck() { |
226 | | - # the following var is used to check access to extension's locals |
227 | | - # in the eval scope |
228 | | - $selfCheck = 1; |
229 | | - foreach ( self::$disallowedCode as $key => &$sourceCode ) { |
230 | | - # check source code sample |
231 | | - $destinationCode = ''; |
232 | | - $result = self::checkAndTransformCode( $sourceCode['code'], $destinationCode ); |
233 | | - if ( isset( $sourceCode['badresult'] ) ) { |
234 | | - # the code is meant to be vaild, however the result may be insecure |
235 | | - if ( $result !== true ) { |
236 | | - # there is an error in sample |
237 | | - return 'Sample error:' . $sourceCode['desc']; |
238 | | - } |
239 | | - # compare eval() result with "insecure" bad result |
240 | | - if ( eval( $destinationCode ) === $sourceCode['badresult'] ) { |
241 | | - return $sourceCode['desc']; |
242 | | - } |
243 | | - } else { |
244 | | - # the code meant to be invalid |
245 | | - if ( $result === true ) { |
246 | | - # illegal destination code which was passed as vaild |
247 | | - return $sourceCode['desc']; |
248 | | - } |
249 | | - } |
250 | | - } |
251 | | - return true; |
252 | | - } |
253 | | - |
254 | | - /** |
255 | | - * Checks the submitted eval code for errors |
256 | | - * In case of success returns transformed code, which is safer for eval |
257 | | - * @param $sourceCode submitted code which has to be eval'ed (no php tags) |
258 | | - * @param $destinationCode transformed code (in case of success) (no php tags) |
259 | | - * @return boolean true in case of success, string with error message on failure |
260 | | - */ |
261 | | - static function checkAndTransformCode( $sourceCode, &$destinationCode ) { |
262 | | - |
263 | | - # tokenizer requires php tags to parse propely, |
264 | | - # eval(), however requires not to have php tags - weird.. |
265 | | - $tokens = token_get_all( "<?php $sourceCode ?>" ); |
266 | | - /* remove <?php ?> */ |
267 | | - array_shift( $tokens ); |
268 | | - array_pop( $tokens ); |
269 | | - |
270 | | - $destinationCode = ''; |
271 | | - $prev_token = null; |
272 | | - foreach ( $tokens as $token ) { |
273 | | - if ( is_array( $token ) ) { |
274 | | - list( $token_id, $content, $line ) = $token; |
275 | | - # check against generic list of disallowed tokens |
276 | | - if ( !in_array( $token_id, self::$allowedTokens, true ) ) { |
277 | | - return wfMsg( 'qp_error_eval_illegal_token', token_name( $token_id ), QP_Setup::specialchars( $content ), $line ); |
278 | | - } |
279 | | - if ( $token_id == T_VARIABLE ) { |
280 | | - $prev_content = is_array( $prev_token ) ? $prev_token[1] : $prev_token; |
281 | | - preg_match( '`(\$)$`', $prev_content, $matches ); |
282 | | - # disallow variable variables |
283 | | - if ( count( $matches ) > 1 && $matches[1] == '$' ) { |
284 | | - return wfMsg( 'qp_error_eval_variable_variable_access', token_name( $token_id ), QP_Setup::specialchars( $content ), $line ); |
285 | | - } |
286 | | - # disallow superglobals |
287 | | - if ( in_array( $content, self::$superGlobals ) ) { |
288 | | - return wfMsg( 'qp_error_eval_illegal_superglobal', token_name( $token_id ), QP_Setup::specialchars( $content ), $line ); |
289 | | - } |
290 | | - # restrict variable names |
291 | | - preg_match( '`^(\$)([A-Za-z0-9_]*)$`', $content, $matches ); |
292 | | - if ( count( $matches ) != 3 ) { |
293 | | - return wfMsg( 'qp_error_eval_illegal_variable_name', token_name( $token_id ), QP_Setup::specialchars( $content ), $line ); |
294 | | - } |
295 | | - # correct variable names into pseudonamespace 'qpv_' |
296 | | - $content = "\$" . self::$pseudoNamespace . $matches[2]; |
297 | | - } |
298 | | - # do not count whitespace as previous token |
299 | | - if ( $token_id != T_WHITESPACE ) { |
300 | | - $prev_token = $token; |
301 | | - } |
302 | | - # concat corrected token to the destination |
303 | | - $destinationCode .= $content; |
304 | | - } else { |
305 | | - if ( $token == '(' && is_array( $prev_token ) ) { |
306 | | - list( $token_id, $content, $line ) = $prev_token; |
307 | | - # disallow variable function calls |
308 | | - if ( $token_id === T_VARIABLE ) { |
309 | | - return wfMsg( 'qp_error_eval_variable_function_call', token_name( $token_id ), QP_Setup::specialchars( $content ), $line ); |
310 | | - } |
311 | | - # disallow non-allowed function calls based on the list |
312 | | - if ( $token_id === T_STRING && array_search( $content, self::$allowedCalls ) === false ) { |
313 | | - return wfMsg( 'qp_error_eval_illegal_function_call', token_name( $token_id ), QP_Setup::specialchars( $content ), $line ); |
314 | | - } |
315 | | - } |
316 | | - $prev_token = $token; |
317 | | - # concat current token to the destination |
318 | | - $destinationCode .= $token; |
319 | | - } |
320 | | - } |
321 | | - |
322 | | - return true; |
323 | | - } |
324 | | - |
325 | | - /** |
326 | | - * Interpretates the answer with selected script |
327 | | - * @param $interpretScript string source code of interpretation script |
328 | | - * @param $answers array of user selected categories for every proposal & question of the poll |
329 | | - * @param $interpAnswer instance of qp_InterpAnswer class |
330 | | - * @modifies $interpAnswer |
331 | | - * @return array script result to check, or |
332 | | - * qpInterpAnswer $interpAnswer (in case of error) |
333 | | - */ |
334 | | - function interpretAnswer( $interpretScript, $answers, qp_InterpAnswer $interpAnswer ) { |
335 | | - # template page evaluation |
336 | | - if ( !function_exists( 'json_decode' ) ) { |
337 | | - # environment error |
338 | | - return $interpAnswer->setError( wfMsg( 'qp_error_no_json_decode' ) ); |
339 | | - } |
340 | | - if ( ( $check = self::selfCheck() ) !== true ) { |
341 | | - # self-check error |
342 | | - return $interpAnswer->setError( wfMsg( 'qp_error_eval_self_check', $check ) ); |
343 | | - } |
344 | | - $evalScript = ''; |
345 | | - if ( ( $check = self::checkAndTransformCode( $interpretScript, $evalScript ) ) !== true ) { |
346 | | - # possible malicious code |
347 | | - return $interpAnswer->setError( $check ); |
348 | | - } |
349 | | - # inject poll answer into the interpretation script |
350 | | - $evalScript = |
351 | | -"\$" . self::$pseudoNamespace . "a = json_decode( <<<HEREDOC |
352 | | -" . FormatJson::encode( $answers ) . " |
353 | | -HEREDOC |
354 | | -, true );\n" . $evalScript; |
355 | | - $result = eval( $evalScript ); |
356 | | - return $result; |
357 | | - } |
358 | | - |
359 | | -} |
Index: trunk/extensions/QPoll/qp_user.php |
— | — | @@ -28,7 +28,7 @@ |
29 | 29 | * * Add this line at the end of your LocalSettings.php file : |
30 | 30 | * require_once "$IP/extensions/QPoll/qp_user.php"; |
31 | 31 | * |
32 | | - * @version 0.8.0a |
| 32 | + * @version 0.7.0 |
33 | 33 | * @link http://www.mediawiki.org/wiki/Extension:QPoll |
34 | 34 | * @author QuestPC <questpc@rambler.ru> |
35 | 35 | */ |
— | — | @@ -37,11 +37,13 @@ |
38 | 38 | die( "This file is part of the QPoll extension. It is not a valid entry point.\n" ); |
39 | 39 | } |
40 | 40 | |
41 | | -# interpretation scripts namespace |
42 | | -define( 'NS_QP_INTERPRETATION', 800 ); |
43 | | -# talk namespace is always + 1 |
44 | | -define( 'NS_QP_INTERPRETATION_TALK', 801 ); |
| 41 | +define( 'QP_CSS_ERROR_COLOR2', "#D700D7" ); |
45 | 42 | |
| 43 | +define( 'QP_ERROR_MISSED_TITLE', 1 ); |
| 44 | +define( 'QP_ERROR_INVALID_ADDRESS', 2 ); |
| 45 | + |
| 46 | +define( 'QP_MAX_TEXT_ANSWER_LENGTH', 1024 ); |
| 47 | + |
46 | 48 | qp_Setup::init(); |
47 | 49 | |
48 | 50 | /** |
— | — | @@ -50,7 +52,7 @@ |
51 | 53 | $wgExtensionCredits['parserhook'][] = array( |
52 | 54 | 'path' => __FILE__, |
53 | 55 | 'name' => 'QPoll', |
54 | | - 'version' => '0.8.0a', |
| 56 | + 'version' => '0.7.0', |
55 | 57 | 'author' => 'QuestPC', |
56 | 58 | 'url' => 'http://www.mediawiki.org/wiki/Extension:QPoll', |
57 | 59 | 'descriptionmsg' => 'qp_desc', |
— | — | @@ -58,7 +60,7 @@ |
59 | 61 | $wgExtensionCredits['specialpage'][] = array( |
60 | 62 | 'path' => __FILE__, |
61 | 63 | 'name' => 'QPoll results page', |
62 | | - 'version' => '0.8.0a', |
| 64 | + 'version' => '0.7.0', |
63 | 65 | 'author' => 'QuestPC', |
64 | 66 | 'url' => 'http://www.mediawiki.org/wiki/Extension:QPoll', |
65 | 67 | 'descriptionmsg' => 'qp_desc-sp', |
— | — | @@ -78,82 +80,17 @@ |
79 | 81 | ); |
80 | 82 | } |
81 | 83 | |
82 | | -if ( !isset( $wgAutoloadClasses['FormatJson'] ) ) { |
83 | | - // for MediaWiki 1.15 |
84 | | - class FormatJson { |
85 | | - |
86 | | - /** |
87 | | - * Returns the JSON representation of a value. |
88 | | - * |
89 | | - * @param $value Mixed: the value being encoded. Can be any type except a resource. |
90 | | - * @param $isHtml Boolean |
91 | | - * |
92 | | - * @return string |
93 | | - */ |
94 | | - public static function encode( $value, $isHtml = false ) { |
95 | | - // Some versions of PHP have a broken json_encode, see PHP bug |
96 | | - // 46944. Test encoding an affected character (U+20000) to |
97 | | - // avoid this. |
98 | | - if ( !function_exists( 'json_encode' ) || $isHtml || strtolower( json_encode( "\xf0\xa0\x80\x80" ) ) != '\ud840\udc00' ) { |
99 | | - $json = new Services_JSON(); |
100 | | - return $json->encode( $value, $isHtml ); |
101 | | - } else { |
102 | | - return json_encode( $value ); |
103 | | - } |
104 | | - } |
105 | | - |
106 | | - /** |
107 | | - * Decodes a JSON string. |
108 | | - * |
109 | | - * @param $value String: the json string being decoded. |
110 | | - * @param $assoc Boolean: when true, returned objects will be converted into associative arrays. |
111 | | - * |
112 | | - * @return Mixed: the value encoded in json in appropriate PHP type. |
113 | | - * Values true, false and null (case-insensitive) are returned as true, false |
114 | | - * and &null; respectively. &null; is returned if the json cannot be |
115 | | - * decoded or if the encoded data is deeper than the recursion limit. |
116 | | - */ |
117 | | - public static function decode( $value, $assoc = false ) { |
118 | | - if ( !function_exists( 'json_decode' ) ) { |
119 | | - $json = new Services_JSON(); |
120 | | - $jsonDec = $json->decode( $value ); |
121 | | - if( $assoc ) { |
122 | | - $jsonDec = wfObjectToArray( $jsonDec ); |
123 | | - } |
124 | | - return $jsonDec; |
125 | | - } else { |
126 | | - return json_decode( $value, $assoc ); |
127 | | - } |
128 | | - } |
129 | | - |
130 | | - } /* end of FormatJson class */ |
131 | | -} |
132 | | - |
133 | 84 | /** |
134 | 85 | * Extension's global settings and initializiers |
135 | 86 | * should be purely static and preferrably have no constructor |
136 | 87 | */ |
137 | 88 | class qp_Setup { |
138 | 89 | |
139 | | - const ERROR_MISSED_TITLE = 1; |
140 | | - const ERROR_INVALID_ADDRESS = 2; |
141 | | - const MAX_TEXT_ANSWER_LENGTH = 1024; |
142 | | - |
143 | | - static $pollTag = 'qpoll'; |
144 | | - static $interpTag = 'qpinterpret'; |
145 | | - # parser $interpTag hook output market list |
146 | | - static $markerList = array(); |
147 | | - |
148 | 90 | static $ExtDir; // filesys path with windows path fix |
149 | 91 | static $ScriptPath; // apache virtual path |
150 | 92 | static $messagesLoaded = false; // check whether the extension's localized messages are loaded |
151 | 93 | static $article; // Article instance we got from hook parameter |
152 | 94 | static $user; // User instance we got from hook parameter |
153 | | - # extension's namespaces with their canonical names |
154 | | - static $namespaces = array( |
155 | | - NS_QP_INTERPRETATION => 'Interpretation', |
156 | | - NS_QP_INTERPRETATION_TALK => 'Interpretation_talk' |
157 | | - ); |
158 | 95 | |
159 | 96 | /** |
160 | 97 | * default configuration settings |
— | — | @@ -165,8 +102,6 @@ |
166 | 103 | public static $anon_forwarded_for = false; |
167 | 104 | # enable parser and article caches control for better performance (somewhat experimental, may break compatibility; checked with MW v1.15, v1.16) |
168 | 105 | public static $cache_control = false; |
169 | | - # number of submit attempts allowed (0 or less for infinite number) |
170 | | - public static $max_submit_attempts = 0; |
171 | 106 | /* end of default configuration settings */ |
172 | 107 | |
173 | 108 | static function entities( $s ) { |
— | — | @@ -206,137 +141,35 @@ |
207 | 142 | } |
208 | 143 | |
209 | 144 | /** |
210 | | - * Autoload classes from the map provided |
211 | | - */ |
212 | | - static function autoLoad( $map ) { |
213 | | - global $wgAutoloadClasses; |
214 | | - foreach ( $map as $path => &$classes ) { |
215 | | - if ( is_array( $classes ) ) { |
216 | | - foreach ( $classes as &$className ) { |
217 | | - $wgAutoloadClasses[$className] = self::$ExtDir . '/' . $path; |
218 | | - } |
219 | | - } else { |
220 | | - $wgAutoloadClasses[$classes] = self::$ExtDir . '/' . $path; |
221 | | - } |
222 | | - } |
223 | | - } |
224 | | - |
225 | | - /** |
226 | 145 | * Add this extension to the mediawiki's extensions list. |
227 | 146 | */ |
228 | 147 | static function init() { |
229 | 148 | global $wgScriptPath; |
230 | | - global $wgExtensionMessagesFiles, $wgExtensionAliasesFiles; |
| 149 | + global $wgAutoloadClasses; |
| 150 | + global $wgExtensionMessagesFiles; |
231 | 151 | global $wgSpecialPages; |
232 | 152 | global $wgHooks; |
233 | | - global $wgExtraNamespaces, $wgNamespaceProtection; |
234 | | - global $wgGroupPermissions; |
235 | | - |
236 | | - # core check and local / remote path |
237 | 153 | self::coreRequirements(); |
238 | 154 | self::$ExtDir = str_replace( "\\", "/", dirname(__FILE__) ); |
239 | 155 | $dirs = explode( '/', self::$ExtDir ); |
240 | 156 | $top_dir = array_pop( $dirs ); |
241 | 157 | self::$ScriptPath = $wgScriptPath . '/extensions' . ( ( $top_dir == 'extensions' ) ? '' : '/' . $top_dir ); |
242 | | - |
243 | | - # language files |
244 | | - # extension messages |
245 | | - $wgExtensionMessagesFiles['QPoll'] = self::$ExtDir . '/i18n/qp.i18n.php'; |
246 | | - # localized namespace names |
247 | | - $wgExtensionMessagesFiles['QPollNamespaces'] = self::$ExtDir . '/i18n/qp.namespaces.php'; |
248 | | - # localized special page titles |
249 | | - $wgExtensionAliasesFiles['QPoll'] = self::$ExtDir . '/i18n/qp.alias.php'; |
250 | | - |
251 | | - # extension setup, hooks handling and content transformation |
252 | | - self::autoLoad( array( |
253 | | - 'qp_user.php' => array( 'FormatJson', 'qp_Setup', 'qp_Renderer', 'qp_FunctionsHook' ), |
254 | | - |
255 | | - ## controllers (polls and questions derived from separate abstract classes) |
256 | | - # polls |
257 | | - 'ctrl/qp_abstractpoll.php' => 'qp_AbstractPoll', |
258 | | - 'ctrl/qp_poll.php' => 'qp_Poll', |
259 | | - 'ctrl/qp_pollstats.php' => 'qp_PollStats', |
260 | | - # questions |
261 | | - 'ctrl/qp_abstractquestion.php' => 'qp_AbstractQuestion', |
262 | | - 'ctrl/qp_question.php' => 'qp_Question', |
263 | | - 'ctrl/qp_questionstats.php' => 'qp_QuestionStats', |
264 | | - |
265 | | - ## views are derived from single generic class |
266 | | - ## isCompatibleController() method is used to check linked controllers (bugcheck) |
267 | | - # generic |
268 | | - 'view/qp_abstractview.php' => 'qp_AbstractView', |
269 | | - # questions |
270 | | - 'view/qp_questionview.php' => 'qp_QuestionView', |
271 | | - 'view/qp_questionstatsview.php' => 'qp_QuestionStatsView', |
272 | | - # polls |
273 | | - 'view/qp_pollview.php' => 'qp_PollView', |
274 | | - 'view/qp_pollstatsview.php' => 'qp_PollStatsView', |
275 | | - |
276 | | - # storage |
277 | | - 'qp_pollstore.php' => array( 'qp_QuestionData', 'qp_InterpAnswer', 'qp_PollStore' ), |
278 | | - |
279 | | - # results page |
280 | | - 'qp_results.php' => array( 'qp_QueryPage', 'PollResults' ), |
281 | | - |
282 | | - # interpretation of answers |
283 | | - 'qp_interpret.php' => 'qp_Interpret', |
284 | | - 'qp_eval.php' => 'qp_Eval' |
285 | | - ) ); |
286 | | - |
287 | | - # TODO: Use the new technique for i18n of special page aliases |
| 158 | + $wgExtensionMessagesFiles['QPoll'] = self::$ExtDir . '/qp_i18n.php'; |
| 159 | + $wgAutoloadClasses['PollResults'] = self::$ExtDir . '/qp_results.php'; |
| 160 | + $wgAutoloadClasses['qp_Question'] = |
| 161 | + $wgAutoloadClasses['qp_QuestionStats'] = self::$ExtDir . '/qp_question.php'; |
| 162 | + $wgAutoloadClasses['qp_PollStore'] = |
| 163 | + $wgAutoloadClasses['qp_QuestionData'] = self::$ExtDir . '/qp_pollstore.php'; |
| 164 | + $wgAutoloadClasses['qp_QueryPage'] = self::$ExtDir . '/qp_results.php'; |
| 165 | + // TODO: Use the new technique for i18n of special page aliases |
288 | 166 | $wgSpecialPages['PollResults'] = 'PollResults'; |
289 | | - # TODO: Use the new technique for i18n of magic words |
290 | | - # instantiating fake instance for PHP < 5.2.3, which does not support 'Class::method' type of callbacks |
| 167 | + // TODO: Use the new technique for i18n of magic words |
| 168 | + // instantiating fake instance for PHP < 5.2.3, which does not support 'Class::method' type of callbacks |
291 | 169 | $wgHooks['LanguageGetMagic'][] = |
292 | 170 | $wgHooks['MediaWikiPerformAction'][] = |
293 | | - $wgHooks['ParserFirstCallInit'][] = |
294 | | - $wgHooks['LoadAllMessages'][] = |
295 | | - $wgHooks['ParserAfterTidy'][] = |
296 | | - $wgHooks['CanonicalNamespaces'][] = |
297 | | - new qp_Setup; |
298 | | - |
299 | | - # define namespaces for the interpretation scripts and their talk pages |
300 | | - foreach ( self::$namespaces as $ns_idx => $canonical_name ) { |
301 | | - if ( isset( $wgExtraNamespaces[$ns_idx] ) ) { |
302 | | - die( "QPoll requires namespace index {$ns_idx} which is already used by another extension. Either disable another extension or change the namespace index." ); |
303 | | - } |
304 | | - $wgNamespaceProtection[$ns_idx] = array( 'editinterpretation' ); |
305 | | - } |
306 | | - if ( self::mediaWikiVersionCompare( '1.17' ) ) { |
307 | | - foreach ( self::$namespaces as $ns_idx => $canonical_name ) { |
308 | | - $wgExtraNamespaces[$ns_idx] = $canonical_name; |
309 | | - } |
310 | | - } |
311 | | - |
312 | | - # groups which has permission to access poll results by default |
313 | | - $wgGroupPermissions['sysop']['showresults'] = true; |
314 | | - $wgGroupPermissions['bureaucrat']['showresults'] = true; |
315 | | - $wgGroupPermissions['polladmin']['showresults'] = true; |
316 | | - # groups which can edit interpretation scripts by default |
317 | | - # please minimize the number of groups as low as you can |
318 | | - # that is security measure against inserting of malicious code |
319 | | - # into the source of interpretation scripts |
320 | | - $wgGroupPermissions['sysop']['editinterpretation'] = true; |
321 | | - $wgGroupPermissions['bureaucrat']['editinterpretation'] = true; |
| 171 | + $wgHooks['ParserFirstCallInit'][] = new qp_Setup; |
322 | 172 | } |
323 | 173 | |
324 | | - static function mediaWikiVersionCompare( $version, $operator = '<' ) { |
325 | | - global $wgVersion; |
326 | | - return version_compare( $wgVersion, $version, $operator ); |
327 | | - } |
328 | | - |
329 | | - static function onLoadAllMessages() { |
330 | | - if ( !self::$messagesLoaded ) { |
331 | | - self::$messagesLoaded = true; |
332 | | - # for MW 1.15 which is still being used by many customers |
333 | | - # please do not remove until 2012 |
334 | | - if ( self::mediaWikiVersionCompare( '1.16' ) ) { |
335 | | - wfLoadExtensionMessages( 'QPoll' ); |
336 | | - } |
337 | | - } |
338 | | - return true; |
339 | | - } |
340 | | - |
341 | 174 | static function ParserFunctionsWords( $lang ) { |
342 | 175 | $words = array(); |
343 | 176 | $words[ 'en' ] = array( 'qpuserchoice'=>array( 0, 'qpuserchoice' ) ); |
— | — | @@ -430,8 +263,7 @@ |
431 | 264 | } |
432 | 265 | global $wgQPollFunctionsHook; |
433 | 266 | # setup tag hook |
434 | | - $parser->setHook( self::$pollTag, array( 'qp_Setup', 'showPoll' ) ); |
435 | | - $parser->setHook( self::$interpTag, array( 'qp_Setup', 'showScript' ) ); |
| 267 | + $parser->setHook( 'qpoll', array( 'qp_Setup', 'renderPoll' ) ); |
436 | 268 | $wgQPollFunctionsHook = new qp_FunctionsHook(); |
437 | 269 | # setup function hook |
438 | 270 | $parser->setFunctionHook( 'qpuserchoice', array( &$wgQPollFunctionsHook, 'qpuserchoice' ), SFH_OBJECT_ARGS ); |
— | — | @@ -443,92 +275,789 @@ |
444 | 276 | * |
445 | 277 | * @param $input Text between <qpoll> and </qpoll> tags, in QPoll syntax. |
446 | 278 | * @param $argv An array containing any arguments passed to the extension |
447 | | - * @param &$parser The wikitext parser. |
| 279 | + * @param &$parser The wikitext parser. |
448 | 280 | * @param &$frame PPFrame object passed in MW 1.16+ |
449 | 281 | * @return An HTML poll. |
450 | 282 | */ |
451 | 283 | |
452 | 284 | /* @param $input Text between <qpoll> and </qpoll> tags, in QPoll syntax. */ |
453 | | - static function showPoll( $input, $argv, $parser, $frame = false ) { |
| 285 | + static function renderPoll( $input, $argv, $parser, $frame = false ) { |
454 | 286 | if ( !self::$cache_control ) { |
455 | 287 | $parser->disableCache(); |
456 | 288 | } |
457 | 289 | if ( array_key_exists( 'address', $argv ) ) { |
458 | | - $qpoll = new qp_PollStats( |
459 | | - $argv, |
460 | | - new qp_PollStatsView( $parser, $frame ) |
461 | | - ); |
| 290 | + $qpoll = new qp_PollStats( $argv, $parser, $frame ); |
462 | 291 | } else { |
463 | | - $qpoll = new qp_Poll( |
464 | | - $argv, |
465 | | - new qp_PollView( $parser, $frame ) |
466 | | - ); |
| 292 | + $qpoll = new qp_Poll( $argv, $parser, $frame ); |
467 | 293 | } |
468 | 294 | return $qpoll->parsePoll( $input ); |
469 | 295 | } |
470 | 296 | |
471 | | - /** |
472 | | - * Show interpetation script source with line numbering (for debugging convenience) |
| 297 | +} |
| 298 | + |
| 299 | +/*** |
| 300 | + * a poll stub which cannot process and render itself |
| 301 | + * to process and render itself, real Poll should extend this class to implement it's own: |
| 302 | + $this->getPollStore() |
| 303 | + $this->parseInput() |
| 304 | + $this->generateOutput() |
| 305 | + ***/ |
| 306 | +class qp_AbstractPoll { |
| 307 | + |
| 308 | + static $skin; |
| 309 | + static $sOrderId = 0; // order of polls on the page (used for sorting of the output) |
| 310 | + static $sPrevPollIDs = Array(); // used to check uniqueness of PollId on the page |
| 311 | + |
| 312 | + var $parser; // parser for parsing tags content |
| 313 | + var $ppframe; // parser context passed in MW 1.16+; unused in MW 1.15 |
| 314 | + var $username; |
| 315 | + |
| 316 | + # an ID of the poll on current page (used in declaration/voting mode) |
| 317 | + var $mPollId = null; |
| 318 | + var $mOrderId = null; // order_id in DB that will used to sort out polls on the Special:PollResults statistics page |
| 319 | + # poll address of the poll to display statistics (used in statistical mode) |
| 320 | + var $pollAddr = null; |
| 321 | + var $mQuestionId = null; // the unique index number of the question in the current poll (used to instantiate the questions) |
| 322 | + |
| 323 | + var $mState = ''; // current state of poll parsing (no error) |
| 324 | + var $dependsOn = ''; // optional address of the poll which must be answered first |
| 325 | + var $mBeingCorrected = false; // true, when the poll is posted (answered) |
| 326 | + |
| 327 | + # the following showresults types are currently available: |
| 328 | + # 0 - none; 1 - percents; 2 - bars |
| 329 | + # may contain extra options (color, width) for selected display type |
| 330 | + var $showResults = Array( 'type'=>0 ); // hide showResults by default |
| 331 | + |
| 332 | + // qp_pollStore instance that will be used to transfer poll data from/to DB |
| 333 | + var $pollStore = null; |
| 334 | + |
| 335 | + /** |
| 336 | + * Constructor |
473 | 337 | * |
474 | | - * @param $input Text between <qpinterpret> and </qpinterper> tags, subset of PHP syntax. |
475 | | - * @param $argv An array containing any arguments passed to the extension |
476 | | - * @param &$parser The wikitext parser. |
477 | | - * @param &$frame PPFrame object passed in MW 1.16+ |
478 | | - * @return script source with line numbering |
| 338 | + * @public |
479 | 339 | */ |
480 | | - static function showScript( $input, $argv, $parser, $frame = false ) { |
481 | | - $lines_count = count( preg_split( '`(\r\n|\n|\r)`', $input, -1 ) ); |
482 | | - $line_numbers = ''; |
483 | | - for ( $i = 1; $i <= $lines_count; $i++ ) { |
484 | | - $line_numbers .= "{$i}\n"; |
| 340 | + function __construct( $argv, &$parser, &$frame ) { |
| 341 | + global $wgUser, $wgRequest, $wgLanguageCode; |
| 342 | + $this->parser = &$parser; |
| 343 | + $this->ppframe = $frame; |
| 344 | + $this->mRequest = &$wgRequest; |
| 345 | + $this->mResponse = $wgRequest->response(); |
| 346 | + # load current skin |
| 347 | + if ( self::$skin === null ) { |
| 348 | + self::$skin = $wgUser->getSkin(); |
485 | 349 | } |
486 | | - $out = |
487 | | - array( '__tag'=>'div', 'class'=>'qpoll', |
488 | | - array( '__tag'=>'div', 'class'=>'line_numbers', $line_numbers ), |
489 | | - array( '__tag'=>'div', 'class'=>'script_view', qp_Setup::specialchars( $input ) . "\n" ) |
490 | | - ); |
| 350 | + # reset the unique index number of the question in the current poll (used to instantiate the questions) |
| 351 | + $this->mQuestionId = 0; // ( correspons to 'question_id' DB field ) |
| 352 | + $this->username = self::currentUserName(); |
491 | 353 | |
492 | | - $markercount = count( self::$markerList ); |
493 | | - $marker = "!qpoll-script-view{$markercount}-qpoll!"; |
494 | | - self::$markerList[$markercount] = qp_Renderer::renderHTMLobject( $out ); |
495 | | - return $marker; |
| 354 | + # *** get visual style poll attributes *** |
| 355 | + $this->perRow = intval( array_key_exists( 'perrow', $argv ) ? $argv['perrow'] : 1 ); |
| 356 | + if ( $this->perRow < 1 ) |
| 357 | + $this->perRow = 1; |
| 358 | + $this->currCol = $this->perRow; |
| 359 | + if ( array_key_exists( 'showresults', $argv ) && qp_Setup::$global_showresults != 0 ) { |
| 360 | + if ( $argv['showresults'] == 'showresults' ) { |
| 361 | + # default showresults for the empty value of xml attribute |
| 362 | + $argv['showresults'] = '1'; |
| 363 | + } |
| 364 | + $this->showResults = self::parse_showResults( $argv['showresults'] ); |
| 365 | + } |
| 366 | + # every poll on the page should have unique poll id, to minimize the risk of collisions |
| 367 | + # it is required to be set manually via id="value" parameter |
| 368 | + # ( used only in "declaration" mode ) |
| 369 | + $this->mPollId = array_key_exists('id', $argv) ? trim( $argv['id'] ) : null; |
| 370 | + if ( array_key_exists('dependance', $argv) ) { |
| 371 | + $this->dependsOn = trim( $argv['dependance'] ); |
| 372 | + } |
496 | 373 | } |
497 | 374 | |
498 | 375 | /** |
499 | | - * replace previousely set markers with actual rendered html of source text |
500 | | - * which has line numbers for easier way to spot possible eval check errors |
501 | | - * otherwise, this html code will be ruined when passed directly to parser |
| 376 | + * Convert the input text to an HTML output. |
| 377 | + * |
| 378 | + * @param $input Text between <qpoll> and </qpoll> tags, in QPoll syntax. |
502 | 379 | */ |
503 | | - static function onParserAfterTidy( $parser, &$text ) { |
504 | | - # find markers in $text |
505 | | - # replace markers with actual output |
506 | | - $keys = array(); |
507 | | - $marker_count = count( self::$markerList ); |
| 380 | + function parsePoll( $input ) { |
| 381 | + if ( ($result = $this->getPollStore() ) !== true ) { |
| 382 | + # error message box (invalid poll attributes) |
| 383 | + return $result; |
| 384 | + } |
| 385 | + if ( ($result = $this->parseInput( $input ) ) === true ) { |
| 386 | + # no output generation - due to active redirect or access denied |
| 387 | + return ''; |
| 388 | + } else { |
| 389 | + # generateOutput() assumes that the poll is not being submitted and is correctly declared |
| 390 | + return $this->generateOutput( $result ); |
| 391 | + } |
| 392 | + } |
508 | 393 | |
509 | | - for ( $i = 0; $i < $marker_count; $i++ ) { |
510 | | - $keys[] = "!qpoll-script-view{$i}-qpoll!"; |
| 394 | + static function fatalError() { |
| 395 | + $args = func_get_args(); |
| 396 | + $result = 'Extension bug: ' . __METHOD__ . ' called without arguments'; |
| 397 | + if ( count( $args > 0 ) ) { |
| 398 | + $result = call_user_func_array( 'wfMsgHTML', $args ); |
511 | 399 | } |
| 400 | + return '<div class="qpoll"><div class="fatalerror">' . $result . '</div></div>'; |
| 401 | + } |
512 | 402 | |
513 | | - $text = str_replace( $keys, self::$markerList, $text ); |
| 403 | + # title fragment part (GET/POST) |
| 404 | + static function getPollTitleFragment( $pollid, $dash = '#' ) { |
| 405 | + return $dash . 'qp_' . Title::escapeFragmentForURL( $pollid ); |
| 406 | + } |
| 407 | + |
| 408 | + static function addPollId ( $pollId ) { |
| 409 | + self::$sPrevPollIDs[] = $pollId; |
| 410 | + } |
| 411 | + |
| 412 | + function isValidPollId( $pollId ) { |
| 413 | + // more non-allowed chars ? |
| 414 | + return !preg_match('`#`u', $pollId ); |
| 415 | + } |
| 416 | + |
| 417 | + function isUniquePollId( $pollId ) { |
| 418 | + return !in_array( $pollId, self::$sPrevPollIDs ); |
| 419 | + } |
| 420 | + |
| 421 | + static function currentUserName() { |
| 422 | + global $wgUser, $wgSquidServers; |
| 423 | + global $wgUsePrivateIPs; |
| 424 | + if ( qp_Setup::$anon_forwarded_for === true && $wgUser->isAnon() ) { |
| 425 | + /* collect the originating IPs |
| 426 | + borrowed from ProxyTools::wfGetIP |
| 427 | + bypass trusted proxies list check */ |
| 428 | + # Client connecting to this webserver |
| 429 | + if ( isset( $_SERVER['REMOTE_ADDR'] ) ) { |
| 430 | + $ipchain = array( IP::canonicalize( $_SERVER['REMOTE_ADDR'] ) ); |
| 431 | + } else { |
| 432 | + # Running on CLI? |
| 433 | + $ipchain = array( '127.0.0.1' ); |
| 434 | + } |
| 435 | + $ip = $ipchain[0]; |
| 436 | + |
| 437 | + # Append XFF on to $ipchain |
| 438 | + $forwardedFor = wfGetForwardedFor(); |
| 439 | + if ( isset( $forwardedFor ) ) { |
| 440 | + $xff = array_map( 'trim', explode( ',', $forwardedFor ) ); |
| 441 | + $xff = array_reverse( $xff ); |
| 442 | + $ipchain = array_merge( $ipchain, $xff ); |
| 443 | + } |
| 444 | + $username = ""; |
| 445 | + foreach ( $ipchain as $i => $curIP ) { |
| 446 | + if( $wgUsePrivateIPs || IP::isPublic( $curIP ) ) { |
| 447 | + $username .= IP::canonicalize( $curIP ) . '/'; |
| 448 | + } |
| 449 | + } |
| 450 | + if ( $username != "" ) { |
| 451 | + # remove trailing slash |
| 452 | + $username = substr( $username, 0, strlen( $username ) - 1 ); |
| 453 | + } else { |
| 454 | + $username .= IP::canonicalize( $ipchain[0] ); |
| 455 | + } |
| 456 | + } else { |
| 457 | + $username = $wgUser->getName(); |
| 458 | + } |
| 459 | + return $username; |
| 460 | + } |
| 461 | + |
| 462 | + // @input $addr - source poll address (possibly the short one) in the string or array form |
| 463 | + // @return array[0] - title where the poll is located |
| 464 | + // array[1] - pollId string |
| 465 | + // array[2] - prefixed (complete) poll address |
| 466 | + // false - invalid source poll address was given |
| 467 | + static function getPrefixedPollAddress( $addr ) { |
| 468 | + global $wgTitle; |
| 469 | + if ( is_array( $addr ) ) { |
| 470 | + if ( count( $addr ) > 1 ) { |
| 471 | + list( $titlePart, $pollIdPart ) = $addr; |
| 472 | + } else { |
| 473 | + return false; |
| 474 | + } |
| 475 | + } else { |
| 476 | + preg_match( '`^(.*?)#(.*?)$`u', $addr, $matches ); |
| 477 | + if ( count( $matches ) == 3 ) { |
| 478 | + $titlePart = trim( $matches[1] ); |
| 479 | + $pollIdPart = trim( $matches[2] ); |
| 480 | + } else { |
| 481 | + return false; |
| 482 | + } |
| 483 | + } |
| 484 | + if ( $pollIdPart == '' ) { |
| 485 | + return false; |
| 486 | + } |
| 487 | + if ( $titlePart == '' ) { |
| 488 | + # poll is located at the current page |
| 489 | + $titlePart = $wgTitle->getPrefixedText(); |
| 490 | + } |
| 491 | + return array( $titlePart, $pollIdPart, $titlePart . '#' . $pollIdPart ); |
| 492 | + } |
| 493 | + |
| 494 | + // parses source showresults xml parameter value and returns the corresponding showResults array |
| 495 | + // input: $str contains entries separated by ';' |
| 496 | + // entry 1 is a number of showresults type (always presented) |
| 497 | + // entries 2..n are optional css-style list of attributes and their values |
| 498 | + // returns showResults parsed array |
| 499 | + // 'type' indicates the type, optional keys contain values of css-style attributes |
| 500 | + static function parse_showResults( $str ) { |
| 501 | + $showResults['type'] = 0; |
| 502 | + $attrs = array_map( 'trim', explode( ';', $str ) ); |
| 503 | + if ( count( $attrs ) > 0 ) { |
| 504 | + $showResults['type'] = intval( array_shift( $attrs ) ); |
| 505 | + if ( $showResults['type'] < 0 ) { |
| 506 | + $showResults['type'] = 0; |
| 507 | + } |
| 508 | + if ( $showResults['type'] != 0 && count( $attrs ) > 0 ) { |
| 509 | + foreach( $attrs as &$attr ) { |
| 510 | + preg_match( '`([A-Za-z]+):([#\w]+)`u', $attr, $matches ); |
| 511 | + if ( count( $matches ) == 3 ) { |
| 512 | + $showResults[ $matches[1] ] = $matches[2]; |
| 513 | + } |
| 514 | + } |
| 515 | + } |
| 516 | + } |
| 517 | + return $showResults; |
| 518 | + } |
| 519 | + |
| 520 | +} |
| 521 | + |
| 522 | +/** |
| 523 | + * Processes poll markup in statistical mode (only to show the results) |
| 524 | + */ |
| 525 | +class qp_PollStats extends qp_AbstractPoll { |
| 526 | + |
| 527 | + function __construct( $argv, &$parser, &$frame ) { |
| 528 | + parent::__construct( $argv, $parser, $frame ); |
| 529 | + $this->pollAddr = trim( $argv['address'] ); |
| 530 | + # statistical mode is active, but qp_Setup::$global_showresults still can be false |
| 531 | + if ( qp_Setup::$global_showresults == 0 ) { |
| 532 | + $this->showResults = false; |
| 533 | + } |
| 534 | + } |
| 535 | + |
| 536 | + # prepare qp_PollStore object |
| 537 | + # @return true on success ($this->pollStore has been created successfully), error string on failure |
| 538 | + function getPollStore() { |
| 539 | + if ( $this->mPollId !== null ) { |
| 540 | + $this->mState = "error"; |
| 541 | + return self::fatalError( 'qp_error_id_in_stats_mode' ); |
| 542 | + } |
| 543 | + if ( $this->dependsOn !== '' ) { |
| 544 | + $this->mState = "error"; |
| 545 | + return self::fatalError( 'qp_error_dependance_in_stats_mode' ); |
| 546 | + } |
| 547 | + $this->pollStore = qp_PollStore::newFromAddr( $this->pollAddr ); |
| 548 | + if ( !($this->pollStore instanceof qp_PollStore) || $this->pollStore->pid === null ) { |
| 549 | + return self::fatalError( 'qp_error_no_such_poll', $this->pollAddr ); |
| 550 | + } |
| 551 | + if ( !$this->pollStore->loadQuestions() ) { |
| 552 | + $this->mState = "error"; |
| 553 | + return self::fatalError( 'qp_error_no_stats', $this->pollAddr ); |
| 554 | + } |
| 555 | + $this->pollStore->setLastUser( $this->username, false ); |
| 556 | + # do not check the result, because we may show results even if the user hasn't voted |
| 557 | + $this->pollStore->loadUserAlreadyVoted(); |
514 | 558 | return true; |
515 | 559 | } |
516 | 560 | |
517 | | - public static function onCanonicalNamespaces( &$list ) { |
518 | | - # do not use array_merge() as it will destroy negative indexes in $list |
519 | | - # thus completely ruining the namespaces list |
520 | | - foreach ( self::$namespaces as $ns_idx => $canonical_name ) { |
521 | | - $list[$ns_idx] = $canonical_name; |
| 561 | + # Replace questions from QPoll syntax to HTML |
| 562 | + # @param $input - A question in QPoll statistical mode syntax |
| 563 | + # @return string representing rendered set of the questions / boolean true - stop further processing |
| 564 | + function parseInput( $input ) { |
| 565 | + $write_row = Array(); |
| 566 | + $write_col = Array(); |
| 567 | + $questions = Array(); |
| 568 | + # question attributes split pattern |
| 569 | + $splitPattern = '`\s*{|}\s*\n*`u'; |
| 570 | + # preg_split counts the matches starting from zero |
| 571 | + $unparsedAttributes = preg_split( $splitPattern, $input, -1, PREG_SPLIT_NO_EMPTY ); |
| 572 | + # we count questions starting from 1 |
| 573 | + array_unshift( $unparsedAttributes, null ); |
| 574 | + unset( $unparsedAttributes[0] ); |
| 575 | + # first pass: parse the headers |
| 576 | + foreach ( $this->pollStore->Questions as &$qdata ) { |
| 577 | + $question = new qp_QuestionStats( $this->parser, $this->ppframe, $qdata->type, $qdata->question_id, $this->showResults ); |
| 578 | + if ( isset( $unparsedAttributes[$qdata->question_id] ) ) { |
| 579 | + $attr_str = $unparsedAttributes[$qdata->question_id]; |
| 580 | + } else { |
| 581 | + $attr_str = ''; |
| 582 | + } |
| 583 | + if ( ($type = $question->parseAttributes( $attr_str )) != '' ) { |
| 584 | + # there cannot be type attribute of question in statistical display mode |
| 585 | + $question->setState( 'error', wfMsg( 'qp_error_type_in_stats_mode', $type ) ); |
| 586 | + } |
| 587 | + $questions[] = $question; |
522 | 588 | } |
| 589 | + # analyze question headers |
| 590 | + # check for showresults attribute |
| 591 | + $questions_set = Array(); |
| 592 | + foreach ( $questions as &$question ) { |
| 593 | + if ( $question->showResults['type'] != 0 && |
| 594 | + method_exists( 'qp_Question', 'addShowResults' . $question->showResults['type'] ) ) { |
| 595 | + $questions_set[] = $question->mQuestionId; |
| 596 | + } |
| 597 | + } |
| 598 | + # load the statistics for all/selective/none of questions |
| 599 | + if ( count( $questions_set ) > 0 ) { |
| 600 | + if ( count( $questions_set ) == count( $questions ) ) { |
| 601 | + $this->pollStore->loadTotals(); |
| 602 | + } else { |
| 603 | + $this->pollStore->loadTotals( $questions_set ); |
| 604 | + } |
| 605 | + $this->pollStore->calculateStatistics(); |
| 606 | + } |
| 607 | + # second pass: parse the statistics |
| 608 | + foreach ( $questions as &$question ) { |
| 609 | + # render the question statistics only when showResuls isn't 0 (suppress stats) |
| 610 | + if ( $question->showResults['type'] != 0 ) { |
| 611 | + if ( $this->perRow > 1 ) { |
| 612 | + $write_col[] = array( '__tag'=>'td', 'valign'=>'top', 0=>$this->parseStats( $question ), '__end'=>"\n" ); |
| 613 | + if ( $this->currCol == 1 ) { |
| 614 | + $write_row[] = array( '__tag'=>'tr', 0=>$write_col, '__end'=>"\n" ); |
| 615 | + $write_col = Array(); |
| 616 | + } |
| 617 | + if ( --$this->currCol < 1 ) { |
| 618 | + $this->currCol = $this->perRow; |
| 619 | + } |
| 620 | + } else { |
| 621 | + $write_row[] = $this->parseStats( $question ); |
| 622 | + } |
| 623 | + } |
| 624 | + # question object is not needed anymore |
| 625 | + unset( $question ); |
| 626 | + } |
| 627 | + if ( $this->perRow > 1 && $this->currCol != $this->perRow ) { |
| 628 | + # add last incomplete row |
| 629 | + $write_row[] = array( '__tag'=>'tr', '__end'=>"\n", 0=>$write_col ); |
| 630 | + } |
| 631 | + if ( $this->perRow > 1 ) { |
| 632 | + $question_table = array( '__tag'=>'table', 0=>array( '__tag'=>'tbody', 0=>&$write_row, '__end'=>"\n" ), '__end'=>"\n" ); |
| 633 | + return qp_Renderer::renderHTMLobject( $question_table ); |
| 634 | + } else { |
| 635 | + return qp_Renderer::renderHTMLobject( $write_row ); |
| 636 | + } |
| 637 | + } |
| 638 | + |
| 639 | + # encloses the output of $this->parseQuestions() into the output tag wrappers |
| 640 | + # @param $input - the output of $this->parseQuestions() |
| 641 | + # @return rendered "final" html |
| 642 | + function generateOutput( $input ) { |
| 643 | + global $wgOut; |
| 644 | + # Generates the output. |
| 645 | + $qpoll_div = array( '__tag'=>'div', 'class'=>'qpoll', 0=>$input ); |
| 646 | + return qp_Renderer::renderHTMLobject( $qpoll_div ); |
| 647 | + } |
| 648 | + |
| 649 | + # populate the question with data and build it's HTML representation |
| 650 | + # returns HTML representation of the question |
| 651 | + function parseStats( qp_QuestionStats &$question ) { |
| 652 | + # parse the question body |
| 653 | + $buffer = ''; |
| 654 | + if ( $question->getQuestionAnswer( $this->pollStore ) ) { |
| 655 | + # check whether the current global showresults level allows to display statistics |
| 656 | + if ( qp_Setup::$global_showresults == 0 || |
| 657 | + (qp_Setup::$global_showresults <= 1 && !$question->alreadyVoted) ) { |
| 658 | + # suppress the output |
| 659 | + return ''; |
| 660 | + } |
| 661 | + $buffer = $question->renderStats(); |
| 662 | + } |
| 663 | + $output_table = array( '__tag'=>'table', '__end'=>"\n", 'class'=>'object' ); |
| 664 | + # Determine the side border color the question. |
| 665 | + $output_table[] = array( '__tag'=>'tbody', '__end'=>"\n", 0=>$buffer ); |
| 666 | + $tags = array( '__tag'=>'div', '__end'=>"\n", 'class'=>'question', |
| 667 | + 0=>array( '__tag'=>'div', '__end'=>"\n", 'class'=>'header', |
| 668 | + 0=>array( '__tag'=>'span', 'class'=>'questionId', 0=>$question->mQuestionId ) |
| 669 | + ), |
| 670 | + 1=>array( '__tag'=>'div', 0=>$this->parser->recursiveTagParse( $question->mCommonQuestion, $this->ppframe ) ) |
| 671 | + ); |
| 672 | + $tags[] = &$output_table; |
| 673 | + return qp_Renderer::renderHTMLobject( $tags ); |
| 674 | + } |
| 675 | + |
| 676 | +} |
| 677 | + |
| 678 | +/** |
| 679 | + * Processes poll markup in declaration/voting mode |
| 680 | + */ |
| 681 | +class qp_Poll extends qp_AbstractPoll { |
| 682 | + |
| 683 | + function __construct( $argv, &$parser, &$frame ) { |
| 684 | + parent::__construct( $argv, $parser, $frame ); |
| 685 | + # order_id is used to sort out polls on the Special:PollResults statistics page |
| 686 | + $this->mOrderId = self::$sOrderId; |
| 687 | + # Determine if this poll is being corrected or not, according to the pollId |
| 688 | + $this->mBeingCorrected = ( $this->mRequest->getVal('pollId') == $this->mPollId ); |
| 689 | + } |
| 690 | + |
| 691 | + # prepare qp_PollStore object |
| 692 | + # @return true on success ($this->pollStore has been created successfully), error string on failure |
| 693 | + function getPollStore() { |
| 694 | + # check the headers for errors |
| 695 | + if ( $this->mPollId == null ) { |
| 696 | + $this->mState = "error"; |
| 697 | + return self::fatalError( 'qp_error_no_poll_id' ); |
| 698 | + } |
| 699 | + if ( !self::isValidPollId( $this->mPollId ) ) { |
| 700 | + $this->mState = "error"; |
| 701 | + return self::fatalError( 'qp_error_invalid_poll_id', $this->mPollId ); |
| 702 | + } |
| 703 | + if ( !self::isUniquePollId( $this->mPollId ) ) { |
| 704 | + $this->mState = "error"; |
| 705 | + return self::fatalError( 'qp_error_already_used_poll_id', $this->mPollId ); |
| 706 | + } |
| 707 | + self::addPollId( $this->mPollId ); // add current poll id to the static list of poll ids on this page |
| 708 | + if ( $this->pollAddr !== null ) { |
| 709 | + $this->mState = "error"; |
| 710 | + return self::fatalError( 'qp_error_address_in_decl_mode' ); |
| 711 | + } |
| 712 | + if ( $this->dependsOn != '' ) { |
| 713 | + $depsOnAddr = self::getPrefixedPollAddress( $this->dependsOn ); |
| 714 | + if ( is_array( $depsOnAddr ) ) { |
| 715 | + $this->dependsOn = $depsOnAddr[2]; |
| 716 | + } else { |
| 717 | + return self::fatalError( 'qp_error_invalid_dependance_value', $this->mPollId, $this->dependsOn ); |
| 718 | + } |
| 719 | + } |
| 720 | + if ( ( $dependanceResult = $this->checkDependance( $this->dependsOn ) ) !== true ) { |
| 721 | + # return an error string |
| 722 | + # here we create a pollstore only to update poll attributes (order_id,dependance), in case these were changed |
| 723 | + $this->pollStore = new qp_PollStore( array( |
| 724 | + 'from'=>'poll_get', |
| 725 | + 'poll_id'=>$this->mPollId, |
| 726 | + 'order_id'=>$this->mOrderId, |
| 727 | + 'dependance'=>$this->dependsOn ) ); |
| 728 | + return $dependanceResult; |
| 729 | + } |
| 730 | + if ( $this->mBeingCorrected ) { |
| 731 | + $this->pollStore = new qp_PollStore( array( |
| 732 | + 'from'=>'poll_post', |
| 733 | + 'poll_id'=>$this->mPollId, |
| 734 | + 'order_id'=>$this->mOrderId, |
| 735 | + 'dependance'=>$this->dependsOn ) ); |
| 736 | + $this->pollStore->loadQuestions(); |
| 737 | + $this->pollStore->setLastUser( $this->username, false ); |
| 738 | + $this->pollStore->loadUserAlreadyVoted(); |
| 739 | + } else { |
| 740 | + $this->pollStore = new qp_PollStore( array( |
| 741 | + 'from'=>'poll_get', |
| 742 | + 'poll_id'=>$this->mPollId, |
| 743 | + 'order_id'=>$this->mOrderId, |
| 744 | + 'dependance'=>$this->dependsOn ) ); |
| 745 | + $this->pollStore->loadQuestions(); |
| 746 | + $this->pollStore->setLastUser( $this->username, false ); |
| 747 | + # to show previous choice of current user, if that's available |
| 748 | + # do not check the result, because user can vote even if haven't voted before |
| 749 | + $this->pollStore->loadUserVote(); |
| 750 | + } |
523 | 751 | return true; |
524 | 752 | } |
525 | 753 | |
526 | | -} /* end of qp_Setup class */ |
| 754 | + # parse the text enclosed in poll tag |
| 755 | + # @param $input - text enclosed in poll tag |
| 756 | + # @return string representing rendered set of the questions / boolean true - stop further processing |
| 757 | + function parseInput( $input ) { |
| 758 | + global $wgTitle; |
| 759 | + # Process the input |
| 760 | + $output = $this->parseQuestions( $input ); |
| 761 | + # check whether the poll was successfully submitted |
| 762 | + if ( $this->pollStore->stateComplete() ) { |
| 763 | + # store user vote to the DB (when the poll is fine) |
| 764 | + $this->pollStore->setLastUser( $this->username ); |
| 765 | + $this->pollStore->setUserVote(); |
| 766 | + } |
| 767 | + if ( $this->pollStore->voteDone ) { |
| 768 | + if ( qp_Setup::$cache_control ) { |
| 769 | + $this->mResponse->setcookie( 'QPoll', 'clearCache', time()+20 ); |
| 770 | + } |
| 771 | + $this->mResponse->header( 'HTTP/1.0 302 Found' ); |
| 772 | + $this->mResponse->header( 'Location: ' . $wgTitle->getFullURL() . self::getPollTitleFragment( $this->mPollId ) ); |
| 773 | + return true; |
| 774 | + } |
| 775 | + return $output; |
| 776 | + } |
527 | 777 | |
528 | | -/* renders output data */ |
| 778 | + # encloses the output of $this->parseQuestions() into the output tag wrappers |
| 779 | + # @param $input - the output of $this->parseQuestions() |
| 780 | + # @return rendered "final" html |
| 781 | + function generateOutput( $input ) { |
| 782 | + global $wgOut, $wgRequest; |
| 783 | + # increase the order_id counter for the future successfully declared polls |
| 784 | + # (remember, we're in declaration mode, where 'order_id' is important |
| 785 | + self::$sOrderId++; |
| 786 | + # Generates the output. |
| 787 | + $qpoll_div = array( '__tag'=>'div', 'class'=>'qpoll' ); |
| 788 | + $qpoll_div[] = array( '__tag'=>'a', 'name'=>self::getPollTitleFragment( $this->mPollId, '' ), 0=>'' ); |
| 789 | + $qpoll_form = array( '__tag'=>'form', 'method'=>'post', 'action'=>self::getPollTitleFragment( $this->mPollId ), '__end'=>"\n" ); |
| 790 | + $qpoll_div[] = &$qpoll_form; |
| 791 | + # Determine the content of the settings table. |
| 792 | + $settings = Array(); |
| 793 | + if ( $this->mState != '' ) { |
| 794 | + $settings[0][] = array( '__tag'=>'td', 'class'=>'margin', 'style'=>'background: ' . QP_CSS_ERROR_COLOR2 . ';' ); |
| 795 | + $settings[0][] = array( '__tag'=>'td', 0=>wfMsgHtml( 'qp_result_' . $this->mState ) ); |
| 796 | + } |
| 797 | + # Build the settings table. |
| 798 | + if ( count( $settings ) > 0 ) { |
| 799 | + $settingsTable = array( '__tag'=>'table', 'class'=>'settings', '__end'=>"\n" ); |
| 800 | + foreach($settings as $settingsTr) { |
| 801 | + $settingsTable[] = array( '__tag'=>'tr', 0=> $settingsTr, '__end'=>"\n" ); |
| 802 | + } |
| 803 | + $qpoll_form[] = &$settingsTable; |
| 804 | + } |
| 805 | + $qpoll_form[] = array( '__tag'=>'input', 'type'=>'hidden', 'name'=>'pollId', 'value'=>$this->mPollId ); |
| 806 | + $qpoll_form[] = array( '__tag'=>'div', 'class'=>'pollQuestions', 0=>$input ); |
| 807 | + $submitBtn = array( '__tag'=>'input', 'type'=>'submit' ); |
| 808 | + $submitMsg = 'qp_vote_button'; |
| 809 | + if ( $this->pollStore->isAlreadyVoted() ) { |
| 810 | + $submitMsg = 'qp_vote_again_button'; |
| 811 | + } |
| 812 | + if ( $this->mBeingCorrected ) { |
| 813 | + if ( $this->pollStore->getState() == "complete" ) { |
| 814 | + $submitMsg = 'qp_vote_again_button'; |
| 815 | + } |
| 816 | + } else { |
| 817 | + if ( $this->pollStore->getState() == "error" ) { |
| 818 | + $submitBtn[ 'disabled' ] = 'disabled'; |
| 819 | + } |
| 820 | + } |
| 821 | + # disable submit button in preview mode & printable version |
| 822 | + if ( $wgRequest->getVal( 'action' ) == 'parse' || $wgOut->isPrintable() ) { |
| 823 | + $submitBtn[ 'disabled' ] = 'disabled'; |
| 824 | + } |
| 825 | + $submitBtn[ 'value' ] = wfMsgHtml( $submitMsg ); |
| 826 | + $p = array( '__tag'=>'p' ); |
| 827 | + $p[] = $submitBtn; |
| 828 | + $qpoll_form[] = &$p; |
| 829 | + return qp_Renderer::renderHTMLobject( $qpoll_div ); |
| 830 | + } |
| 831 | + |
| 832 | + # check whether the poll is dependant on other polls |
| 833 | + # @param $dependsOn - poll address on which the current (recursive) poll is dependant |
| 834 | + # @param $nonVotedDepLink - maintains different logic for recursion |
| 835 | + # value: string - link to the poll in chain which has not been voted yet OR |
| 836 | + # value: boolean - false when there was no poll in the chain which has not been voted yet |
| 837 | + # @return true when dependance is fulfilled, error message otherwise |
| 838 | + private function checkDependance( $dependsOn, $nonVotedDepLink = false ) { |
| 839 | + # check the headers for dependance to other polls |
| 840 | + if ( $dependsOn !== '' ) { |
| 841 | + $depPollStore = qp_PollStore::newFromAddr( $dependsOn ); |
| 842 | + if ( $depPollStore instanceof qp_PollStore ) { |
| 843 | + # process recursive dependance |
| 844 | + $depTitle = $depPollStore->getTitle(); |
| 845 | + $depPollId = $depPollStore->mPollId; |
| 846 | + $depLink = self::$skin->link( $depTitle, $depTitle->getPrefixedText() . ' (' . $depPollStore->mPollId . ')' ); |
| 847 | + if ( $depPollStore->pid === null ) { |
| 848 | + return self::fatalError( 'qp_error_missed_dependance_poll', $this->mPollId, $depLink, $depPollId ); |
| 849 | + } |
| 850 | + if ( !$depPollStore->loadQuestions() ) { |
| 851 | + return self::fatalError( 'qp_error_vote_dependance_poll', $depLink ); |
| 852 | + } |
| 853 | + $depPollStore->setLastUser( $this->username, false ); |
| 854 | + if ( $depPollStore->loadUserAlreadyVoted() ) { |
| 855 | + # user already voted in current the poll in chain |
| 856 | + if ( $depPollStore->dependsOn === '' ) { |
| 857 | + if ( $nonVotedDepLink === false ) { |
| 858 | + # there was no non-voted deplinks in the chain at some previous level of recursion |
| 859 | + return true; |
| 860 | + } else { |
| 861 | + # there is an non-voted deplink in the chain at some previous level of recursion |
| 862 | + return self::fatalError( 'qp_error_vote_dependance_poll', $nonVotedDepLink ); |
| 863 | + } |
| 864 | + } else { |
| 865 | + return $this->checkDependance( $depPollStore->dependsOn, $nonVotedDepLink ); |
| 866 | + } |
| 867 | + } else { |
| 868 | + # user hasn't voted in current the poll in chain |
| 869 | + if ( $depPollStore->dependsOn === '' ) { |
| 870 | + # current element of chain is not voted and furthermore, doesn't depend on any other polls |
| 871 | + return self::fatalError( 'qp_error_vote_dependance_poll', $depLink ); |
| 872 | + } else { |
| 873 | + # current element of chain is not voted, BUT it has it's own dependance |
| 874 | + # so we will check for the most deeply nested poll which hasn't voted, yet |
| 875 | + return $this->checkDependance( $depPollStore->dependsOn, $depLink ); |
| 876 | + } |
| 877 | + } |
| 878 | + } else { |
| 879 | + # process poll address errors |
| 880 | + switch ( $depPollStore ) { |
| 881 | + case QP_ERROR_INVALID_ADDRESS : |
| 882 | + return self::fatalError( 'qp_error_invalid_dependance_value', $this->mPollId, $dependsOn ); |
| 883 | + case QP_ERROR_MISSED_TITLE : |
| 884 | + $depSplit = self::getPrefixedPollAddress( $dependsOn ); |
| 885 | + if ( is_array( $depSplit ) ) { |
| 886 | + list( $depTitleStr, $depPollId ) = $depSplit; |
| 887 | + $depTitle = Title::newFromURL( $depTitleStr ); |
| 888 | + $depTitleStr = $depTitle->getPrefixedText(); |
| 889 | + $depLink = self::$skin->link( $depTitle, $depTitleStr ); |
| 890 | + return self::fatalError( 'qp_error_missed_dependance_title', $this->mPollId, $depLink, $depPollId ); |
| 891 | + } else { |
| 892 | + return self::fatalError( 'qp_error_invalid_dependance_value', $this->mPollId, $dependsOn ); |
| 893 | + } |
| 894 | + default : |
| 895 | + throw new MWException( __METHOD__ . ' invalid dependance poll store found' ); |
| 896 | + } |
| 897 | + } |
| 898 | + } else { |
| 899 | + return true; |
| 900 | + } |
| 901 | + } |
| 902 | + |
| 903 | + # Replace questions from QPoll syntax to HTML |
| 904 | + # @param $input - A question in QPoll syntax |
| 905 | + # @return string representing rendered set of the questions / empty string "suggests" redirect |
| 906 | + function parseQuestions($input) { |
| 907 | + $write_row = Array(); |
| 908 | + $write_col = Array(); |
| 909 | + $questions = Array(); |
| 910 | + $splitPattern = '`(^|\n\s*)\n\s*{`u'; |
| 911 | + $unparsedQuestions = preg_split( $splitPattern, $input, -1, PREG_SPLIT_NO_EMPTY ); |
| 912 | + $questionPattern = '`(.*?[^|\}])\}[ \t]*(\n(.*)|$)`su'; |
| 913 | + # first pass: parse the headers |
| 914 | + foreach( $unparsedQuestions as $unparsedQuestion ) { |
| 915 | + # If this "unparsedQuestion" is not a full question, |
| 916 | + # we put the text into a buffer to add it at the beginning of the next question. |
| 917 | + if( !empty( $buffer ) ) { |
| 918 | + $unparsedQuestion = "$buffer\n\n{" . $unparsedQuestion; |
| 919 | + } |
| 920 | + if( preg_match( $questionPattern, $unparsedQuestion, $matches ) ) { |
| 921 | + $buffer = ""; |
| 922 | + $header = isset( $matches[1] ) ? $matches[1] : ''; |
| 923 | + $body = isset( $matches[3] ) ? $matches[3] : null; |
| 924 | + $questions[] = $this->parseQuestionHeader( $header, $body ); |
| 925 | + } else { |
| 926 | + $buffer = $unparsedQuestion; |
| 927 | + } |
| 928 | + } |
| 929 | + # analyze question headers |
| 930 | + # check for showresults attribute |
| 931 | + $questions_set = Array(); |
| 932 | + foreach( $questions as &$question ) { |
| 933 | + if ( $question->showResults['type'] != 0 && |
| 934 | + method_exists( 'qp_Question', 'addShowResults' . $question->showResults['type'] ) ) { |
| 935 | + $questions_set[] = $question->mQuestionId; |
| 936 | + } |
| 937 | + } |
| 938 | + # load the statistics for all/selective/none of questions |
| 939 | + if ( count( $questions_set ) > 0 ) { |
| 940 | + if ( count( $questions_set ) == count( $questions ) ) { |
| 941 | + $this->pollStore->loadTotals(); |
| 942 | + } else { |
| 943 | + $this->pollStore->loadTotals( $questions_set ); |
| 944 | + } |
| 945 | + $this->pollStore->calculateStatistics(); |
| 946 | + } |
| 947 | + # second pass: parse the body |
| 948 | + foreach( $questions as &$question ) { |
| 949 | + if ( $this->perRow > 1 ) { |
| 950 | + $write_col[] = array( '__tag'=>'td', 'valign'=>'top', 0=>$this->parseQuestionBody( $question ), '__end'=>"\n" ); |
| 951 | + if ( $this->currCol == 1 ) { |
| 952 | + $write_row[] = array( '__tag'=>'tr', 0=>$write_col, '__end'=>"\n" ); |
| 953 | + $write_col = Array(); |
| 954 | + } |
| 955 | + if ( --$this->currCol < 1 ) { |
| 956 | + $this->currCol = $this->perRow; |
| 957 | + } |
| 958 | + } else { |
| 959 | + $write_row[] = $this->parseQuestionBody( $question ); |
| 960 | + } |
| 961 | + # question object is not needed anymore |
| 962 | + unset( $question ); |
| 963 | + } |
| 964 | + if ( $this->perRow > 1 && $this->currCol != $this->perRow ) { |
| 965 | + # add last incomplete row |
| 966 | + $write_row[] = array( '__tag'=>'tr', '__end'=>"\n", 0=>$write_col ); |
| 967 | + } |
| 968 | + if ( $this->perRow > 1 ) { |
| 969 | + $question_table = array( '__tag'=>'table', 0=>array( '__tag'=>'tbody', 0=>&$write_row, '__end'=>"\n" ), '__end'=>"\n" ); |
| 970 | + return qp_Renderer::renderHTMLobject( $question_table ); |
| 971 | + } else { |
| 972 | + return qp_Renderer::renderHTMLobject( $write_row ); |
| 973 | + } |
| 974 | + } |
| 975 | + |
| 976 | + # Convert a question on the page from QPoll syntax to HTML |
| 977 | + # @param $header : the text of question "main" header (common question and XML-like attrs) |
| 978 | + # $body : the text of question body (starting with body header which defines categories and spans, followed by proposal list) |
| 979 | + # @return question object with parsed headers and no data loaded |
| 980 | + function parseQuestionHeader( $header, $body ) { |
| 981 | + $question = new qp_Question( $this->parser, $this->ppframe, $this->mBeingCorrected, ++$this->mQuestionId, $this->showResults ); |
| 982 | + # parse questions common question and XML attributes |
| 983 | + $question->parseMainHeader( $header ); |
| 984 | + if ( $question->getState() != 'error' ) { |
| 985 | + # load previous user choice, when it's available and DB header is compatible with parsed header |
| 986 | + if ( $body === null || !method_exists( $question, $question->mType . 'ParseBody' ) ) { |
| 987 | + $question->setState( 'error', wfMsgHtml( 'qp_error_question_not_implemented', qp_Setup::entities( $question->mType ) ) ); |
| 988 | + } else { |
| 989 | + # parse the categories and spans (metacategories) |
| 990 | + $question->parseBodyHeader( $body ); |
| 991 | + } |
| 992 | + } |
| 993 | + return $question; |
| 994 | + } |
| 995 | + |
| 996 | + # populate the question with data and build it's HTML representation |
| 997 | + # returns HTML representation of the question |
| 998 | + function parseQuestionBody( &$question ) { |
| 999 | + if ( $question->getState() == 'error' ) { |
| 1000 | + # error occured during the previously performed header parsing, do not process further |
| 1001 | + $buffer = $question->getHeaderError(); |
| 1002 | + # http get: invalid question syntax, parse errors will cause submit button disabled |
| 1003 | + $this->pollStore->stateError(); |
| 1004 | + } else { |
| 1005 | + # populate $question with raw source values |
| 1006 | + $question->getQuestionAnswer( $this->pollStore ); |
| 1007 | + # check whether the global showresults level prohibits to show statistical data |
| 1008 | + # to the users who hasn't voted |
| 1009 | + if ( qp_Setup::$global_showresults <= 1 && !$question->alreadyVoted ) { |
| 1010 | + # suppress statistical results when the current user hasn't voted the question |
| 1011 | + $question->showResults = Array( 'type'=>0 ); |
| 1012 | + } |
| 1013 | + # parse the question body |
| 1014 | + # store the html result into the buffer to determine some parameters before outputing it |
| 1015 | + # warning! parameters are passed only by value, not the reference |
| 1016 | + $buffer = $question->{$question->mType . 'ParseBody'}(); |
| 1017 | + if ( $this->mBeingCorrected ) { |
| 1018 | + if ( $question->getState() == '' ) { |
| 1019 | + # question is OK, store it into pollStore |
| 1020 | + $question->store( $this->pollStore ); |
| 1021 | + } else { |
| 1022 | + # http post: not every proposals were answered: do not update DB |
| 1023 | + $this->pollStore->stateIncomplete(); |
| 1024 | + } |
| 1025 | + } else { |
| 1026 | + # this is the get, not the post: do not update DB |
| 1027 | + if ( $question->getState() == '' ) { |
| 1028 | + $this->pollStore->stateIncomplete(); |
| 1029 | + } else { |
| 1030 | + # http get: invalid question syntax, parse errors will cause submit button disabled |
| 1031 | + $this->pollStore->stateError(); |
| 1032 | + } |
| 1033 | + } |
| 1034 | + } |
| 1035 | + $output_table = array( '__tag'=>'table', '__end'=>"\n", 'class'=>'object' ); |
| 1036 | + # Determine the side border color the question. |
| 1037 | + if ( $question->getState() != "" ) { |
| 1038 | + global $wgContLang; |
| 1039 | + $style = $wgContLang->isRTL() ? 'border-right' : 'border-left'; |
| 1040 | + $style .= ': 3px solid ' . QP_CSS_ERROR_COLOR2 . ';'; |
| 1041 | + $output_table[ 'style' ] = $style; |
| 1042 | + $this->mState = $question->getState(); |
| 1043 | + } |
| 1044 | + $output_table[] = array( '__tag'=>'tbody', '__end'=>"\n", 0=>&$buffer ); |
| 1045 | + $tags = array( '__tag'=>'div', '__end'=>"\n", 'class'=>'question', |
| 1046 | + 0=>array( '__tag'=>'div', '__end'=>"\n", 'class'=>'header', |
| 1047 | + 0=>array( '__tag'=>'span', 'class'=>'questionId', 0=>$question->mQuestionId ) |
| 1048 | + ), |
| 1049 | + 1=>array( '__tag'=>'div', 0=>$this->parser->recursiveTagParse( $question->mCommonQuestion, $this->ppframe ) ) |
| 1050 | + ); |
| 1051 | + $tags[] = &$output_table; |
| 1052 | + return qp_Renderer::renderHTMLobject( $tags ); |
| 1053 | + } |
| 1054 | + |
| 1055 | +} |
| 1056 | + |
| 1057 | +/* render output data */ |
529 | 1058 | class qp_Renderer { |
530 | | - # the stucture of $tag is like this: |
531 | | - # array( "__tag"=>"td", "class"=>"myclass", 0=>"text before li", 1=>array( "__tag"=>"li", 0=>"text inside li" ), 2=>"text after li" ) |
532 | | - # both tagged and tagless lists are supported |
| 1059 | + // the stucture of $tag is like this: |
| 1060 | + // array( "__tag"=>"td", "class"=>"myclass", 0=>"text before li", 1=>array( "__tag"=>"li", 0=>"text inside li" ), 2=>"text after li" ) |
| 1061 | + // both tagged and tagless lists are supported |
533 | 1062 | static function renderHTMLobject( &$tag ) { |
534 | 1063 | $tag_open = ""; |
535 | 1064 | $tag_close = ""; |
— | — | @@ -705,7 +1234,7 @@ |
706 | 1235 | } |
707 | 1236 | } |
708 | 1237 | } |
709 | | -} /* end of qp_Renderer class */ |
| 1238 | +} |
710 | 1239 | |
711 | 1240 | class qp_FunctionsHook { |
712 | 1241 | |
— | — | @@ -721,7 +1250,6 @@ |
722 | 1251 | var $error_message = 'no_such_poll'; |
723 | 1252 | |
724 | 1253 | function qpuserchoice( &$parser, $frame, $args ) { |
725 | | - qp_Setup::onLoadAllMessages(); |
726 | 1254 | $this->frame = &$frame; |
727 | 1255 | $this->args = &$args; |
728 | 1256 | if ( isset( $args[ 0 ] ) ) { |
— | — | @@ -803,9 +1331,8 @@ |
804 | 1332 | } |
805 | 1333 | } |
806 | 1334 | } |
807 | | - # do not need to wrap the result into qp_Setup::entities() |
808 | | - # because the result is a wikitext (will be escaped by parser) |
| 1335 | + # do not need to use qp_Setup::entities because the result is a wikitext (will be escaped by parser) |
809 | 1336 | return $result; |
810 | 1337 | } |
811 | 1338 | |
812 | | -} /* end of qp_FunctionsHook class */ |
| 1339 | +} |
Index: trunk/extensions/QPoll/qp_i18n.php |
— | — | @@ -0,0 +1,2639 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * ***** BEGIN LICENSE BLOCK ***** |
| 5 | + * This file is part of QPoll. |
| 6 | + * Uses parts of code from Quiz extension (c) 2007 Louis-Rémi BABE. All rights reserved. |
| 7 | + * |
| 8 | + * QPoll is free software; you can redistribute it and/or modify |
| 9 | + * it under the terms of the GNU General Public License as published by |
| 10 | + * the Free Software Foundation; either version 2 of the License, or |
| 11 | + * (at your option) any later version. |
| 12 | + * |
| 13 | + * QPoll is distributed in the hope that it will be useful, |
| 14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | + * GNU General Public License for more details. |
| 17 | + * |
| 18 | + * You should have received a copy of the GNU General Public License |
| 19 | + * along with QPoll; if not, write to the Free Software |
| 20 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 21 | + * |
| 22 | + * ***** END LICENSE BLOCK ***** |
| 23 | + * |
| 24 | + * QPoll is a poll tool for MediaWiki. |
| 25 | + * |
| 26 | + * To activate this extension : |
| 27 | + * * Create a new directory named QPoll into the directory "extensions" of MediaWiki. |
| 28 | + * * Place the files from the extension archive there. |
| 29 | + * * Add this line at the end of your LocalSettings.php file : |
| 30 | + * require_once "$IP/extensions/QPoll/qp_user.php"; |
| 31 | + * |
| 32 | + * @file |
| 33 | + * @version 0.7.0 |
| 34 | + * @link http://www.mediawiki.org/wiki/Extension:QPoll |
| 35 | + * @author QuestPC <questpc@rambler.ru> |
| 36 | + * @ingroup Extensions |
| 37 | + */ |
| 38 | + |
| 39 | +/** |
| 40 | + * Messages list. |
| 41 | + */ |
| 42 | + |
| 43 | +$messages = array(); |
| 44 | + |
| 45 | +/** English (English) |
| 46 | + * @author QuestPC |
| 47 | + */ |
| 48 | +$messages['en'] = array( |
| 49 | + 'pollresults' => 'Results of the polls on this site', |
| 50 | + 'qp_parentheses' => '($1)', |
| 51 | + 'qp_full_category_name' => '$1($2)', |
| 52 | + 'qp_desc' => 'Allows creation of polls', |
| 53 | + 'qp_desc-sp' => '[[Special:PollResults|Special page]] for viewing results of the polls', |
| 54 | + 'qp_result_NA' => 'Not answered', |
| 55 | + 'qp_result_error' => 'Syntax error', |
| 56 | + 'qp_vote_button' => 'Vote', |
| 57 | + 'qp_vote_again_button' => 'Change your vote', |
| 58 | + 'qp_polls_list' => 'List all polls', |
| 59 | + 'qp_users_list' => 'List all users', |
| 60 | + 'qp_browse_to_poll' => 'Browse to $1', |
| 61 | + 'qp_browse_to_user' => 'Browse to $1', |
| 62 | + 'qp_votes_count' => '$1 {{PLURAL:$1|vote|votes}}', |
| 63 | + 'qp_source_link' => 'Source', |
| 64 | + 'qp_stats_link' => 'Statistics', |
| 65 | + 'qp_users_link' => 'Users', |
| 66 | + 'qp_voice_link' => 'User voice', |
| 67 | + 'qp_voice_link_inv' => 'User voice?', |
| 68 | + 'qp_user_polls_link' => 'Participated in $1 {{PLURAL:$1|poll|polls}}', // Supports use of GENDER with $2 |
| 69 | + 'qp_user_missing_polls_link' => 'No participation', // Supports use of GENDER with $1 |
| 70 | + 'qp_not_participated_link' => 'Not participated', |
| 71 | + 'qp_order_by_username' => 'Order by username', |
| 72 | + 'qp_order_by_polls_count' => 'Order by polls count', |
| 73 | + 'qp_results_line_qupl' => 'Page "$1" Poll "$2": $3', |
| 74 | + 'qp_results_line_qpl' => 'Page "$1" Poll "$2": $3, $4, $5, $6', |
| 75 | + 'qp_header_line_qpul' => '$1 [ Page "$2" Poll "$3" ]', |
| 76 | + 'qp_results_line_qpul' => '$1: $2', |
| 77 | + 'qp_header_line_qucl' => '$1. $2<br />$3 ??? $4', |
| 78 | + 'qp_results_line_qucl' => '$1: $2 $3', |
| 79 | + 'qp_export_to_xls' => 'Export statistics into XLS format', |
| 80 | + 'qp_voices_to_xls' => 'Export voices into XLS format', |
| 81 | + 'qp_users_answered_questions' => '$1 {{PLURAL:$1|user|users}} answered to the questions', |
| 82 | + 'qp_func_no_such_poll' => 'No such poll ($1)', |
| 83 | + 'qp_func_missing_question_id' => 'Please specify an existing question id (starting from 1) for the poll $1', |
| 84 | + 'qp_func_invalid_question_id' => 'Invalid question id=$2 (not a number) for the poll $1', |
| 85 | + 'qp_func_missing_proposal_id' => 'Please specify an existing proposal id (starting from 0) for the poll $1, question $2', |
| 86 | + 'qp_func_invalid_proposal_id' => 'Invalid proposal id=$3 (not a number) for the poll $1, question $2', |
| 87 | + 'qp_error_no_such_poll' => 'No such poll ($1). |
| 88 | +Make sure that the poll declared and saved, also be sure to use address delimiter character #', |
| 89 | + 'qp_error_in_question_header' => 'Invalid question header: $1', |
| 90 | + 'qp_error_id_in_stats_mode' => 'Cannot declare an ID of the poll in statistical mode', |
| 91 | + 'qp_error_dependance_in_stats_mode' => 'Cannot declare dependance chain of the poll in statistical mode', |
| 92 | + 'qp_error_no_stats' => 'No statistical data is available, because no one has voted for this poll, yet (address=$1)', |
| 93 | + 'qp_error_address_in_decl_mode' => 'Cannot get an address of the poll in declaration mode', |
| 94 | + 'qp_error_question_not_implemented' => 'Questions of such type are not implemented: $1', |
| 95 | + 'qp_error_invalid_question_type' => 'Invalid question type: $1', |
| 96 | + 'qp_error_type_in_stats_mode' => 'Question type cannot be defined in statistical display mode: $1', |
| 97 | + 'qp_error_no_poll_id' => 'Poll tag has no id attribute defined.', |
| 98 | + 'qp_error_invalid_poll_id' => 'Invalid poll id (id=$1). |
| 99 | +Poll id may contain only letters, numbers and space character', |
| 100 | + 'qp_error_already_used_poll_id' => 'The poll id has already been used on this page (id=$1).', |
| 101 | + 'qp_error_invalid_dependance_value' => 'The poll (id=$1) dependance chain has invalid value of dependance attribute (dependance="$2")', |
| 102 | + 'qp_error_missed_dependance_title' => 'The poll (id=$1) is dependant on the another poll (id=$3) from page [[$2]], but the title [[$2]] was not found. |
| 103 | +Either remove the dependance attribute, or restore [[$2]]', |
| 104 | + 'qp_error_missed_dependance_poll' => 'The poll (id=$1) is dependant on the another poll (id=$3) at page $2, but that poll does not exists or has not been saved yet. |
| 105 | +Either remove the dependance attribute, or create the poll with id=$3 at the page $2 and save it. |
| 106 | +To save a poll, submit it while not answering to any proposal questions.', |
| 107 | + 'qp_error_vote_dependance_poll' => 'Please vote for poll $1 first.', |
| 108 | + 'qp_error_too_many_spans' => 'Too many category groups for the total number of subcategories defined', |
| 109 | + 'qp_error_unanswered_span' => 'Unanswered subcategory', |
| 110 | + 'qp_error_non_unique_choice' => 'This question requires unique proposal answer', |
| 111 | + 'qp_error_category_name_empty' => 'Category name is empty', |
| 112 | + 'qp_error_proposal_text_empty' => 'Proposal text is empty', |
| 113 | + 'qp_error_too_few_categories' => 'At least two categories must be defined', |
| 114 | + 'qp_error_too_few_spans' => 'Every category group must contain at least two subcategories', |
| 115 | + 'qp_error_no_answer' => 'Unanswered proposal', |
| 116 | + 'qp_error_unique' => 'Question of type unique() has more proposals than possible answers defined: impossible to complete' |
| 117 | +); |
| 118 | + |
| 119 | +/** Message documentation (Message documentation) |
| 120 | + * @author Fryed-peach |
| 121 | + * @author Hamilton Abreu |
| 122 | + * @author IAlex |
| 123 | + * @author Purodha |
| 124 | + * @author Siebrand |
| 125 | + */ |
| 126 | +$messages['qqq'] = array( |
| 127 | + 'pollresults' => 'Special page name in [[Special:SpecialPages]]', |
| 128 | + 'qp_desc' => '{{desc}} Important notice: Categories can be grouped into category groups, which are internally referred as "spans". Such grouped categories become "subcategories". While the extension evolved, these groups were consequentially called as "spans", "metacategories", "category groups". Please read the on-line documentation carefully before translating.', |
| 129 | + 'qp_result_error' => '{{Identical|Syntax error}}', |
| 130 | + 'qp_vote_button' => '{{Identical|Vote}}', |
| 131 | + 'qp_source_link' => '"Source" is the link text for a link to the page where the poll is defined. |
| 132 | +{{Identical|Source}}', |
| 133 | + 'qp_stats_link' => '{{Identical|Statistics}}', |
| 134 | + 'qp_users_link' => '{{Identical|User}}', |
| 135 | + 'qp_voice_link_inv' => 'At the moment of query generation there was no user answer for the selected poll yet. Question mark encourages wiki administrator to re-submit the query again.', |
| 136 | + 'qp_user_polls_link' => 'Parameters: |
| 137 | +* $1 is the number of polls participated in. |
| 138 | +* $2 is the name of the user this message refers to (optional - use for GENDER)', |
| 139 | + 'qp_user_missing_polls_link' => 'Parameters: |
| 140 | +* $1 is the name of the user this message refers to (optional - use for GENDER)', |
| 141 | + 'qp_results_line_qupl' => 'Parameters: |
| 142 | +* $1 is a link to the page page name the poll is on with the page title as link label |
| 143 | +* $2 is the poll name in plain text |
| 144 | +* $3 is a link to the poll statistics with link label {{msg-mw|qp_stats_link}}', |
| 145 | + 'qp_results_line_qpl' => 'Parameters: |
| 146 | +* $1 is a link to the page page name the poll is on with the page title as link label |
| 147 | +* $2 is the poll name in plain text |
| 148 | +* $3 is a link to the poll with link label {{msg-mw|qp_source_link}} |
| 149 | +* $4 is a link to the poll statistics with link label {{msg-mw|qp_stats_link}} |
| 150 | +* $5 is a link to the users that participated in the poll with link label {{msg-mw|qp_users_link}} |
| 151 | +* $6 is a link to the with link label {{msg-mw|qp_not_participated_link}}', |
| 152 | + 'qp_error_missed_dependance_poll' => 'Parameters: |
| 153 | +* $1 is the poll ID of the poll having an error. |
| 154 | +* $2 is a link to the page with the poll, that this erroneous poll depends on. |
| 155 | +* $3 is the poll ID of the poll, which this erroneous poll depends on.', |
| 156 | + 'qp_error_too_many_spans' => 'There cannot be more category groups defined than the total count of subcategories.', |
| 157 | + 'qp_error_too_few_spans' => 'Every category group should include at least two subcategories', |
| 158 | +); |
| 159 | + |
| 160 | +/** Afrikaans (Afrikaans) |
| 161 | + * @author Naudefj |
| 162 | + */ |
| 163 | +$messages['af'] = array( |
| 164 | + 'pollresults' => 'Resultate van die peilings op hierdie webwerf', |
| 165 | + 'qp_desc' => 'Maak dit moontlik om peilings te skep', |
| 166 | + 'qp_desc-sp' => '[[Special:PollResults|Speciale bladsy]] om die resultate van peilings te wys', |
| 167 | + 'qp_result_NA' => 'Nie beantwoord nie', |
| 168 | + 'qp_result_error' => 'Sintaksfout', |
| 169 | + 'qp_vote_button' => 'Stem', |
| 170 | + 'qp_vote_again_button' => 'Verander u stem', |
| 171 | + 'qp_polls_list' => 'Wys alle peilings', |
| 172 | + 'qp_users_list' => 'Lys alle gebruikers', |
| 173 | + 'qp_browse_to_poll' => 'Wys peiling $1', |
| 174 | + 'qp_browse_to_user' => 'Blaai na gebruiker $1', |
| 175 | + 'qp_votes_count' => '$1 {{PLURAL:$1|stem|stemme}}', |
| 176 | + 'qp_source_link' => 'Bron', |
| 177 | + 'qp_stats_link' => 'Statistieke', |
| 178 | + 'qp_users_link' => 'Gebruikers', |
| 179 | + 'qp_voice_link' => 'Gebruikersstem', |
| 180 | + 'qp_voice_link_inv' => 'Gebruikersstem', |
| 181 | + 'qp_user_polls_link' => 'Het aan $1 {{PLURAL:$1|peiling|peilings}} deelgeneem', |
| 182 | + 'qp_user_missing_polls_link' => 'Geen deelname', |
| 183 | + 'qp_not_participated_link' => 'Nie deelgeneem nie', |
| 184 | + 'qp_order_by_username' => 'Sorteer op gebruikersnaam', |
| 185 | + 'qp_order_by_polls_count' => 'Sorteer op aantal peilings', |
| 186 | + 'qp_results_line_qupl' => 'Bladsy "$1", peiling "$2": $3', |
| 187 | + 'qp_results_line_qpl' => 'Bladsy "$1", peiling "$2": $3, $4, $5, $6', |
| 188 | + 'qp_header_line_qpul' => '$1 [ bladsy "$2", peiling "$3" ]', |
| 189 | + 'qp_export_to_xls' => 'Eksporteer statistieke na XLS-formaat', |
| 190 | + 'qp_users_answered_questions' => '$1 {{PLURAL:$1|gebruiker|gebruikers}} het die vraag beantwoord', |
| 191 | + 'qp_func_no_such_poll' => 'Die peiling bestaan nie ($1)', |
| 192 | + 'qp_func_missing_question_id' => "Verskaf asseblief 'n vraag-ID (begin by 1) vir die peiling $1", |
| 193 | + 'qp_func_invalid_question_id' => "Ongeldige vraag-ID ($2 - nie 'n getal nie) vir die peiling $1", |
| 194 | + 'qp_func_missing_proposal_id' => "Verskaf asseblief 'n voorstel-ID (begin by 0) vir die peiling $1, vraag $2", |
| 195 | + 'qp_func_invalid_proposal_id' => "Ongeldige voorstel-ID ($3 - nie 'n getal nie) vir die peiling $1, vraag $2", |
| 196 | + 'qp_error_no_such_poll' => 'Die peiling bestaan nie ($1). |
| 197 | +Sorg dat die peiling opgestel en gestoor is, en dat "#" as skeidingskarakter in die adres gebruik word.', |
| 198 | + 'qp_error_id_in_stats_mode' => "Dit is nie moontlik om 'n ID vir die peiling in die statistiese modus te verklaar nie", |
| 199 | + 'qp_error_dependance_in_stats_mode' => "Dit is nie moontlik om 'n afhanklikheid-ketting vir die peiling in die statistiese modus te verklaar nie", |
| 200 | + 'qp_error_no_stats' => 'Daar is geen statistiese data beskikbaar nie omdat nog geen gebruikers in hierdie peiling gestem het nie (adres $1)', |
| 201 | + 'qp_error_address_in_decl_mode' => "Dit is nie moontlik om 'n adres van die peiling in die verklaar-modus aan te vra nie.", |
| 202 | + 'qp_error_question_not_implemented' => 'Vrae van die tipe is nie geïmplementeer nie: $1', |
| 203 | + 'qp_error_invalid_question_type' => 'Ongeldige vraagtipe: $1', |
| 204 | + 'qp_error_type_in_stats_mode' => 'Die vraagtipe kan nie in die statistiese vertoon-modus gedefinieer word nie: $1', |
| 205 | + 'qp_error_no_poll_id' => 'Die eienskap "id" is nie vir die peiling gedefinieer nie.', |
| 206 | + 'qp_error_invalid_poll_id' => 'Ongeldig peiling-ID ($1). |
| 207 | +Die ID mag slegs letters, syfers en spasies bevat.', |
| 208 | + 'qp_error_already_used_poll_id' => 'Die peilingsnommer word al reeds op hierdie bladsy gebruik (ID $1)', |
| 209 | + 'qp_error_invalid_dependance_value' => 'Die peiling se afhanklikheid-ketting (ID $1) het \'n ongeldige waarde vir die afhanklikheid-eienskap (dependance "$2")', |
| 210 | + 'qp_error_missed_dependance_title' => 'Die peiling (ID $1) is afhanklik van \'n ander peiling (ID $3) op bladsy [[$2]], maar die bladsy [[$2]] bestaan nie. |
| 211 | +Verwyder die eienskap "dependance" of plaas die bladsy [[$2]] terug.', |
| 212 | + 'qp_error_missed_dependance_poll' => 'Die peiling (ID $1) is afhanklik van \'n ander peiling (ID $3) op bladsy $2, maar die peiling bestaan nie of is nog nie geskep nie. |
| 213 | +Verwyder die eienskap "dependance" of skep \'n peiling met ID $3 op bladsy $2. |
| 214 | +Om \'n peiling te stoor, stuur dit sonder dat enig voorstel beantwoord word.', |
| 215 | + 'qp_error_vote_dependance_poll' => 'Stem asseblief eers in die peiling $1.', |
| 216 | + 'qp_error_too_many_spans' => 'Daar is te veel kategorieklasse vir die subkategorieë gedefinieer', |
| 217 | + 'qp_error_unanswered_span' => 'Onbeantwoorde subkategorie', |
| 218 | + 'qp_error_non_unique_choice' => "Hierdie vraag vereis 'n unieke voorstel-antwoord", |
| 219 | + 'qp_error_category_name_empty' => 'Kategorie se naam is leeg', |
| 220 | + 'qp_error_proposal_text_empty' => 'Geen voorstelteks is verskaf nie', |
| 221 | + 'qp_error_too_few_categories' => 'Ten minste twee kategorieë moet gedefinieer word', |
| 222 | + 'qp_error_too_few_spans' => 'Vir elke kategorieklas moet daar ten minste twee moontlike antwoorde gedefinieerd wees', |
| 223 | + 'qp_error_no_answer' => 'Onbeantwoorde voorstel', |
| 224 | + 'qp_error_unique' => 'Vir die vraag van die tipe unique() is daar meer voorstelle as moontlike antwoorde gedefinieer. Dit is nie reg voorberei nie.', |
| 225 | +); |
| 226 | + |
| 227 | +/** Gheg Albanian (Gegë) |
| 228 | + * @author Mdupont |
| 229 | + */ |
| 230 | +$messages['aln'] = array( |
| 231 | + 'qp_votes_count' => '$1 {{PLURAL:$1|votuar|vota}}', |
| 232 | + 'qp_source_link' => 'Burim', |
| 233 | + 'qp_stats_link' => 'Statistika', |
| 234 | + 'qp_users_link' => 'Përdorues', |
| 235 | + 'qp_voice_link' => 'zëri i përdoruesit', |
| 236 | + 'qp_voice_link_inv' => 'zë User?', |
| 237 | + 'qp_user_polls_link' => 'Marrë pjesë në $1 {{PLURAL:$1|sondazhi|Sondazhet}}', |
| 238 | + 'qp_user_missing_polls_link' => 'Nuk ka pjesëmarrje', |
| 239 | + 'qp_not_participated_link' => 'Nuk ka marrë pjesë', |
| 240 | + 'qp_order_by_username' => 'Rendit nga username', |
| 241 | + 'qp_order_by_polls_count' => 'Rendit nga sondazhet numërimin e', |
| 242 | + 'qp_results_line_qupl' => 'Faqja "$1" Hulumtimi i opinionit publik "$2": $3', |
| 243 | + 'qp_results_line_qpl' => 'Faqja "$1" Hulumtimi i opinionit publik "$2": $3, $4, $5, $6', |
| 244 | + 'qp_header_line_qpul' => '$1 [ Faqja "$2" Hulumtimi i opinionit publik "$3"]', |
| 245 | + 'qp_export_to_xls' => 'Statistikat e eksportit në formatin XLS', |
| 246 | + 'qp_users_answered_questions' => '$1 {{PLURAL:$1|përdorues|përdorues}} përgjigjur në pyetjet', |
| 247 | + 'qp_func_no_such_poll' => 'Asnjë sondazh i tillë ($1)', |
| 248 | + 'qp_func_missing_question_id' => 'Ju lutem specifikoni një pyetje id ekzistuese (duke filluar nga 1) për sondazhi i $1', |
| 249 | + 'qp_func_invalid_question_id' => 'pyetje e pavlefshme id = $2 (nuk një numër) për sondazhi i $1', |
| 250 | + 'qp_func_missing_proposal_id' => 'Ju lutem specifikoni një propozim id ekzistuese (duke filluar nga 0) për votimin e pyetjes $1, $2', |
| 251 | + 'qp_func_invalid_proposal_id' => 'propozimin e pavlefshme id = $3 nuk (një numër) për votimin e pyetjes $1, $2', |
| 252 | + 'qp_error_no_such_poll' => 'Asnjë sondazh i tillë ($1). Sigurohuni që sondazhi i deklaruar dhe ruhet, gjithashtu të jetë e sigurtë për të përdorur karakter adresën Kufi #', |
| 253 | + 'qp_error_in_question_header' => 'Fillim i pavlefshëm pyetje: $1', |
| 254 | + 'qp_error_id_in_stats_mode' => 'Nuk mund të deklarojë një ID të anketës në mënyrë statistikore', |
| 255 | + 'qp_error_dependance_in_stats_mode' => 'Nuk mund të deklaroj zinxhir dependance e anketës në mënyrë statistikore', |
| 256 | + 'qp_error_no_stats' => 'Nuk ka të dhëna statistikore është në dispozicion, sepse askush nuk ka votuar për këtë sondazh, por (adresa = $1)', |
| 257 | + 'qp_error_address_in_decl_mode' => 'Nuk mund të merrni një adresë e anketës në deklaratë mode', |
| 258 | + 'qp_error_question_not_implemented' => 'Pyetjet e tipit të tillë nuk janë zbatuar: $1', |
| 259 | + 'qp_error_invalid_question_type' => 'Lloj i pavlefshëm pyetje: $1', |
| 260 | + 'qp_error_type_in_stats_mode' => 'Lloji i Pyetja nuk mund të përcaktohet në mënyrë të shfaqur statistikore: $1', |
| 261 | + 'qp_error_no_poll_id' => 'tag Anketa id ka asnjë atribut të përcaktuar.', |
| 262 | + 'qp_error_invalid_poll_id' => 'Sondazhi id pavlefshme (id = $1). id Anketa mund të përmbajë vetëm shkronja, numra dhe karakterin hapësirë', |
| 263 | + 'qp_error_already_used_poll_id' => 'Id sondazh është tashmë të përdorura në këtë faqe (id = $1).', |
| 264 | + 'qp_error_invalid_dependance_value' => 'Anketa (id = 1 $) zinxhirit të dependance ka vlerë të pavlefshme e vetive dependance (dependance = "$2")', |
| 265 | + 'qp_error_missed_dependance_title' => 'Anketa (id = $1) është i varur nga anketa e një tjetër (id = $3) nga faqja [[$2]], por titullin [[$2]] nuk u gjet. |
| 266 | +Ose hequr atribut dependance, ose rivendosjen e [[$2]]', |
| 267 | + 'qp_error_missed_dependance_poll' => 'Anketa (id = $1) është i varur nga anketa e një tjetër (id = $3) në faqe $2, por se sondazhi nuk ekziston ose nuk është ruajtur akoma. Ose hequr atribut dependance, apo krijimi i anketës me id = $3 në faqe $2 dhe për të shpëtuar atë. Për të ruajtur një sondazh, i jepni kohë nuk iu përgjigjur ndonjë pyetje propozim.', |
| 268 | + 'qp_error_vote_dependance_poll' => 'Ju lutemi të votojnë për sondazh $1 të parë.', |
| 269 | + 'qp_error_too_many_spans' => 'Shumë grupe të kategorisë së për numrin e përgjithshëm të nën-kategori të përcaktuara', |
| 270 | + 'qp_error_unanswered_span' => 'nënkategori pa përgjigje', |
| 271 | + 'qp_error_non_unique_choice' => 'Kjo pyetje kërkon përgjigje unike propozim', |
| 272 | + 'qp_error_category_name_empty' => 'Emri Kategoria është e zbrazët', |
| 273 | + 'qp_error_proposal_text_empty' => 'tekstit Propozimi është e zbrazët', |
| 274 | + 'qp_error_too_few_categories' => 'Së paku dy kategori duhet të përcaktohet', |
| 275 | + 'qp_error_too_few_spans' => 'Çdo grup kategori Duhet të përmbajë të paktën dy nën-kategori', |
| 276 | + 'qp_error_no_answer' => 'propozim pa përgjigje', |
| 277 | + 'qp_error_unique' => 'Pyetje të tipit () ka unike propozimet më shumë se përgjigje të mundshme të përcaktuara: e pamundur për të kompletuar', |
| 278 | +); |
| 279 | + |
| 280 | +/** Arabic (العربية) |
| 281 | + * @author Meno25 |
| 282 | + * @author OsamaK |
| 283 | + */ |
| 284 | +$messages['ar'] = array( |
| 285 | + 'pollresults' => 'نتائج الاستقصاءات في هذا الموقع', |
| 286 | + 'qp_desc' => 'يسمح بإنشاء اقتراعات', |
| 287 | + 'qp_desc-sp' => '[[Special:PollResults|صفحة خاصة]] لرؤية نتائج الاقتراعات', |
| 288 | + 'qp_result_NA' => 'غير مجاب عنه', |
| 289 | + 'qp_result_error' => 'خطأ صياغة', |
| 290 | + 'qp_vote_button' => 'تصويت', |
| 291 | + 'qp_vote_again_button' => 'غير صوتك', |
| 292 | + 'qp_polls_list' => 'عرض كل الاقتراعات', |
| 293 | + 'qp_users_list' => 'عرض كل المستخدمين', |
| 294 | + 'qp_browse_to_poll' => 'اذهب إلى $1', |
| 295 | + 'qp_browse_to_user' => 'اذهب إلى $1', |
| 296 | + 'qp_votes_count' => '$1 {{PLURAL:$1|صوت|أصوات}}', |
| 297 | + 'qp_source_link' => 'مصدر', |
| 298 | + 'qp_stats_link' => 'إحصاءات', |
| 299 | + 'qp_users_link' => 'مستخدمون', |
| 300 | + 'qp_voice_link' => 'صوت المستخدم', |
| 301 | + 'qp_voice_link_inv' => 'صوت المستخدم؟', |
| 302 | + 'qp_user_polls_link' => 'شارك في $1 {{PLURAL:$1|اقتراع|اقتراعات}}', |
| 303 | + 'qp_user_missing_polls_link' => 'لا مشاركة', |
| 304 | + 'qp_not_participated_link' => 'لم يشارك', |
| 305 | + 'qp_order_by_username' => 'رتب حسب اسم المستخدم', |
| 306 | + 'qp_order_by_polls_count' => 'رتب حسب عداد الاقتراعات', |
| 307 | + 'qp_results_line_qupl' => 'الصفحة "$1" الاقتراع "$2": $3', |
| 308 | + 'qp_results_line_qpl' => 'الصفحة "$1" الاقتراع "$2": $3, $4, $5, $6', |
| 309 | + 'qp_header_line_qpul' => '$1 [ الصفحة "$2" الاقتراع "$3" ]', |
| 310 | + 'qp_export_to_xls' => 'صدر الإحصاءات بصيغة XLS', |
| 311 | + 'qp_users_answered_questions' => '$1 {{PLURAL:$1|مستخدم|مستخدم}} أجاب على الأسئلة', |
| 312 | + 'qp_func_no_such_poll' => 'لا استطلاع كهذا ($1)', |
| 313 | + 'qp_func_missing_question_id' => 'من فضلك حدد رقم سؤال موجود (بدءا من 1) للاقتراع $1', |
| 314 | + 'qp_func_invalid_question_id' => 'سؤال غير صحيح id=$2 (ليس رقما) للاقتراع $1', |
| 315 | + 'qp_func_missing_proposal_id' => 'من فضلك حدد رقم اقتراح موجود (بدءا من 0) للاقتراع $1, السؤال $2', |
| 316 | + 'qp_func_invalid_proposal_id' => 'عرض غير صحيح id=$3 (ليس رقما) للاقتراع $1, السؤال $2', |
| 317 | + 'qp_error_no_such_poll' => 'لا اقتراع كهذا ($1). |
| 318 | +تأكد من أن الاقتراع معلن عنه ومحفوظ، وتأكد أيضا من استخدام حرف فصل العنوان #', |
| 319 | + 'qp_error_id_in_stats_mode' => 'لا يمكن إعلان رقم للاقتراع في نمط الإحصاءات', |
| 320 | + 'qp_error_dependance_in_stats_mode' => 'لا يمكن الإعلان عن سلسلة اعتماد الاقتراع في نمط الإحصاءات', |
| 321 | + 'qp_error_no_stats' => 'لا بيانات إحصائية متوفرة، لأنه لا أحد صوت في هذا الاقتراع بعد (address=$1)', |
| 322 | + 'qp_error_address_in_decl_mode' => 'لا يمكن الحصول على عنوان في نمط الإعلان', |
| 323 | + 'qp_error_question_not_implemented' => 'الأسئلة من هذا النوع غير مطبقة: $1', |
| 324 | + 'qp_error_invalid_question_type' => 'نوع سؤال غير صالح: $1', |
| 325 | + 'qp_error_type_in_stats_mode' => 'نوع السؤال لا يمكن تعريفه في نمط العرض الإحصائي: $1', |
| 326 | + 'qp_error_no_poll_id' => 'وسم الاقتراع ليس به معرف رقم محدد.', |
| 327 | + 'qp_error_invalid_poll_id' => 'رقم اقتراع غير صحيح (id=$1). |
| 328 | +رقم الاقتراع يمكن ان يحتوي فقط على حروف، أرقام وحرف الفراغ', |
| 329 | + 'qp_error_already_used_poll_id' => 'رقم الاقتراع تم استخدامه بالفعل في هذه الصفحة (id=$1).', |
| 330 | + 'qp_error_invalid_dependance_value' => 'سلسة اعتماد الاقتراع (id=$1) بها قيمة غير صحيحة لمحدد الاعتماد (dependance="$2")', |
| 331 | + 'qp_error_missed_dependance_title' => 'الاقتراع (id=$1) معتمد على اقتراع آخر (id=$3) من الصفحة [[$2]]، لكن العنوان [[$2]] لم يتم العثور عليه. |
| 332 | +إما أن تزيل محدد الاعتماد، أو تسترجع [[$2]]', |
| 333 | + 'qp_error_missed_dependance_poll' => 'الاقتراع (id=$1) معتمد على اقتراع آخر (id=$3) في الصفحة $2، لكن هذا الاقتراع غير موجود أو لم يتم حفظه بعد. |
| 334 | +إما أن تزيل محدد الاعتماد، أو تنشئ الاقتراع بالرقم id=$3 في الصفحة $2 وتحفظه. |
| 335 | +لحفظ اقتراع، نفذه مع عدم الإجابة على أي أسئلة مطروحة.', |
| 336 | + 'qp_error_vote_dependance_poll' => 'من فضلك صوت للاقتراع $1 أولا.', |
| 337 | + 'qp_error_too_many_spans' => 'عدد كبير من مجموعات التصنيفات للعدد الإجمالي المعرف من التصنيفات الفرعية', |
| 338 | + 'qp_error_unanswered_span' => 'تصنيف فرعي غير مجاب عليه', |
| 339 | + 'qp_error_non_unique_choice' => 'يجب أن يتوفر للسؤال إجابة مُقترحة فريدة', |
| 340 | + 'qp_error_category_name_empty' => 'اسم التصنيف فارغ', |
| 341 | + 'qp_error_proposal_text_empty' => 'نص الاقتراح فارغ', |
| 342 | + 'qp_error_too_few_categories' => 'يجب أن تُعرّف تصنيفين على الأقل', |
| 343 | + 'qp_error_too_few_spans' => 'كل مجموعة تصنيف يجب أن تحتوي على الأقل على تصنيفين فرعيين', |
| 344 | + 'qp_error_no_answer' => 'اقتراح غير مجاب عليه', |
| 345 | + 'qp_error_unique' => 'السؤال من نوع unique() لديه اقتراحات أكثر من الأجوبة المحتملة المعرفة: مستحيل الإكمال', |
| 346 | +); |
| 347 | + |
| 348 | +/** Aramaic (ܐܪܡܝܐ) |
| 349 | + * @author 334a |
| 350 | + * @author Basharh |
| 351 | + * @author Michaelovic |
| 352 | + */ |
| 353 | +$messages['arc'] = array( |
| 354 | + 'qp_vote_button' => 'ܝܗܒ ܩܠܐ', |
| 355 | + 'qp_users_list' => 'ܚܘܝ ܟܠ ܡܦܠܚܢ̈ܐ', |
| 356 | + 'qp_browse_to_poll' => 'ܙܠ ܠ $1', |
| 357 | + 'qp_browse_to_user' => 'ܙܠ ܠ $1', |
| 358 | + 'qp_votes_count' => '$1 {{PLURAL:$1|ܩܠܐ|ܩܠ̈ܐ}}', |
| 359 | + 'qp_source_link' => 'ܡܒܘܥܐ', |
| 360 | + 'qp_users_link' => 'ܡܦܠܚܢ̈ܐ', |
| 361 | + 'qp_voice_link' => 'ܩܠܐ ܕܡܦܠܚܢܐ', |
| 362 | + 'qp_voice_link_inv' => 'ܡܦܠܚܢܐ ܝܗܒ ܩܠܐ؟', |
| 363 | + 'qp_error_category_name_empty' => 'ܫܡܐ ܕܣܕܪܐ ܣܦܝܩܐ ܗܘ', |
| 364 | +); |
| 365 | + |
| 366 | +/** Egyptian Spoken Arabic (مصرى) |
| 367 | + * @author Meno25 |
| 368 | + */ |
| 369 | +$messages['arz'] = array( |
| 370 | + 'pollresults' => 'نتائج الاستقصاءات فى هذا الموقع', |
| 371 | + 'qp_desc' => 'يسمح بإنشاء اقتراعات', |
| 372 | + 'qp_desc-sp' => '[[Special:PollResults|صفحه خاصة]] لرؤيه نتائج الاقتراعات', |
| 373 | + 'qp_result_NA' => 'غير مجاب عنه', |
| 374 | + 'qp_result_error' => 'خطأ صياغة', |
| 375 | + 'qp_vote_button' => 'تصويت', |
| 376 | + 'qp_vote_again_button' => 'غير صوتك', |
| 377 | + 'qp_polls_list' => 'عرض كل الاقتراعات', |
| 378 | + 'qp_users_list' => 'عرض كل المستخدمين', |
| 379 | + 'qp_browse_to_poll' => 'اذهب إلى $1', |
| 380 | + 'qp_browse_to_user' => 'اذهب إلى $1', |
| 381 | + 'qp_votes_count' => '$1 {{PLURAL:$1|صوت|أصوات}}', |
| 382 | + 'qp_source_link' => 'مصدر', |
| 383 | + 'qp_stats_link' => 'إحصاءات', |
| 384 | + 'qp_users_link' => 'مستخدمون', |
| 385 | + 'qp_voice_link' => 'صوت المستخدم', |
| 386 | + 'qp_voice_link_inv' => 'صوت المستخدم؟', |
| 387 | + 'qp_user_polls_link' => 'شارك فى $1 {{PLURAL:$1|اقتراع|اقتراعات}}', |
| 388 | + 'qp_user_missing_polls_link' => 'لا مشاركة', |
| 389 | + 'qp_not_participated_link' => 'لم يشارك', |
| 390 | + 'qp_order_by_username' => 'رتب حسب اسم المستخدم', |
| 391 | + 'qp_order_by_polls_count' => 'رتب حسب عداد الاقتراعات', |
| 392 | + 'qp_results_line_qupl' => 'الصفحه "$1" الاقتراع "$2": $3', |
| 393 | + 'qp_results_line_qpl' => 'الصفحه "$1" الاقتراع "$2": $3, $4, $5, $6', |
| 394 | + 'qp_header_line_qpul' => '$1 [ الصفحه "$2" الاقتراع "$3" ]', |
| 395 | + 'qp_export_to_xls' => 'صدر الإحصاءات بصيغه XLS', |
| 396 | + 'qp_users_answered_questions' => '$1 {{PLURAL:$1|مستخدم|مستخدم}} أجاب على الأسئلة', |
| 397 | + 'qp_func_no_such_poll' => 'لا استطلاع كهذا ($1)', |
| 398 | + 'qp_func_missing_question_id' => 'من فضلك حدد رقم سؤال موجود (بدءا من 1) للاقتراع $1', |
| 399 | + 'qp_func_invalid_question_id' => 'سؤال غير صحيح id=$2 (ليس رقما) للاقتراع $1', |
| 400 | + 'qp_func_missing_proposal_id' => 'من فضلك حدد رقم اقتراح موجود (بدءا من 0) للاقتراع $1, السؤال $2', |
| 401 | + 'qp_func_invalid_proposal_id' => 'عرض غير صحيح id=$3 (ليس رقما) للاقتراع $1, السؤال $2', |
| 402 | + 'qp_error_no_such_poll' => 'لا اقتراع كهذا ($1). |
| 403 | +تأكد من أن الاقتراع معلن عنه ومحفوظ، وتأكد أيضا من استخدام حرف فصل العنوان #', |
| 404 | + 'qp_error_id_in_stats_mode' => 'لا يمكن إعلان رقم للاقتراع فى نمط الإحصاءات', |
| 405 | + 'qp_error_dependance_in_stats_mode' => 'لا يمكن الإعلان عن سلسله اعتماد الاقتراع فى نمط الإحصاءات', |
| 406 | + 'qp_error_no_stats' => 'لا بيانات إحصائيه متوفره، لأنه لا أحد صوت فى هذا الاقتراع بعد (address=$1)', |
| 407 | + 'qp_error_address_in_decl_mode' => 'لا يمكن الحصول على عنوان فى نمط الإعلان', |
| 408 | + 'qp_error_question_not_implemented' => 'الأسئله من هذا النوع غير مطبقة: $1', |
| 409 | + 'qp_error_invalid_question_type' => 'نوع سؤال غير صالح: $1', |
| 410 | + 'qp_error_type_in_stats_mode' => 'نوع السؤال لا يمكن تعريفه فى نمط العرض الإحصائي: $1', |
| 411 | + 'qp_error_no_poll_id' => 'وسم الاقتراع ليس به معرف رقم محدد.', |
| 412 | + 'qp_error_invalid_poll_id' => 'رقم اقتراع غير صحيح (id=$1). |
| 413 | +رقم الاقتراع يمكن ان يحتوى فقط على حروف، أرقام وحرف الفراغ', |
| 414 | + 'qp_error_already_used_poll_id' => 'رقم الاقتراع تم استخدامه بالفعل فى هذه الصفحه (id=$1).', |
| 415 | + 'qp_error_invalid_dependance_value' => 'سلسه اعتماد الاقتراع (id=$1) بها قيمه غير صحيحه لمحدد الاعتماد (dependance="$2")', |
| 416 | + 'qp_error_missed_dependance_title' => 'الاقتراع (id=$1) معتمد على اقتراع آخر (id=$3) من الصفحه [[$2]]، لكن العنوان [[$2]] لم يتم العثور عليه. |
| 417 | +إما أن تزيل محدد الاعتماد، أو تسترجع [[$2]]', |
| 418 | + 'qp_error_missed_dependance_poll' => 'الاقتراع (id=$1) معتمد على اقتراع آخر (id=$3) فى الصفحه $2، لكن هذا الاقتراع غير موجود أو لم يتم حفظه بعد. |
| 419 | +إما أن تزيل محدد الاعتماد، أو تنشئ الاقتراع بالرقم id=$3 فى الصفحه $2 وتحفظه. |
| 420 | +لحفظ اقتراع، نفذه مع عدم الإجابه على أى أسئله مطروحه.', |
| 421 | + 'qp_error_vote_dependance_poll' => 'من فضلك صوت للاقتراع $1 أولا.', |
| 422 | + 'qp_error_too_many_spans' => 'عدد كبير من مجموعات التصنيفات للعدد الإجمالى المعرف من التصنيفات الفرعية', |
| 423 | + 'qp_error_unanswered_span' => 'تصنيف فرعى غير مجاب عليه', |
| 424 | + 'qp_error_non_unique_choice' => 'يجب أن يتوفر للسؤال إجابه مُقترحه فريدة', |
| 425 | + 'qp_error_category_name_empty' => 'اسم التصنيف فارغ', |
| 426 | + 'qp_error_proposal_text_empty' => 'نص الاقتراح فارغ', |
| 427 | + 'qp_error_too_few_categories' => 'يجب أن تُعرّف تصنيفين على الأقل', |
| 428 | + 'qp_error_too_few_spans' => 'كل مجموعه تصنيف يجب أن تحتوى على الأقل على تصنيفين فرعيين', |
| 429 | + 'qp_error_no_answer' => 'اقتراح غير مجاب عليه', |
| 430 | + 'qp_error_unique' => 'السؤال من نوع unique() لديه اقتراحات أكثر من الأجوبه المحتمله المعرفة: مستحيل الإكمال', |
| 431 | +); |
| 432 | + |
| 433 | +/** Azerbaijani (Azərbaycanca) |
| 434 | + * @author Cekli829 |
| 435 | + */ |
| 436 | +$messages['az'] = array( |
| 437 | + 'qp_users_link' => 'İstifadəçilər', |
| 438 | +); |
| 439 | + |
| 440 | +/** Belarusian (Беларуская) |
| 441 | + * @author Тест |
| 442 | + */ |
| 443 | +$messages['be'] = array( |
| 444 | + 'qp_stats_link' => 'Статыстыка', |
| 445 | +); |
| 446 | + |
| 447 | +/** Belarusian (Taraškievica orthography) (Беларуская (тарашкевіца)) |
| 448 | + * @author EugeneZelenko |
| 449 | + * @author Jim-by |
| 450 | + */ |
| 451 | +$messages['be-tarask'] = array( |
| 452 | + 'pollresults' => 'Вынікі апытаньняў на гэтым сайце', |
| 453 | + 'qp_desc' => 'Дазваляе стварэньне апытаньняў', |
| 454 | + 'qp_desc-sp' => '[[Special:PollResults|Спэцыяльная старонка]] для прагляду вынікаў апытаньняў', |
| 455 | + 'qp_result_NA' => 'Няма адказу', |
| 456 | + 'qp_result_error' => 'Сынтаксычная памылка', |
| 457 | + 'qp_vote_button' => 'Прагаласаваць', |
| 458 | + 'qp_vote_again_button' => 'Зьмяніць Ваш голас', |
| 459 | + 'qp_polls_list' => 'Сьпіс усіх апытаньняў', |
| 460 | + 'qp_users_list' => 'Сьпіс усіх удзельнікаў', |
| 461 | + 'qp_browse_to_poll' => 'Перайсьці да $1', |
| 462 | + 'qp_browse_to_user' => 'Перайсьці да $1', |
| 463 | + 'qp_votes_count' => '$1 {{PLURAL:$1|голас|галасы|галасоў}}', |
| 464 | + 'qp_source_link' => 'Крыніца', |
| 465 | + 'qp_stats_link' => 'Статыстыка', |
| 466 | + 'qp_users_link' => 'Удзельнікі', |
| 467 | + 'qp_voice_link' => 'Голас удзельніка', |
| 468 | + 'qp_voice_link_inv' => 'Голас удзельніка?', |
| 469 | + 'qp_user_polls_link' => '{{GENDER:$2|Удзельнічаў|Удзельнічала}} у $1 {{PLURAL:$1|апытаньні|апытаньнях|апытаньнях}}', |
| 470 | + 'qp_user_missing_polls_link' => 'Не {{GENDER:$1|ўдзельнічаў|ўдзельнічала}}', |
| 471 | + 'qp_not_participated_link' => 'Сьпіс не прыняўшых удзел', |
| 472 | + 'qp_order_by_username' => 'Сартаваць па імені ўдзельніка', |
| 473 | + 'qp_order_by_polls_count' => 'Сартаваць па колькасьці апытаньняў', |
| 474 | + 'qp_results_line_qupl' => 'Старонка «$1» Апытаньне «$2»: $3', |
| 475 | + 'qp_results_line_qpl' => 'Старонка «$1» Апытаньне «$2»: $3, $4, $5, $6', |
| 476 | + 'qp_header_line_qpul' => '$1 [ Старонка «$2» Апытаньне «$3» ]', |
| 477 | + 'qp_export_to_xls' => 'Экспартаваць статыстыку ў фармат XLS', |
| 478 | + 'qp_voices_to_xls' => 'Экспартаваць галасы ў фармат XLS', |
| 479 | + 'qp_users_answered_questions' => 'На пытаньні {{PLURAL:$1|адказаў $1 удзельнік|адказалі $1 удзельнікі|адказалі $1 удзельнікаў}}', |
| 480 | + 'qp_func_no_such_poll' => 'Няма такога апытаньня ($1)', |
| 481 | + 'qp_func_missing_question_id' => 'Калі ласка, пазначце ідэнтыфікатар існуючага пытаньня (пачынаючы з 1) для апытаньня $1', |
| 482 | + 'qp_func_invalid_question_id' => 'Няслушны ідэнтыфікатар апытаньня=$2 (ня лік) для апытаньня $1', |
| 483 | + 'qp_func_missing_proposal_id' => 'Калі ласка, пазначце існуючы ідэнтыфікатар (пачынаючы з 0) для апытаньня $1, пытаньня $2', |
| 484 | + 'qp_func_invalid_proposal_id' => 'Няслушны ідэнтыфікатар=$3 (ня лік) для апытаньня $1, пытаньня $2', |
| 485 | + 'qp_error_no_such_poll' => 'Няма такога апытаньня ($1). |
| 486 | +Упэўніцеся што апытаньне вызначанае і захаванае, а таксама, што выкарыстоўваецца сымбаль падзелу адрасу #', |
| 487 | + 'qp_error_in_question_header' => 'Няслушны загаловак пытаньня: $1', |
| 488 | + 'qp_error_id_in_stats_mode' => 'Немагчыма вызначаць ідэнтыфікатар апытаньня ў статыстычным рэжыме', |
| 489 | + 'qp_error_dependance_in_stats_mode' => 'Немагчыма вызначаць залежную пасьлядоўнасьць апытаньня ў статыстычным рэжыме', |
| 490 | + 'qp_error_no_stats' => 'Няма статыстычных зьвестак, таму што ніхто яшчэ не падаў голас у гэтым апытаньні (адрас=$1)', |
| 491 | + 'qp_error_address_in_decl_mode' => 'Немагчыма атрымаць адрас апытаньня ў рэжыме вызначэньня', |
| 492 | + 'qp_error_question_not_implemented' => 'Пытаньні гэтага тыпу не рэалізаваныя: $1', |
| 493 | + 'qp_error_invalid_question_type' => 'Няслушны тып пытаньня: $1', |
| 494 | + 'qp_error_type_in_stats_mode' => 'Немагчыма вызначыць тып пытаньня ў статыстычным рэжыме: $1', |
| 495 | + 'qp_error_no_poll_id' => 'Тэг апытаньня ня мае атрыбута ідэнтыфікацыі.', |
| 496 | + 'qp_error_invalid_poll_id' => 'Няслушны ідэнтыфікатар апытаньня (id=$1). |
| 497 | +Ідэнтыфікатар апытаньня можа ўтрымліваць толькі літары, лічбы і сымбаль прагалу', |
| 498 | + 'qp_error_already_used_poll_id' => 'Ідэнтыфікатар апытаньня ўжо быў выкарыстаны на гэтай старонцы (id=$1).', |
| 499 | + 'qp_error_invalid_dependance_value' => 'У ланцугу залежнасьці апытаньня (id=$1) існуе няслушнае значэньне атрыбуту залежнасьці (dependance="$2")', |
| 500 | + 'qp_error_missed_dependance_title' => 'Апытаньне (id=$1) залежыць ад іншага апытаньня (id=$3) са старонкі [[$2]], але назва [[$2]] не была знойдзеная. |
| 501 | +Неабходна выдаліць атрыбут залежнасьці ці аднавіць [[$2]]', |
| 502 | + 'qp_error_missed_dependance_poll' => 'Апытаньне (id=$1) залежыць ад іншага апытаньня (id=$3) на старонцы $2, але гэта апытаньне не існуе ці яшчэ не было захаванае. |
| 503 | +Неабходна выдаліць атрыбут залежнасьці альбо стварыць апытаньне з ідэнтыфікатарам id=$3 на старонцы $2 і яго захаваць. Каб захаваць апытаньне можна націснуць кнопку «Прагаласаваць», не адказваючы на пытаньні.', |
| 504 | + 'qp_error_vote_dependance_poll' => 'Калі ласка, спачатку прыміце ўдзел у апытаньні $1.', |
| 505 | + 'qp_error_too_many_spans' => 'Вызначана зашмат клясаў катэгорыяў для падкатэгорыяў', |
| 506 | + 'qp_error_unanswered_span' => 'Падкатэгорыя без адказу', |
| 507 | + 'qp_error_non_unique_choice' => 'Гэта пытаньне патрабуе, каб варыянт адказу не выкарыстоўваўся раней', |
| 508 | + 'qp_error_category_name_empty' => 'Пустая назва катэгорыі', |
| 509 | + 'qp_error_proposal_text_empty' => 'Прапанаваны тэкст — пусты', |
| 510 | + 'qp_error_too_few_categories' => 'Павінны быць вызначаныя хаця б дзьве катэгорыі', |
| 511 | + 'qp_error_too_few_spans' => 'Кожная кляса катэгорыі патрабуе хаця б два варыянты адказу', |
| 512 | + 'qp_error_no_answer' => 'Няма адказу на пытаньне', |
| 513 | + 'qp_error_unique' => 'Пытаньне тыпу unique() мае больш адказаў чым гэта магчыма: немагчыма скончыць', |
| 514 | +); |
| 515 | + |
| 516 | +/** Bengali (বাংলা) |
| 517 | + * @author Wikitanvir |
| 518 | + */ |
| 519 | +$messages['bn'] = array( |
| 520 | + 'qp_vote_button' => 'ভোট', |
| 521 | + 'qp_vote_again_button' => 'আপনার ভোট পরিবর্তন করুন', |
| 522 | + 'qp_polls_list' => 'সকল নির্বাচন তালিকাভুক্ত করো', |
| 523 | + 'qp_source_link' => 'উৎস', |
| 524 | + 'qp_stats_link' => 'পরিসংখ্যান', |
| 525 | + 'qp_users_link' => 'ব্যবহারকারীগণ', |
| 526 | + 'qp_voice_link' => 'ব্যবহারকারীর কণ্ঠ', |
| 527 | +); |
| 528 | + |
| 529 | +/** Breton (Brezhoneg) |
| 530 | + * @author Fohanno |
| 531 | + * @author Fulup |
| 532 | + * @author Y-M D |
| 533 | + */ |
| 534 | +$messages['br'] = array( |
| 535 | + 'pollresults' => "Disoc'hoù ar sontadegoù el lec'hienn-mañ", |
| 536 | + 'qp_desc' => 'Aotren krouiñ sontadegoù', |
| 537 | + 'qp_desc-sp' => "[[Special:PollResults|Pajenn ispisial]] evit sellet ouzh disoc'hoù ar sontadegoù", |
| 538 | + 'qp_result_NA' => 'Direspont', |
| 539 | + 'qp_result_error' => 'Fazi ereadur', |
| 540 | + 'qp_vote_button' => 'Mouezhiañ', |
| 541 | + 'qp_vote_again_button' => 'Distreiñ war ho vot', |
| 542 | + 'qp_polls_list' => 'Rollañ an holl sontadegoù', |
| 543 | + 'qp_users_list' => 'Renabliñ an holl implijerien', |
| 544 | + 'qp_browse_to_poll' => 'Mont betek $1', |
| 545 | + 'qp_browse_to_user' => 'Mont betek $1', |
| 546 | + 'qp_votes_count' => '$1 {{PLURAL:$1|vot|vot}}', |
| 547 | + 'qp_source_link' => 'Mammenn', |
| 548 | + 'qp_stats_link' => 'Stadegoù', |
| 549 | + 'qp_users_link' => 'Implijerien', |
| 550 | + 'qp_voice_link' => 'Mouezh an implijer', |
| 551 | + 'qp_voice_link_inv' => 'Mouezh an implijer ?', |
| 552 | + 'qp_user_polls_link' => 'En deus kemeret perzh e $1 sontadeg{{PLURAL:$1||}}', |
| 553 | + 'qp_user_missing_polls_link' => 'Ne gemer ket perzh', |
| 554 | + 'qp_not_participated_link' => "N'en deus ket kemeret perzh", |
| 555 | + 'qp_order_by_username' => 'Urzhiañ dre anv implijer', |
| 556 | + 'qp_order_by_polls_count' => 'Urzhiañ dre an niver a sontadegoù', |
| 557 | + 'qp_results_line_qupl' => 'Pajenn "$1" Sontadeg "$2" : $3', |
| 558 | + 'qp_results_line_qpl' => 'Pajenn "$1" Sontadeg "$2" : $3, $4, $5, $6', |
| 559 | + 'qp_header_line_qpul' => '$1 [ Pajenn "$2" Votadeg "$3" ]', |
| 560 | + 'qp_export_to_xls' => "Ezporzhiañ ar stadegoù d'ar furmad XLS", |
| 561 | + 'qp_voices_to_xls' => "Ezporzhiañ ar votoù d'ar furmad XLS", |
| 562 | + 'qp_users_answered_questions' => "$1 {{PLURAL:$1|implijer|implijer}} o deus respontet d'ar goulennoù", |
| 563 | + 'qp_func_no_such_poll' => "N'eus ket eus ar votadeg-mañ ($1)", |
| 564 | + 'qp_func_missing_question_id' => "Spisait un ID evit ur goulenn zo anezhañ c'hoazh (adalek 1) evit ar sontadeg $1", |
| 565 | + 'qp_func_invalid_question_id' => 'Id direizh evit ar goulenn=$2 direizh (ket un niver) evit ar sontadeg $1', |
| 566 | + 'qp_func_missing_proposal_id' => "Spisait un ID kinnig zo anezhañ c'hoazh (adalek 0) evit ar sontadeg $1, goulenn $2", |
| 567 | + 'qp_func_invalid_proposal_id' => 'Id kinnig=$3 direizh (ket un niver) evit ar sontadeg $1, goulenn $2', |
| 568 | + 'qp_error_no_such_poll' => "N'eus ket eus ar sontadeg ($1). |
| 569 | +Bezit sur eo bet disklêriet hag enrollet ar sontadeg ha na zisoñjit ket ober gant an arouezenn bevenniñ chomlec'hioù #", |
| 570 | + 'qp_error_in_question_header' => 'Talbenn goulenn direizh : $1', |
| 571 | + 'qp_error_id_in_stats_mode' => 'Dibosupl eo diskleriañ un ID eus ar sontadeg er mod stadegoù', |
| 572 | + 'qp_error_dependance_in_stats_mode' => "Dibosupl eo diskleriañ ar chadenn amzalc'h d'ar sontadeg er mod stadegoù", |
| 573 | + 'qp_error_no_stats' => "N'eus ket a roadennoù stadegel rak den ebet n'en deus respontet d'ar sontadeg evit c'hoazh (chomlec'h=$1)", |
| 574 | + 'qp_error_address_in_decl_mode' => "N'haller ket tapout ur chomlec'h eus ar sontadeg er mod disklêriañ", |
| 575 | + 'qp_error_question_not_implemented' => "N'eo ket emplementet ar goulennoù a-seurt gant $1", |
| 576 | + 'qp_error_invalid_question_type' => 'Seurt goulenn direizh : $1', |
| 577 | + 'qp_error_type_in_stats_mode' => "N'haller ket termeniñ doare ar goulennoù er mod diskwel stadegoù : $1", |
| 578 | + 'qp_error_no_poll_id' => "N'eus ket a niverenn-anout termenet gant balizenn ar sontadeg.", |
| 579 | + 'qp_error_invalid_poll_id' => "Direizh eo an niverenn-anaout (id=$1). |
| 580 | +N'hall bezañ en niverenn-anaout nemet lizherennoù, niverennoù hag an arouezenn esaouenn", |
| 581 | + 'qp_error_already_used_poll_id' => 'Implijet eo bet choazh an niverenn-anaout sontadeg war ar bajenn (id=$1).', |
| 582 | + 'qp_error_invalid_dependance_value' => 'Direizh eo talvoudenn chadennad amzalc\'h ar sontadeg (id=$1) evit an atribut amzalc\'h (amzalc\'h="$2")', |
| 583 | + 'qp_error_missed_dependance_title' => "E dalc'h ur sontadeg all (id=$3) eus ar bajenn [[$2]] emañ ar sontadeg (i=$1), met an titl [[$2]] n'eo ket bet kavet. |
| 584 | +Diverkit an atribut amzalc'h pe assavit [[$2]]", |
| 585 | + 'qp_error_missed_dependance_poll' => "Dindan dalc'h ur sontadeg all (id=$3) war pajenn $2 emañ ar sontadeg (id=$1), met n'eus ket eus ar sontadeg-se pe n'eo ket bet enrollet c'hoazh. |
| 586 | +Tennit an atribut amzalc'h pe krouit ar sontadeg $3 war ar bajenn $2 hag enrollit anezhi. |
| 587 | +Evit enrollañ ur sontadeg, kasit anezhi ha na respontit da goulenn kinnig ebet.", |
| 588 | + 'qp_error_vote_dependance_poll' => 'Mar plij, votit evit ar sontadeg $1 da gentañ.', |
| 589 | + 'qp_error_too_many_spans' => 'Re a strolladoù rummadoù evit an niver hollek a isrummadoù termenet', |
| 590 | + 'qp_error_unanswered_span' => 'Is-rummad hep respont', |
| 591 | + 'qp_error_non_unique_choice' => 'Ar goulenn-mañ he deus ezhomm ur respont gant un dibab hepken', |
| 592 | + 'qp_error_category_name_empty' => 'Goullo eo anv ar rummad', |
| 593 | + 'qp_error_proposal_text_empty' => "Goullo eo testenn ar c'hinnig", |
| 594 | + 'qp_error_too_few_categories' => 'Daou rummad da nebeutañ a rank bezañ termenet', |
| 595 | + 'qp_error_too_few_spans' => 'Pep strollad rummad a rank bezañ ennañ daou isrummad da nebeutañ', |
| 596 | + 'qp_error_no_answer' => 'Kinnig direspont', |
| 597 | + 'qp_error_unique' => 'Re a ginnigoù zo evit ar goulenn seurt nemetañ () eget an niver a respontoù posupl termenet : dibosupl eo klokaat', |
| 598 | +); |
| 599 | + |
| 600 | +/** Bosnian (Bosanski) |
| 601 | + * @author CERminator |
| 602 | + */ |
| 603 | +$messages['bs'] = array( |
| 604 | + 'pollresults' => 'Rezultati glasanja na ovoj stranici', |
| 605 | + 'qp_desc' => 'Omogućuje pravljenje glasanja', |
| 606 | + 'qp_desc-sp' => '[[Special:PollResults|Posebna stranica]] za pregled rezultata glasanja', |
| 607 | + 'qp_result_NA' => 'Nije odgovoreno', |
| 608 | + 'qp_result_error' => 'Sintaksna greška', |
| 609 | + 'qp_vote_button' => 'Glasaj', |
| 610 | + 'qp_vote_again_button' => 'Promijeni svoj glas', |
| 611 | + 'qp_polls_list' => 'Prikaži sva glasanja', |
| 612 | + 'qp_users_list' => 'Prikaži sve korisnike', |
| 613 | + 'qp_browse_to_poll' => 'Pregledaj po $1', |
| 614 | + 'qp_browse_to_user' => 'Pregledaj po $1', |
| 615 | + 'qp_votes_count' => '$1 {{PLURAL:$1|glas|glasa|glasova}}', |
| 616 | + 'qp_source_link' => 'Izvor', |
| 617 | + 'qp_stats_link' => 'Statistika', |
| 618 | + 'qp_users_link' => 'Korisnici', |
| 619 | + 'qp_voice_link' => 'Korisnički glas', |
| 620 | + 'qp_voice_link_inv' => 'Korisnički glas?', |
| 621 | + 'qp_user_polls_link' => 'Učestvovao u $1 {{PLURAL:$1|glasanju|glasanja}}', |
| 622 | + 'qp_user_missing_polls_link' => 'Bez učešća', |
| 623 | + 'qp_not_participated_link' => 'Nije učestvovao', |
| 624 | + 'qp_order_by_username' => 'Pregled po korisničkim imenima', |
| 625 | + 'qp_order_by_polls_count' => 'Pregled po broju glasova', |
| 626 | + 'qp_results_line_qupl' => 'Stranica "$1" Anketa "$2": $3', |
| 627 | + 'qp_results_line_qpl' => 'Stranica "$1" Anketa "$2": $3, $4, $5, $6', |
| 628 | + 'qp_header_line_qpul' => '$1 [ Stranica "$2" Anketa "$3" ]', |
| 629 | + 'qp_func_no_such_poll' => 'Nema takve ankete ($1)', |
| 630 | +); |
| 631 | + |
| 632 | +/** Czech (Česky) */ |
| 633 | +$messages['cs'] = array( |
| 634 | + 'qp_source_link' => 'Zdroj', |
| 635 | + 'qp_stats_link' => 'Statistika', |
| 636 | + 'qp_users_link' => 'Uživatelé', |
| 637 | +); |
| 638 | + |
| 639 | +/** German (Deutsch) |
| 640 | + * @author Imre |
| 641 | + * @author Kghbln |
| 642 | + * @author The Evil IP address |
| 643 | + */ |
| 644 | +$messages['de'] = array( |
| 645 | + 'pollresults' => 'Abstimmungsergebnisse auf dieser Seite', |
| 646 | + 'qp_desc' => 'Ermöglicht die Erstellung von Abstimmungen', |
| 647 | + 'qp_desc-sp' => '[[Special:PollResults|Spezialseite]] zum Anzeigen von Abstimmungsergebnissen', |
| 648 | + 'qp_result_NA' => 'Nicht beantwortet', |
| 649 | + 'qp_result_error' => 'Syntaxfehler', |
| 650 | + 'qp_vote_button' => 'Abstimmen', |
| 651 | + 'qp_vote_again_button' => 'Stimme ändern', |
| 652 | + 'qp_polls_list' => 'Alle Abstimmungen auflisten', |
| 653 | + 'qp_users_list' => 'Alle Benutzer anzeigen', |
| 654 | + 'qp_browse_to_poll' => 'Nach $1 wechseln', |
| 655 | + 'qp_browse_to_user' => 'Nach $1 wechseln', |
| 656 | + 'qp_votes_count' => '$1 {{PLURAL:$1|Stimme|Stimmen}}', |
| 657 | + 'qp_source_link' => 'Quelle', |
| 658 | + 'qp_stats_link' => 'Statistik', |
| 659 | + 'qp_users_link' => 'Benutzer', |
| 660 | + 'qp_voice_link' => 'Benutzerstimme', |
| 661 | + 'qp_voice_link_inv' => 'Benutzerstimme?', |
| 662 | + 'qp_user_polls_link' => 'Hat an $1 {{PLURAL:$1|Abstimmung|Abstimmungen}} teilgenommen', |
| 663 | + 'qp_user_missing_polls_link' => 'Keine Teilnahme', |
| 664 | + 'qp_not_participated_link' => 'Nicht teilgenommen', |
| 665 | + 'qp_order_by_username' => 'Nach Benutzernamen ordnen', |
| 666 | + 'qp_order_by_polls_count' => 'Nach Abstimmungszahl ordnen', |
| 667 | + 'qp_results_line_qupl' => 'Seite „$1“ Abstimmung „$2“: $3', |
| 668 | + 'qp_results_line_qpl' => 'Seite „$1“ Abstimmung „$2“: $3, $4, $5, $6', |
| 669 | + 'qp_header_line_qpul' => '$1 [ Seite „$2“ Abstimmung „$3“ ]', |
| 670 | + 'qp_export_to_xls' => 'Statistiken in das XLS-Format exportieren', |
| 671 | + 'qp_voices_to_xls' => 'Stimmen im XLS-Format exportieren', |
| 672 | + 'qp_users_answered_questions' => '$1 {{PLURAL:$1|Benutzer|Benutzer}} haben auf die Fragen geantwortet', |
| 673 | + 'qp_func_no_such_poll' => 'Abstimmung nicht vorhanden ($1)', |
| 674 | + 'qp_func_missing_question_id' => 'Bitte lege eine existierende Frage-ID (ab 1 aufwärts) für die Abstimmung $1 fest', |
| 675 | + 'qp_func_invalid_question_id' => 'Ungültige Frage ID=$2 (keine Nummer) für die Abstimmung $1', |
| 676 | + 'qp_func_missing_proposal_id' => 'Bitte lege eine existierende Vorschlagskennung für die Abstimmung $1 fest (ab 0 aufwärts), Frage $2.', |
| 677 | + 'qp_func_invalid_proposal_id' => 'Ungültige Vorschlagskennung id=$3 (keine Nummer) für die Abstimmung $1, Frage $2', |
| 678 | + 'qp_error_no_such_poll' => 'Abstimmung nicht vorhanden ($1). |
| 679 | +Stelle sicher, dass die Abstimmung festgelegt und gespeichert ist und dass # als Trennsymbol für Adressen verwendet wird', |
| 680 | + 'qp_error_in_question_header' => 'Ungültige Bezeichnung: $1', |
| 681 | + 'qp_error_id_in_stats_mode' => 'Kann keine Kennung für diese Abstimmung im Statistik-Modus festlegen.', |
| 682 | + 'qp_error_dependance_in_stats_mode' => 'Kann Abhängigkeitskette der Abstimmung im statistischen Modus nicht festlegen', |
| 683 | + 'qp_error_no_stats' => 'Es sind keine statistischen Daten verfügbar, da noch niemand für diese Abstimmung gestimmt hat (Adresse=$1)', |
| 684 | + 'qp_error_address_in_decl_mode' => 'Kann keine Adresse der Abstimmung im Festlegungs-Modus ermitteln', |
| 685 | + 'qp_error_question_not_implemented' => 'Fragen diesen Typs sind nicht implementiert: $1', |
| 686 | + 'qp_error_invalid_question_type' => 'Ungültiger Fragetyp: $1', |
| 687 | + 'qp_error_type_in_stats_mode' => 'Der Fragetyp kann im statistischen Anzeigemodus nicht definiert werden: $1', |
| 688 | + 'qp_error_no_poll_id' => 'Für das Abstimmungs-Tag wurde keine Abstimmungskennung definiert.', |
| 689 | + 'qp_error_invalid_poll_id' => 'Ungültige Abstimmungskennung (id=$1). |
| 690 | +Abstimmungskennung darf nur Buchstaben, Zahlen und Leerstellen enthalten.', |
| 691 | + 'qp_error_already_used_poll_id' => 'Die Abstimmungskennung wurde bereits auf dieser Seite benutzt (id=$1).', |
| 692 | + 'qp_error_invalid_dependance_value' => 'Die Abhängigkeitskette der Abstimmung (id=$1) hat einen ungültigen Wert in dem Abhängigkeits-Attribut (Abhängigkeit=„$2“)', |
| 693 | + 'qp_error_missed_dependance_title' => 'Die Abstimmung (id=$1) ist abhängig von einer anderen Abstimmung (id=$3) auf der Seite [[$2]], aber der Titel [[$2]] wurde nicht gefunden. |
| 694 | +Entferne entweder die Abhängigkeits-Attribute, oder stelle [[$2]] wieder her', |
| 695 | + 'qp_error_missed_dependance_poll' => 'Die Abstimmung (id=$1) ist abhängig von einer anderen Abstimmung (id=$3) auf Seite $2, aber diese Abstimmung existiert nicht oder wurde noch nicht gespeichert. |
| 696 | +Entferne entweder die Abhängigkeits-Attribute oder erstelle die Abstimmung mit id=$3 auf Seite $2 und speichere sie. |
| 697 | +Um die Abstimmung zu speichern, übermittle sie während du nicht auf eine Antragsanfrage antwortest.', |
| 698 | + 'qp_error_vote_dependance_poll' => 'Bitte erst für $1 abstimmen.', |
| 699 | + 'qp_error_too_many_spans' => 'Zu viele Kategoriegruppen für die Gesamtzahl der Unterkategorien definiert', |
| 700 | + 'qp_error_unanswered_span' => 'Unbeantwortete Unterrubrik', |
| 701 | + 'qp_error_non_unique_choice' => 'Diese Frage benötigt eindeutige Antragsbeantwortung', |
| 702 | + 'qp_error_category_name_empty' => 'Kategoriename ist leer', |
| 703 | + 'qp_error_proposal_text_empty' => 'Vorschlagstext ist leer', |
| 704 | + 'qp_error_too_few_categories' => 'Es müssen mindestens zwei Kategorien festgelegt werden', |
| 705 | + 'qp_error_too_few_spans' => 'Jede Kategoriengruppe muss mindestens zwei Unterrubriken enthalten', |
| 706 | + 'qp_error_no_answer' => 'Unbeantworteter Vorschlag', |
| 707 | + 'qp_error_unique' => 'Die Frage des Typs unique() hat mehr Vorschläge, als mögliche Antworten definiert sind: Ausführung unmöglich', |
| 708 | +); |
| 709 | + |
| 710 | +/** German (formal address) (Deutsch (Sie-Form)) |
| 711 | + * @author Imre |
| 712 | + */ |
| 713 | +$messages['de-formal'] = array( |
| 714 | + 'qp_func_missing_question_id' => 'Bitte legen Sie eine existierende Frage-ID (ab 1 aufwärts) für die Abstimmung $1 fest', |
| 715 | + 'qp_error_no_such_poll' => 'Abstimmung nicht vorhanden ($1). |
| 716 | +Stellen Sie sicher, dass die Abstimmung festgelegt und gespeichert ist und dass # als Trennsymbol für Adressen verwendet wird', |
| 717 | + 'qp_error_missed_dependance_title' => 'Die Abstimmung (id=$1) ist abhängig von einer anderen Abstimmung (id=$3) auf der Seite [[$2]], aber der Titel [[$2]] wurde nicht gefunden. |
| 718 | +Entfernen Sie entweder die Abhängigkeits-Attribute, oder stellen Sie [[$2]] wieder her', |
| 719 | + 'qp_error_missed_dependance_poll' => 'Die Abstimmung (id=$1) ist abhängig von einer anderen Abstimmung (id=$3) auf Seite $2, aber diese Abstimmung existiert nicht oder wurde noch nicht gespeichert. |
| 720 | +Entfernen Sie entweder die Abhängigkeits-Attribute oder erstellen Sie die Abstimmung mit id=$3 auf Seite $2 und speichern Sie sie. |
| 721 | +Um die Abstimmung zu speichern, übermitteln Sie sie während Sie nicht auf eine Antragsanfrage antworten.', |
| 722 | +); |
| 723 | + |
| 724 | +/** Lower Sorbian (Dolnoserbski) |
| 725 | + * @author Michawiki |
| 726 | + */ |
| 727 | +$messages['dsb'] = array( |
| 728 | + 'pollresults' => 'Wuslědki napšašowanjow na toś tom sedle', |
| 729 | + 'qp_desc' => 'Zmóžnja napóranje napšašowanjow', |
| 730 | + 'qp_desc-sp' => '[[Special:PollResults|Specialny bok]] za woglědowanje wuslědkow napšašowanjow', |
| 731 | + 'qp_result_NA' => 'Njewótgronjony', |
| 732 | + 'qp_result_error' => 'Syntaksowa zmólka', |
| 733 | + 'qp_vote_button' => 'Wótgłosowaś', |
| 734 | + 'qp_vote_again_button' => 'Twójo wótgłosowanje změniś', |
| 735 | + 'qp_polls_list' => 'Wše napšašowanja nalicyś', |
| 736 | + 'qp_users_list' => 'Wšych wužywarjow nalicyś', |
| 737 | + 'qp_browse_to_poll' => 'Dalej k $1', |
| 738 | + 'qp_browse_to_user' => 'Dalej k $1', |
| 739 | + 'qp_votes_count' => '$1 {{PLURAL:$1|głos|głosa|głose|głosow}}', |
| 740 | + 'qp_source_link' => 'Žrědło', |
| 741 | + 'qp_stats_link' => 'Statistika', |
| 742 | + 'qp_users_link' => 'Wužywarje', |
| 743 | + 'qp_voice_link' => 'Wužywarski głos', |
| 744 | + 'qp_voice_link_inv' => 'Wužywarski głos?', |
| 745 | + 'qp_user_polls_link' => 'Jo se wobźělił na $1 {{PLURAL:$1|napšašowanju|napšašowanjoma|napšašowanjach|napšašowanjach}}', |
| 746 | + 'qp_user_missing_polls_link' => 'Žedno wobźělenje', |
| 747 | + 'qp_not_participated_link' => 'Njewobźělony', |
| 748 | + 'qp_order_by_username' => 'Pórěd pó wužywarskem mjenju', |
| 749 | + 'qp_order_by_polls_count' => 'Pórěd pó licbje napšašowanjow', |
| 750 | + 'qp_results_line_qupl' => 'Bok "$1" napšašowanje "$2": $3', |
| 751 | + 'qp_results_line_qpl' => 'Bok "$1" napšašowanje "$2": $3, $4, $5, $6', |
| 752 | + 'qp_header_line_qpul' => '$1 [ bok "$2" napšašowanje "$3" ]', |
| 753 | + 'qp_export_to_xls' => 'Statistiku do XLS-formata eksportěrowaś', |
| 754 | + 'qp_voices_to_xls' => 'Głose do XLS-formata eksportěrowaś', |
| 755 | + 'qp_users_answered_questions' => '$1 {{PLURAL:$1|wužywaŕ jo wótegronił|wužywarja stej wótegroniłej|wužywarje su wótegronili|wužywarjow jo wótegroniło}}', |
| 756 | + 'qp_func_no_such_poll' => 'Take napšašowanje njejo ($1)', |
| 757 | + 'qp_func_missing_question_id' => 'Pšosym pódaj eksistěrujucy ID pšašanja (zachopinajucy wót 1) za napšašowanje $1', |
| 758 | + 'qp_func_invalid_question_id' => 'Njepłaśiwy ID=$2 pšašanja (žedna licba) za napšašowanje $1', |
| 759 | + 'qp_func_missing_proposal_id' => 'Pšosym pódaj eksistěrujucy ID naraźenja (zachopinajucy wót 0) za napšašowanje $1, pšašanje $2', |
| 760 | + 'qp_func_invalid_proposal_id' => 'Njepłaśiwy ID=$3 naraźenja (žedna licba) za napšašowanje $1, pšašanje $2', |
| 761 | + 'qp_error_no_such_poll' => 'Take napšašowanje ($1) njejo. |
| 762 | +Zawěsć, až napšašowanje se deklarěrujo a składujo, zawěsć se teke adresowe źěleńske znamuško # wužywaś', |
| 763 | + 'qp_error_in_question_header' => 'Njepłaśiwy typ pšašanja: $1', |
| 764 | + 'qp_error_id_in_stats_mode' => 'Njejo móžno ID napšašowanja w statistiskem modusu deklarěrowaś', |
| 765 | + 'qp_error_dependance_in_stats_mode' => 'Njejo móžno rjeśak wótwisnosći napšašowanja w statistiskem modusu deklarěrowaś', |
| 766 | + 'qp_error_no_stats' => 'Žedne statistiske daty k dispoziciji, dokulaž nichten njejo wótgłosował za toś to napšašowanje (adresa=$1)', |
| 767 | + 'qp_error_address_in_decl_mode' => 'Njejo móžno adresu napšašowanja w deklaraciskem modusu dostaś', |
| 768 | + 'qp_error_question_not_implemented' => 'Pšašanja takego typa njejsu implementěrowane: $1', |
| 769 | + 'qp_error_invalid_question_type' => 'Njepłaśiwy typ pšašanja: $1', |
| 770 | + 'qp_error_type_in_stats_mode' => 'Typ pšašanja njedajo se w statistiskem zwobraznjeńskem modusu definěrowaś: $1', |
| 771 | + 'qp_error_no_poll_id' => 'Toflicka Poll njejo atribut ID definěrowana.', |
| 772 | + 'qp_error_invalid_poll_id' => 'Njepłaśiwy napšašowański ID (ID=$1). |
| 773 | +Napšašowański ID smějo jano pismiki, licby a prozne znamje wopśimjeś', |
| 774 | + 'qp_error_already_used_poll_id' => 'Napšašowański ID jo se južo wužył na toś tom boku (ID=$1).', |
| 775 | + 'qp_error_invalid_dependance_value' => 'Rjeśazk wótwisnosći napšašowanja (ID=$1) ma njepłaśiwu gódnotu atributa dependance (dependance="$2")', |
| 776 | + 'qp_error_missed_dependance_title' => 'Napšašowanje (ID=$1) jo wótwisne wót drugego napšašowanja (ID=$3) z boka [[$2]], ale titel [[$2]] njejo se namakał. |
| 777 | +Wótpóraj pak atribut dependance pak wótnow [[$2]]', |
| 778 | + 'qp_error_missed_dependance_poll' => 'Napšašowanje (ID=$1) jo wótwisne wót drugego napšašowanja (ID=$3) na boku $2, ale to napšašowanje njeeksistěrujo abo njejo se doněnta składło. |
| 779 | +Wótpóraj pak atribut dependance pak napóraj napšašowanje z ID=$3 na boku $2 a składuj jo. |
| 780 | +Aby składował napšašowanje, wótpósćel jo, mimo až sy wótegronił na naraźeńske pšašanja.', |
| 781 | + 'qp_error_vote_dependance_poll' => 'Pšosym wótgłosuj nejpjerwjej za napšašowanje $1.', |
| 782 | + 'qp_error_too_many_spans' => 'Pśewjele kategorijowych klasow za pódkategorije definěrowane', |
| 783 | + 'qp_error_unanswered_span' => 'Pódkategorija bźez wótegrona', |
| 784 | + 'qp_error_non_unique_choice' => 'Toś to pšašanje trjeba jadnorazne wótegrono naraźenja', |
| 785 | + 'qp_error_category_name_empty' => 'Mě kategorije jo prozne', |
| 786 | + 'qp_error_proposal_text_empty' => 'Tekst naraźenja jo prozny', |
| 787 | + 'qp_error_too_few_categories' => 'Nanejmjenjej dwě kategorji musytej se definěrować', |
| 788 | + 'qp_error_too_few_spans' => 'Kužda kategorijowa klasa trjeba nanejmjenjej dwě móžnej wótegronje', |
| 789 | + 'qp_error_no_answer' => 'Naraźenje bźez wótegrona', |
| 790 | + 'qp_error_unique' => 'Pšašanje typa unique() ma wěcej naraźenjow ako móžne wótegrona su definěrowane: njemóžno pókšacowaś', |
| 791 | +); |
| 792 | + |
| 793 | +/** Greek (Ελληνικά) |
| 794 | + * @author Egmontaz |
| 795 | + * @author ZaDiak |
| 796 | + */ |
| 797 | +$messages['el'] = array( |
| 798 | + 'qp_result_NA' => 'Αναπάντητο', |
| 799 | + 'qp_result_error' => 'Συντακτικό σφάλμα', |
| 800 | + 'qp_vote_button' => 'Ψήφισε', |
| 801 | + 'qp_vote_again_button' => 'Αλλαγή ψήφου', |
| 802 | + 'qp_polls_list' => 'Καταγραφή όλων των δημοσκοπήσεων', |
| 803 | + 'qp_users_list' => 'Καταγραφή όλων των χρηστών', |
| 804 | + 'qp_browse_to_poll' => 'Πλοήγηση σε $1', |
| 805 | + 'qp_browse_to_user' => 'Πλοήγηση σε $1', |
| 806 | + 'qp_votes_count' => '$1 {{PLURAL:$1|ψήφος|ψήφοι}}', |
| 807 | + 'qp_source_link' => 'Πηγή', |
| 808 | + 'qp_stats_link' => 'Στατιστικά', |
| 809 | + 'qp_users_link' => 'Χρήστες', |
| 810 | + 'qp_voice_link' => 'Φωνή χρήστη', |
| 811 | + 'qp_voice_link_inv' => 'Φωνή χρήστη;', |
| 812 | + 'qp_user_polls_link' => 'Συμμετοχή σε $1 {{PLURAL:$1|δημοσκόπηση|δημοσκοπήσεις}}', |
| 813 | + 'qp_user_missing_polls_link' => 'Καμία συμμετοχή', |
| 814 | + 'qp_not_participated_link' => 'Δεν συμμετείχε', |
| 815 | + 'qp_order_by_username' => 'Ταξινόμηση κατά όνομα χρήστη', |
| 816 | + 'qp_results_line_qupl' => 'Σελίδα "$1" Δημοσκόπηση "$2": $3', |
| 817 | + 'qp_func_no_such_poll' => 'Καμιά τέτοια δημοσκόπηση ($1)', |
| 818 | +); |
| 819 | + |
| 820 | +/** Esperanto (Esperanto) |
| 821 | + * @author Yekrats |
| 822 | + */ |
| 823 | +$messages['eo'] = array( |
| 824 | + 'qp_result_error' => 'Sintaksa eraro', |
| 825 | + 'qp_vote_button' => 'Voĉdoni', |
| 826 | + 'qp_source_link' => 'Fonto', |
| 827 | + 'qp_stats_link' => 'Statistikoj', |
| 828 | + 'qp_users_link' => 'Uzantoj', |
| 829 | +); |
| 830 | + |
| 831 | +/** Spanish (Español) |
| 832 | + * @author Imre |
| 833 | + * @author Translationista |
| 834 | + */ |
| 835 | +$messages['es'] = array( |
| 836 | + 'pollresults' => 'Resultados de las encuestas en esta página', |
| 837 | + 'qp_desc' => 'Permite la creación de encuestas', |
| 838 | + 'qp_desc-sp' => '[[Special:PollResults|Página especial]] para ver los resultados de las encuestas', |
| 839 | + 'qp_result_NA' => 'No respondido', |
| 840 | + 'qp_result_error' => 'Error de sintaxis', |
| 841 | + 'qp_vote_button' => 'Vota', |
| 842 | + 'qp_vote_again_button' => 'Cambia tu voto', |
| 843 | + 'qp_polls_list' => 'Lista todas las encuestas', |
| 844 | + 'qp_users_list' => 'Hacer una lista de todos los usuarios', |
| 845 | + 'qp_browse_to_poll' => 'Navegar a $1', |
| 846 | + 'qp_browse_to_user' => 'Navegar a $1', |
| 847 | + 'qp_votes_count' => '$1 {{PLURAL:$1|voto|votos}}', |
| 848 | + 'qp_source_link' => 'Fuente', |
| 849 | + 'qp_stats_link' => 'Estadísticas', |
| 850 | + 'qp_users_link' => 'Usuarios', |
| 851 | + 'qp_voice_link' => 'Voz de usuario', |
| 852 | + 'qp_voice_link_inv' => '¿Voz de usuario?', |
| 853 | + 'qp_user_polls_link' => 'Ha participado en $1 {{PLURAL:$1|sondeo|sondeos}}', |
| 854 | + 'qp_user_missing_polls_link' => 'No participación', |
| 855 | + 'qp_not_participated_link' => 'No ha participado', |
| 856 | + 'qp_order_by_username' => 'Organizar por nombre de usuario', |
| 857 | + 'qp_order_by_polls_count' => 'Ordenar por conteo de encuestas', |
| 858 | + 'qp_results_line_qupl' => 'Página "$1" Votación "$2": $3', |
| 859 | + 'qp_results_line_qpl' => 'Página "$1" Votación "$2": $3, $4, $5, $6', |
| 860 | + 'qp_header_line_qpul' => '$1 [ Página "$2" Votación "$3" ]', |
| 861 | + 'qp_export_to_xls' => 'Exportar estadísticas a formato XLS', |
| 862 | + 'qp_users_answered_questions' => '$1 {{PLURAL:$1|usuario ha|usuarios han}} respondido a las preguntas', |
| 863 | + 'qp_func_no_such_poll' => 'No hay votación ($1)', |
| 864 | + 'qp_func_missing_question_id' => 'Por favor, especifica un identificador de pregunta existente (a partir de 1) para la encuesta $1', |
| 865 | + 'qp_func_invalid_question_id' => 'Pregunta inválida id=$2 (no es un número) para la encuesta $1', |
| 866 | + 'qp_func_missing_proposal_id' => 'Por favor, especifica un identificador de propuesta que exista (comenzando a partir de 0) para la encuesta $1, pregunta $2', |
| 867 | + 'qp_func_invalid_proposal_id' => 'Identificador de propuesta inválido=$3 (no es un número) para la encuesta $1, pregunta $2', |
| 868 | + 'qp_error_no_such_poll' => 'No existe tal encuesta ($1). |
| 869 | +Asegúrate de que la encuesta está declarada y guardada, y no olvides usar el carácter delimitador de dirección #', |
| 870 | + 'qp_error_in_question_header' => 'Encabezado de pregunta inválido: $1', |
| 871 | + 'qp_error_id_in_stats_mode' => 'No se puede declarar una ID de encuesta en modo estadístico', |
| 872 | + 'qp_error_dependance_in_stats_mode' => 'No se puede declarar una cadena de dependencia para la encuesta en modo estadístico', |
| 873 | + 'qp_error_no_stats' => 'No hay datos estadísticos disponibles porque nadie ha votado aún en esta encuesta (dirección=$1)', |
| 874 | + 'qp_error_address_in_decl_mode' => 'No se puede obtener una dirección de la encuesta en modo declarativo', |
| 875 | + 'qp_error_question_not_implemented' => 'Las preguntas de este tipo no están implementadas: $1', |
| 876 | + 'qp_error_invalid_question_type' => 'Tipo de pregunta inválido: $1', |
| 877 | + 'qp_error_type_in_stats_mode' => 'El tipo de pregunta no puede definirse en modo de visualización estadística: $1', |
| 878 | + 'qp_error_no_poll_id' => 'La etiqueta de la encuesta no tiene atributo de id definido.', |
| 879 | + 'qp_error_invalid_poll_id' => 'El id de la encuesta no es válido (id=$1). |
| 880 | +El id sólo puede contener letras, números y espacios', |
| 881 | + 'qp_error_already_used_poll_id' => 'El identificador de encuesta ya se ha utilizado en esta página (id=$1).', |
| 882 | + 'qp_error_invalid_dependance_value' => 'La cadena de dependencia de la encuesta (id=$1) tiene un valor inválido de atributo de dependencia (dependencia="$2")', |
| 883 | + 'qp_error_missed_dependance_title' => 'La encuesta (id=$1) es dependiente de otra encuesta, (id =$3), de la página [[$2]], pero el título de [[$2]] no se ha encontrado. Elimina el atributo de dependencia, o restaura [[$2] ]', |
| 884 | + 'qp_error_missed_dependance_poll' => 'La encuesta (id=$1) es dependiente de la encuesta (id=$3) en la página $2, pero esa encuesta no existe o aún no se ha guardado. Elimina el atributo de la dependencia o crea la encuesta con id=$3 en la página de $2 y guárdala. Para guardar una encuesta, envíala sin responder a las preguntas.', |
| 885 | + 'qp_error_vote_dependance_poll' => 'Por favor, vota primero en la encuesta $1.', |
| 886 | + 'qp_error_too_many_spans' => 'Muchas clases de categorías para las subcategorías definidas', |
| 887 | + 'qp_error_unanswered_span' => 'Subcategoría sin responder', |
| 888 | + 'qp_error_non_unique_choice' => 'Esta pregunta requiere una propuesta de respuesta única', |
| 889 | + 'qp_error_category_name_empty' => 'El nombre de categoría está vacío', |
| 890 | + 'qp_error_proposal_text_empty' => 'El texto de propuesta está vacío', |
| 891 | + 'qp_error_too_few_categories' => 'Se debe definir al menos dos categorías', |
| 892 | + 'qp_error_too_few_spans' => 'Cada clase de categoría requiere de al menos dos respuestas possibles definidas', |
| 893 | + 'qp_error_no_answer' => 'Propuesta no respondida', |
| 894 | + 'qp_error_unique' => 'La pregunta de tipo único() tiene definidas más propuestas que respuestas posibles: imposible completar', |
| 895 | +); |
| 896 | + |
| 897 | +/** Finnish (Suomi) |
| 898 | + * @author Crt |
| 899 | + * @author Str4nd |
| 900 | + * @author Tofu II |
| 901 | + */ |
| 902 | +$messages['fi'] = array( |
| 903 | + 'qp_result_NA' => 'Ei vastattu', |
| 904 | + 'qp_result_error' => 'Syntaksivirhe', |
| 905 | + 'qp_vote_button' => 'Äänestä', |
| 906 | + 'qp_vote_again_button' => 'Vaihda ääntäsi', |
| 907 | + 'qp_users_list' => 'Lista kaikista käyttäjistä', |
| 908 | + 'qp_votes_count' => '$1 {{PLURAL:$1|ääni|ääntä}}', |
| 909 | + 'qp_source_link' => 'Lähde', |
| 910 | + 'qp_stats_link' => 'Tilastot', |
| 911 | + 'qp_users_link' => 'Käyttäjät', |
| 912 | + 'qp_order_by_username' => 'Lajittele käyttäjänimen mukaan', |
| 913 | + 'qp_export_to_xls' => 'Vie tilastot XLS-muotoon', |
| 914 | + 'qp_error_category_name_empty' => 'Luokan nimi on tyhjä', |
| 915 | + 'qp_error_proposal_text_empty' => 'Ehdotusteksti on tyhjä', |
| 916 | + 'qp_error_too_few_categories' => 'Ainakin kaksi luokkaa pitää määritellä', |
| 917 | + 'qp_error_no_answer' => 'Vastaamaton ehdotus', |
| 918 | +); |
| 919 | + |
| 920 | +/** French (Français) |
| 921 | + * @author IAlex |
| 922 | + * @author Jean-Frédéric |
| 923 | + * @author McDutchie |
| 924 | + * @author PieRRoMaN |
| 925 | + * @author Sherbrooke |
| 926 | + * @author Urhixidur |
| 927 | + */ |
| 928 | +$messages['fr'] = array( |
| 929 | + 'pollresults' => 'Résultats des sondages sur ce site', |
| 930 | + 'qp_desc' => 'Permet la création de sondages', |
| 931 | + 'qp_desc-sp' => '[[Special:PollResults|Page spéciale]] pour consulter les résultats des sondages', |
| 932 | + 'qp_result_NA' => 'Pas de réponse', |
| 933 | + 'qp_result_error' => 'Erreur de syntaxe', |
| 934 | + 'qp_vote_button' => 'Vote', |
| 935 | + 'qp_vote_again_button' => 'Changer votre vote', |
| 936 | + 'qp_polls_list' => 'Lister tous les sondages', |
| 937 | + 'qp_users_list' => 'Lister tous les utilisateurs', |
| 938 | + 'qp_browse_to_poll' => 'Aller jusqu’à $1', |
| 939 | + 'qp_browse_to_user' => 'Aller jusqu’à $1', |
| 940 | + 'qp_votes_count' => '$1 {{PLURAL:$1|vote|votes}}', |
| 941 | + 'qp_source_link' => 'Source', |
| 942 | + 'qp_stats_link' => 'Statistiques', |
| 943 | + 'qp_users_link' => 'Utilisateurs', |
| 944 | + 'qp_voice_link' => 'Voix de l’utilisateur', |
| 945 | + 'qp_voice_link_inv' => 'Voix de l’utilisateur ?', |
| 946 | + 'qp_user_polls_link' => 'A participé à $1 {{PLURAL:$1|sondage|sondages}}', |
| 947 | + 'qp_user_missing_polls_link' => 'Pas de participation', |
| 948 | + 'qp_not_participated_link' => 'Pas de participation', |
| 949 | + 'qp_order_by_username' => 'Trier par nom d’utilisateur', |
| 950 | + 'qp_order_by_polls_count' => 'Trier par nombre de sondages', |
| 951 | + 'qp_results_line_qupl' => 'Page « $1 » Sondage « $2 » : $3', |
| 952 | + 'qp_results_line_qpl' => 'Page « $1 » Sondage « $2 » : $3, $4, $5, $6', |
| 953 | + 'qp_header_line_qpul' => '$1 [ Page « $2 » Sondage « $3 » ]', |
| 954 | + 'qp_export_to_xls' => 'Exporter les statistiques au format XLS', |
| 955 | + 'qp_voices_to_xls' => 'Exporter les votes au format XLS', |
| 956 | + 'qp_users_answered_questions' => '$1 {{PLURAL:$1|utilisateur a|utilisateurs ont}} répondu aux questions', |
| 957 | + 'qp_func_no_such_poll' => 'Ce sondage n’existe pas ($1)', |
| 958 | + 'qp_func_missing_question_id' => 'Veuillez spécifier un id question existant (à partir de 1) pour le sondage $1', |
| 959 | + 'qp_func_invalid_question_id' => 'id question=$2 invalide (pas un nombre) pour le sondage $1', |
| 960 | + 'qp_func_missing_proposal_id' => 'Veuillez spécifier un id proposition existant (à partir de 0) pour le sondage $1, question $2', |
| 961 | + 'qp_func_invalid_proposal_id' => 'id proposition=$3 invalide (pas un nombre) pour le sondage $1, question $2', |
| 962 | + 'qp_error_no_such_poll' => 'Ce sondage n’existe pas ($1). |
| 963 | +Assurez-vous que le sondage soit déclaré et sauvegardé. Vérifiez également si vous utilisez le caractère délimiteur d’adresse #', |
| 964 | + 'qp_error_in_question_header' => 'En-tête de question incorrect : $1', |
| 965 | + 'qp_error_id_in_stats_mode' => 'Impossible de déclarer un ID du sondage dans le mode statistique', |
| 966 | + 'qp_error_dependance_in_stats_mode' => 'Impossible de déclarer la chaîne de dépendance du sondage en mode statistique', |
| 967 | + 'qp_error_no_stats' => 'Aucune donnée statistique n’est disponible, car personne n’a répondu à ce sondage pour l’instant (address=$1)', |
| 968 | + 'qp_error_address_in_decl_mode' => 'Impossible d’obtenir une adresse du sondage en mode déclaratif', |
| 969 | + 'qp_error_question_not_implemented' => 'Les questions de ce type ne sont pas implémentées : $1', |
| 970 | + 'qp_error_invalid_question_type' => 'Type de question invalide : $1', |
| 971 | + 'qp_error_type_in_stats_mode' => 'Le type de question ne peut pas être défini en mode d’affichage statistique : $1', |
| 972 | + 'qp_error_no_poll_id' => 'La balise du sondage n’a pas d’identifiant défini.', |
| 973 | + 'qp_error_invalid_poll_id' => 'Identifiant de sondage invalide (id=$1). |
| 974 | +L’identifiant de sondage peut contenir uniquement des lettres, des nombres et le caractère espace', |
| 975 | + 'qp_error_already_used_poll_id' => 'L’identifiant de sondage a déjà été utilisé sur cette page (id=$1).', |
| 976 | + 'qp_error_invalid_dependance_value' => 'La chaîne de dépendance du sondage (id=$1) a une valeur invalide pour l’attribut de dépendance (dependance="$2")', |
| 977 | + 'qp_error_missed_dependance_title' => 'Le sondage (i=$1) dépend d’un autre sondage (id=$3) de la page [[$2]], mais le titre [[$2]] n’a pas été trouvé. |
| 978 | +Supprimez l’attribut de dépendance, ou bien restaurez [[$2]]', |
| 979 | + 'qp_error_missed_dependance_poll' => 'Le sondage (id=$1) dépend d’un autre sondage (id=$3) à la page $2, mais ce sondage n’existe pas ou n’a pas encore été enregistré. |
| 980 | +Supprimez l’attribut de dépendance, ou bien créez le sondage $3 à la page $2 et enregistrez-le. |
| 981 | +Pour enregistrer un sondage, soumettez-le en ne répondant à aucune question de proposition.', |
| 982 | + 'qp_error_vote_dependance_poll' => 'Veuillez d’abord répondre au sondage $1.', |
| 983 | + 'qp_error_too_many_spans' => 'Trop de classes de catégories pour les sous-catégories définies', |
| 984 | + 'qp_error_unanswered_span' => 'Sous-catégorie sans réponse', |
| 985 | + 'qp_error_non_unique_choice' => 'Cette question nécessite une réponse de proposition unique', |
| 986 | + 'qp_error_category_name_empty' => 'Le nom de la catégorie est vide', |
| 987 | + 'qp_error_proposal_text_empty' => 'Le texte de la proposition est vide', |
| 988 | + 'qp_error_too_few_categories' => 'Au moins deux catégories doivent être définies', |
| 989 | + 'qp_error_too_few_spans' => 'Toute classe de catégorie nécessite au moins deux réponses possibles définies', |
| 990 | + 'qp_error_no_answer' => 'Proposition sans réponse', |
| 991 | + 'qp_error_unique' => 'La question de type unique() a plus de propositions qu’il n’y a de réponses possibles définies : impossible de compléter', |
| 992 | +); |
| 993 | + |
| 994 | +/** Franco-Provençal (Arpetan) |
| 995 | + * @author ChrisPtDe |
| 996 | + */ |
| 997 | +$messages['frp'] = array( |
| 998 | + 'pollresults' => 'Rèsultats des sondâjos sur ceti seto', |
| 999 | + 'qp_desc' => 'Pèrmèt la crèacion de sondâjos.', |
| 1000 | + 'qp_desc-sp' => '[[Special:PollResults|Pâge spèciâla]] por vêre los rèsultats des sondâjos', |
| 1001 | + 'qp_result_NA' => 'Pas rèpondu', |
| 1002 | + 'qp_result_error' => 'Èrror de sintaxa', |
| 1003 | + 'qp_vote_button' => 'Votar', |
| 1004 | + 'qp_vote_again_button' => 'Changiér voutron voto', |
| 1005 | + 'qp_polls_list' => 'Listar tôs los sondâjos', |
| 1006 | + 'qp_users_list' => 'Listar tôs los utilisators', |
| 1007 | + 'qp_browse_to_poll' => 'Navegar tant qu’a $1', |
| 1008 | + 'qp_browse_to_user' => 'Navegar tant qu’a $1', |
| 1009 | + 'qp_votes_count' => '$1 voto{{PLURAL:$1||s}}', |
| 1010 | + 'qp_source_link' => 'Sôrsa', |
| 1011 | + 'qp_stats_link' => 'Statistiques', |
| 1012 | + 'qp_users_link' => 'Utilisators', |
| 1013 | + 'qp_voice_link' => 'Vouèx a l’utilisator', |
| 1014 | + 'qp_voice_link_inv' => 'Vouèx a l’utilisator ?', |
| 1015 | + 'qp_user_polls_link' => 'At participâ a $1 sondâjo{{PLURAL:$1||s}}', |
| 1016 | + 'qp_user_missing_polls_link' => 'Gins de participacion', |
| 1017 | + 'qp_not_participated_link' => 'At pas participâ', |
| 1018 | + 'qp_order_by_username' => 'Triyér per nom d’utilisator', |
| 1019 | + 'qp_order_by_polls_count' => 'Triyér per nombro de sondâjos', |
| 1020 | + 'qp_results_line_qupl' => 'Pâge « $1 » Sondâjo « $2 » : $3', |
| 1021 | + 'qp_results_line_qpl' => 'Pâge « $1 » Sondâjo « $2 » : $3, $4, $5, $6', |
| 1022 | + 'qp_header_line_qpul' => '$1 [ Pâge « $2 » Sondâjo « $3 » ]', |
| 1023 | + 'qp_export_to_xls' => 'Èxportar les statistiques u format XLS', |
| 1024 | + 'qp_voices_to_xls' => 'Èxportar los votos u format XLS', |
| 1025 | + 'qp_users_answered_questions' => '$1 {{PLURAL:$1|utilisator a|utilisators on}}t rèpondu a les quèstions', |
| 1026 | + 'qp_func_no_such_poll' => 'Lo sondâjo ègziste pas ($1)', |
| 1027 | + 'qp_error_in_question_header' => 'En-téta de quèstion fôssa : $1', |
| 1028 | + 'qp_error_invalid_question_type' => 'Tipo de quèstion envalido : $1', |
| 1029 | + 'qp_error_vote_dependance_poll' => 'Volyéd d’abôrd rèpondre u sondâjo $1.', |
| 1030 | + 'qp_error_unanswered_span' => 'Sot-catègorie sen rèponsa', |
| 1031 | + 'qp_error_category_name_empty' => 'Lo nom de la catègorie est vouedo', |
| 1032 | + 'qp_error_proposal_text_empty' => 'Lo tèxto de la proposicion est vouedo', |
| 1033 | + 'qp_error_no_answer' => 'Proposicion sen rèponsa', |
| 1034 | +); |
| 1035 | + |
| 1036 | +/** Galician (Galego) |
| 1037 | + * @author Toliño |
| 1038 | + */ |
| 1039 | +$messages['gl'] = array( |
| 1040 | + 'pollresults' => 'Resultados das enquisas desta páxina', |
| 1041 | + 'qp_desc' => 'Permite a creación de enquisas', |
| 1042 | + 'qp_desc-sp' => '[[Special:PollResults|Páxina especial]] para ollar os resultados das enquisas', |
| 1043 | + 'qp_result_NA' => 'Sen resposta', |
| 1044 | + 'qp_result_error' => 'Erro de sintaxe', |
| 1045 | + 'qp_vote_button' => 'Votar', |
| 1046 | + 'qp_vote_again_button' => 'Cambiar o seu voto', |
| 1047 | + 'qp_polls_list' => 'Lista de todas as enquisas', |
| 1048 | + 'qp_users_list' => 'Lista de todos os usuarios', |
| 1049 | + 'qp_browse_to_poll' => 'Navegar ata $1', |
| 1050 | + 'qp_browse_to_user' => 'Navegar ata $1', |
| 1051 | + 'qp_votes_count' => '$1 {{PLURAL:$1|voto|votos}}', |
| 1052 | + 'qp_source_link' => 'Fonte', |
| 1053 | + 'qp_stats_link' => 'Estatísticas', |
| 1054 | + 'qp_users_link' => 'Usuarios', |
| 1055 | + 'qp_voice_link' => 'Voz do usuario', |
| 1056 | + 'qp_voice_link_inv' => 'Voz do usuario?', |
| 1057 | + 'qp_user_polls_link' => 'Participou {{PLURAL:$1|nunha enquisa|en $1 enquisas}}', |
| 1058 | + 'qp_user_missing_polls_link' => 'Non participou', |
| 1059 | + 'qp_not_participated_link' => 'Non participou', |
| 1060 | + 'qp_order_by_username' => 'Ordenar por nome de usuario', |
| 1061 | + 'qp_order_by_polls_count' => 'Ordenar por número de enquisa', |
| 1062 | + 'qp_results_line_qupl' => 'Páxina "$1", enquisa "$2": $3', |
| 1063 | + 'qp_results_line_qpl' => 'Páxina "$1", enquisa "$2": $3, $4, $5, $6', |
| 1064 | + 'qp_header_line_qpul' => '$1 [ Páxina "$2", enquisa "$3" ]', |
| 1065 | + 'qp_export_to_xls' => 'Exportar as estatísticas en formato XLS', |
| 1066 | + 'qp_voices_to_xls' => 'Exportar as voces en formato XLS', |
| 1067 | + 'qp_users_answered_questions' => '$1 {{PLURAL:$1|usuario respondeu|usuarios responderon}} ás preguntas', |
| 1068 | + 'qp_func_no_such_poll' => 'Non existe tal enquisa ($1)', |
| 1069 | + 'qp_func_missing_question_id' => 'Por favor, especifique o id dunha pregunta existente (a partir de 1) para a enquisa $1', |
| 1070 | + 'qp_func_invalid_question_id' => 'question id=$2 (non un número) non válido para a enquisa $1', |
| 1071 | + 'qp_func_missing_proposal_id' => 'Por favor, especifique o id dunha proposta existente (a partir de 0) para a enquisa $1, pregunta $2', |
| 1072 | + 'qp_func_invalid_proposal_id' => 'proposal id=$3 (non un número) non válido para a enquisa $1, pregunta $2', |
| 1073 | + 'qp_error_no_such_poll' => 'Non existe tal enquisa ($1). |
| 1074 | +Asegúrese de que a enquisa está declarada e gardada, non esqueza usar o carácter delimitador de enderezo #', |
| 1075 | + 'qp_error_in_question_header' => 'Cabeceira de pregunta inválida: $1', |
| 1076 | + 'qp_error_id_in_stats_mode' => 'Non se pode declarar un ID da enquisa no modo de estatística', |
| 1077 | + 'qp_error_dependance_in_stats_mode' => 'Non se pode declarar a cadea de dependencia da enquisa no modo de estatística', |
| 1078 | + 'qp_error_no_stats' => 'Non hai datos estatísticos dispoñibles porque aínda ninguén votou nesta enquisa (address=$1)', |
| 1079 | + 'qp_error_address_in_decl_mode' => 'Non se pode obter un enderezo da enquisa no modo de declaración', |
| 1080 | + 'qp_error_question_not_implemented' => 'As preguntas deste tipo non están implementadas: $1', |
| 1081 | + 'qp_error_invalid_question_type' => 'Tipo de pregunta non válido: $1', |
| 1082 | + 'qp_error_type_in_stats_mode' => 'O tipo de pregunta non se pode definir no modo de vista estatística: $1', |
| 1083 | + 'qp_error_no_poll_id' => 'A etiqueta da enquisa non ten ningún atributo id definido.', |
| 1084 | + 'qp_error_invalid_poll_id' => 'O id da enquisa non é válido (id=$1). |
| 1085 | +O id só pode conter letras, números e espazos', |
| 1086 | + 'qp_error_already_used_poll_id' => 'O id da enquisa xa se empregou nesta páxina (id=$1).', |
| 1087 | + 'qp_error_invalid_dependance_value' => 'A cadea de dependencia da enquisa (id=$1) ten un valor non válido para o atributo de dependencia (dependance="$2")', |
| 1088 | + 'qp_error_missed_dependance_title' => 'A enquisa (id=$1) depende doutra enquisa (id=$3) da páxina [[$2]], pero non se atopou o título [[$2]]. |
| 1089 | +Elimine o atributo de dependencia ou restaure [[$2]]', |
| 1090 | + 'qp_error_missed_dependance_poll' => 'A enquisa (id=$1) depende doutra enquisa (id=$3) na páxina $2, pero esa enquisa non existe ou aínda non foi gardada. |
| 1091 | +Elimine o atributo de dependencia ou cree a enquisa co id=$3 na páxina $2 e gárdea. |
| 1092 | +Para gardar unha enquisa, envíea sen responder a ningunha pregunta.', |
| 1093 | + 'qp_error_vote_dependance_poll' => 'Por favor, vote primeiro na enquisa $1.', |
| 1094 | + 'qp_error_too_many_spans' => 'Demasiadas clases de categoría para as subcategorías definidas', |
| 1095 | + 'qp_error_unanswered_span' => 'Subcategoría sen resposta', |
| 1096 | + 'qp_error_non_unique_choice' => 'Esta pregunta require unha resposta única', |
| 1097 | + 'qp_error_category_name_empty' => 'O nome da categoría está baleiro', |
| 1098 | + 'qp_error_proposal_text_empty' => 'O texto da proposta está baleiro', |
| 1099 | + 'qp_error_too_few_categories' => 'Débense definir, polo menos, dúas categorías', |
| 1100 | + 'qp_error_too_few_spans' => 'Cada clase de categoría necesita definidas, polo menos, dúas respostas posibles', |
| 1101 | + 'qp_error_no_answer' => 'Proposta sen resposta', |
| 1102 | + 'qp_error_unique' => 'A pregunta de tipo unique() ten definidas máis propostas que respostas posibles: imposible de completar', |
| 1103 | +); |
| 1104 | + |
| 1105 | +/** Swiss German (Alemannisch) |
| 1106 | + * @author Als-Holder |
| 1107 | + */ |
| 1108 | +$messages['gsw'] = array( |
| 1109 | + 'pollresults' => 'Ergebnis vu dr Abstimmige uf däm Site', |
| 1110 | + 'qp_desc' => 'Erlaubt s Aalege vu Abstimmige', |
| 1111 | + 'qp_desc-sp' => '[[Special:PollResults|Spezialsyte]] zum Aalueg vu dr Ergebnis vu dr Abstimmige', |
| 1112 | + 'qp_result_NA' => 'Kei Antwort', |
| 1113 | + 'qp_result_error' => 'Syntaxfähler', |
| 1114 | + 'qp_vote_button' => 'Abstimme', |
| 1115 | + 'qp_vote_again_button' => 'Dyy Stimm ändere', |
| 1116 | + 'qp_polls_list' => 'Alli Abstimmige uflischte', |
| 1117 | + 'qp_users_list' => 'Alli Benutzer uflischte', |
| 1118 | + 'qp_browse_to_poll' => 'Wyter zue $1', |
| 1119 | + 'qp_browse_to_user' => 'Wyter zue $1', |
| 1120 | + 'qp_votes_count' => '$1 {{PLURAL:$1|Stimm|Stimme}}', |
| 1121 | + 'qp_source_link' => 'Quälle', |
| 1122 | + 'qp_stats_link' => 'Statischtik', |
| 1123 | + 'qp_users_link' => 'Benutzer', |
| 1124 | + 'qp_voice_link' => 'Benutzerstimm', |
| 1125 | + 'qp_voice_link_inv' => 'Benutzerstimm?', |
| 1126 | + 'qp_user_polls_link' => 'Mitgmacht bi $1 {{PLURAL:$1|Abstimmig|Abstimmige}}', |
| 1127 | + 'qp_user_missing_polls_link' => 'Niene mitgmacht', |
| 1128 | + 'qp_not_participated_link' => 'Niene mitgmacht', |
| 1129 | + 'qp_order_by_username' => 'No Benutzername gordnet', |
| 1130 | + 'qp_order_by_polls_count' => 'No Abstimmigsaazahl gordnet', |
| 1131 | + 'qp_results_line_qupl' => 'Syte „$1“ Abstimmig „$2“: $3', |
| 1132 | + 'qp_results_line_qpl' => 'Syte „$1“ Abstimmig „$2“: $3, $4, $5, $6', |
| 1133 | + 'qp_header_line_qpul' => '$1 [ Syte „$2“ Abstimmig „$3“ ]', |
| 1134 | + 'qp_header_line_qucl' => '$1. $2<br />$3 ??? $4', |
| 1135 | + 'qp_export_to_xls' => 'Statischtik im XLS-Format exportiere', |
| 1136 | + 'qp_voices_to_xls' => 'Stimme im XLS-Format exportiere', |
| 1137 | + 'qp_users_answered_questions' => '$1 {{PLURAL:$1|Benutzer het|Benutzer hän}} Antworte uf d Froge gee', |
| 1138 | + 'qp_func_no_such_poll' => 'Kei sonigi Abstimmig ($1)', |
| 1139 | + 'qp_func_missing_question_id' => 'Bitte spezifizier e Froge-Chännnummere (mit 1 aafange) fir d Abstimmig $1', |
| 1140 | + 'qp_func_invalid_question_id' => 'Uugiltigi Froge-Chännnummere ($2, kei Zahl) fir d Abstimmig $1', |
| 1141 | + 'qp_func_missing_proposal_id' => 'Bitte spezifiezier e Vorschlags-Chännnummere, wu s scho git (mit 0 aafange) fir d Abstimmig $1, Frog $2', |
| 1142 | + 'qp_func_invalid_proposal_id' => 'Nit giltigi Vorschlags-Chännnummere ($3, kei Zahl) fir d Abstimmig $1, Frog $2', |
| 1143 | + 'qp_error_no_such_poll' => 'Kei sonigi Abstimmig ($1). |
| 1144 | +Stell sicher, ass d Abstimmig verchindet un gspycheret woren isch, stell au sicher, ass as Trännzeiche in dr Adräss alliwyl # brucht wird', |
| 1145 | + 'qp_error_in_question_header' => 'Nit giltige Frogechopf: $1', |
| 1146 | + 'qp_error_id_in_stats_mode' => 'Cha dr Abstimmig kei Chännnummere zuewyyse im statistische Modus', |
| 1147 | + 'qp_error_dependance_in_stats_mode' => 'Cha d Abhägikeits-Chette vu dr Abstimmig nit verchinde im statistische Modus', |
| 1148 | + 'qp_error_no_stats' => 'Kei statistischi Date verfiegbar, wel no keini Benutzer abgstumme hän (Adräss $1)', |
| 1149 | + 'qp_error_address_in_decl_mode' => 'Cha kei Adräss vu dr Abstimmig iberchuu im Verchindigs-Modus', |
| 1150 | + 'qp_error_question_not_implemented' => 'Forge vu däm Typ sin nit vorgsäh: $1', |
| 1151 | + 'qp_error_invalid_question_type' => 'Nit giltige Frogetyp: $1', |
| 1152 | + 'qp_error_type_in_stats_mode' => 'Frogetyp cha nit im statistische Widergabmodus definiert wäre: $1', |
| 1153 | + 'qp_error_no_poll_id' => 'D Eigeschaft „id“ (Chännnummere) isch nit definiert fir d Abstimmig.', |
| 1154 | + 'qp_error_invalid_poll_id' => 'Nit giltigi Abstimmigs-Chännnummere ($1). |
| 1155 | +In dr Chännnummere derf s nume Buechstabe, Zahle un Läärstelle haa.', |
| 1156 | + 'qp_error_already_used_poll_id' => 'Die Abstimmigs-Chännnummere wird schoi rbuc ht uf däre Syte ($1)', |
| 1157 | + 'qp_error_invalid_dependance_value' => 'D Abhängigkeits-Chette vu dr Abstimmig (id=$1) het e nit giltige Wärt vu dr Abhängigkeitseigeschaft („$2“)', |
| 1158 | + 'qp_error_missed_dependance_title' => 'D Abstimmig ($1) hangt aqb vun ere andere Abstimmig ($3) vu dr Syte [[$2]], aber dr Titel [[$2]] isch nit gfunde wore. |
| 1159 | +Entwäder due d Abhängigkeitseigeschaft uuseneh oder spychere [[$2]] um', |
| 1160 | + 'qp_error_missed_dependance_poll' => 'D Abstimmig ($1) isch abhängig vun ere andere Abstimmig ($3) uf dr Syte $2, aber sälli Abstimmig git s nit oder si isch nonig gspycheret wore. |
| 1161 | +Entwäder due d Abhängigkeitseigeschaft uuseneh oder leg d Abstimmig aa mit dr Chännnummere $3 uf dr Syte $2 un due si spychere. |
| 1162 | +Go ne Abstimmig spychere due si ibertrage ohni ne Antwort gee uf irged e Vorschlagsfrog.', |
| 1163 | + 'qp_error_vote_dependance_poll' => 'Bitte stimm zerscht ab in dr Abstimmig $1.', |
| 1164 | + 'qp_error_too_many_spans' => 'S sin zvyl Kategorieklasse definiert fir d Unterkategorie', |
| 1165 | + 'qp_error_unanswered_span' => 'Unterkategori ohni Antwort', |
| 1166 | + 'qp_error_non_unique_choice' => 'D Frog brucht ei einzige Vorschlags-Antwort', |
| 1167 | + 'qp_error_category_name_empty' => 'Kei Kategoriname aagee', |
| 1168 | + 'qp_error_proposal_text_empty' => 'Kei Vorschlagstext aagee', |
| 1169 | + 'qp_error_too_few_categories' => 'Zmindescht zwo Kategorie mien definiert wäre', |
| 1170 | + 'qp_error_too_few_spans' => 'Fir jedi Kategorieklasse brucht s zmindescht zwo definierti Antworte', |
| 1171 | + 'qp_error_no_answer' => 'Vorschlag ohni Antwort', |
| 1172 | + 'qp_error_unique' => 'Fir d Frog vum Typ unique() git s meh Vorschleg wie Antworte definiert sin: cha nit abgschlosse wäre', |
| 1173 | +); |
| 1174 | + |
| 1175 | +/** Hebrew (עברית) |
| 1176 | + * @author Amire80 |
| 1177 | + * @author YaronSh |
| 1178 | + */ |
| 1179 | +$messages['he'] = array( |
| 1180 | + 'pollresults' => 'תוצאות הסקרים באתר', |
| 1181 | + 'qp_desc' => 'מאפשר יצירת סקרים', |
| 1182 | + 'qp_desc-sp' => '[[Special:PollResults|דף מיוחד]] לצפייה בתוצאות הסקרים', |
| 1183 | + 'qp_result_NA' => 'לא נענה', |
| 1184 | + 'qp_result_error' => 'שגיאת תחביר', |
| 1185 | + 'qp_vote_button' => 'הצבעה', |
| 1186 | + 'qp_vote_again_button' => 'שינוי הצבעתכם', |
| 1187 | + 'qp_polls_list' => 'הצגת כל הסקרים', |
| 1188 | + 'qp_users_list' => 'הצגת כל המשתמשים', |
| 1189 | + 'qp_browse_to_poll' => 'עיון בסקר $1', |
| 1190 | + 'qp_browse_to_user' => 'עיון בחשבון $1', |
| 1191 | + 'qp_votes_count' => '{{PLURAL:$1|הצבעה אחת|$1 הצבעות}}', |
| 1192 | + 'qp_source_link' => 'מקור', |
| 1193 | + 'qp_stats_link' => 'סטטיסטיקה', |
| 1194 | + 'qp_users_link' => 'משתמשים', |
| 1195 | + 'qp_voice_link' => 'קול המשתמש', |
| 1196 | + 'qp_voice_link_inv' => 'קול המשתמש?', |
| 1197 | + 'qp_user_polls_link' => 'השתתף ב{{PLURAL:$1|סקר אחד|־$1 סקרים}}', |
| 1198 | + 'qp_user_missing_polls_link' => 'אין השתתפות', |
| 1199 | + 'qp_not_participated_link' => 'לא השתתף', |
| 1200 | + 'qp_order_by_username' => 'מיון לפי שם משתמש', |
| 1201 | + 'qp_order_by_polls_count' => 'מיון לפי מספר הסקרים', |
| 1202 | + 'qp_results_line_qupl' => 'הדף "$1" סקר "$2": $3', |
| 1203 | + 'qp_results_line_qpl' => 'הדף "$1" סקר "$2": $3, $4, $5, $6', |
| 1204 | + 'qp_header_line_qpul' => '$1 [ דף "$2" סקר "$3" ]', |
| 1205 | + 'qp_export_to_xls' => 'ייצוא הסטטיסטיקה לקובץ מסוג XLS', |
| 1206 | + 'qp_voices_to_xls' => 'ייצוא קולות לתסדיר XLS', |
| 1207 | + 'qp_users_answered_questions' => '{{PLURAL:$1|משתמש אחד ענה|$1 משתמשים ענו}} על השאלות', |
| 1208 | + 'qp_func_no_such_poll' => 'אין כזה סקר ($1)', |
| 1209 | + 'qp_func_missing_question_id' => "יש לציין מס' שאלה קיים (החל מ־1) עבור הסקר $1", |
| 1210 | + 'qp_func_invalid_question_id' => 'מזהה שאלה לא תקין=$2 (לא מספר) בסקר $1', |
| 1211 | + 'qp_func_missing_proposal_id' => 'נא להגדיר מזהה תשובה אפשירת קיים (מתחיל 0) לסקר $1, שאלה $2', |
| 1212 | + 'qp_func_invalid_proposal_id' => 'מזהה תשובה מוצעת לא תקין=$3 (לא מספר) בסקר $1, שאלה $2', |
| 1213 | + 'qp_error_no_such_poll' => 'אין סקר כזה ($1). |
| 1214 | +נא לוודא שהסקר מוכרז ושמור, ולוודא שנעשה שימוש בתו המפריד # בכתובת', |
| 1215 | + 'qp_error_in_question_header' => 'כותרת שאלה לא תקינה: $1', |
| 1216 | + 'qp_error_id_in_stats_mode' => "לא ניתן להצהיר על מס' עבור הסקר במצב סטטיסטי", |
| 1217 | + 'qp_error_dependance_in_stats_mode' => 'לא ניתן להכריז על שרשרת תלות של הסקר במצב סטטיסטיקה', |
| 1218 | + 'qp_error_no_stats' => 'אין נתונים סטטיסטיים זמינים כיוון שאף אחד עוד לא הצביע בסקר הזה, עדיין (כתובת=$1)', |
| 1219 | + 'qp_error_address_in_decl_mode' => 'לא ניתן לאחזר את כתובת הסקר במצב הצהרה', |
| 1220 | + 'qp_error_question_not_implemented' => 'שאלות מהסוג הזה אינן מיושמות: $1', |
| 1221 | + 'qp_error_invalid_question_type' => 'סוג השאלה שגוי: $1', |
| 1222 | + 'qp_error_type_in_stats_mode' => 'סוג השאלה לא ניתן להגדרה במצב תצוגה סטטיסטית: $1', |
| 1223 | + 'qp_error_no_poll_id' => 'לא מוגדר מאפיין id לתג סקר.', |
| 1224 | + 'qp_error_invalid_poll_id' => 'מזהה סקר לא תקין (id=$1). |
| 1225 | +מזהה הסקר יכול להכיל רק אותיות, ספרות ותו רווח', |
| 1226 | + 'qp_error_already_used_poll_id' => 'כבר נעשה שימוש במזהה הסקר בדף הזה (id=$1).', |
| 1227 | + 'qp_error_invalid_dependance_value' => 'לשרשרת התלות של הסקר (id=$1) יש ערך בלתי תקין של מאפיין dependance (dependance="$2")', |
| 1228 | + 'qp_error_missed_dependance_title' => 'הסקר (id=$1) תלוי בסקר אחר (id=$3) מהדף [[$2]], אבל הכותרת [[$2]] לא נמצאה. |
| 1229 | +הסירו את מאפיין התלות או שחזרו את [[$2]]', |
| 1230 | + 'qp_error_missed_dependance_poll' => 'הסקר (id=$1) תלוי בסקר אחר (id=$3) בדף $2, אבל הסקר ההוא אינו קיים או שהוא עדיין לא נשמר. |
| 1231 | +הסירו את מאפיין התלות או צרו סקר עם id=$3 בדף $2 ושִמרו אותו. |
| 1232 | +כדי לשמור סקר, שלחו אותו בלי לענות על השאלות.', |
| 1233 | + 'qp_error_vote_dependance_poll' => 'יש להצביע עבור הסקר $1 תחילה.', |
| 1234 | + 'qp_error_too_many_spans' => 'הוגדרו קבוצות קטגוריות רבות מדי עבור המספר הכולל של קטגוריות משנה', |
| 1235 | + 'qp_error_unanswered_span' => 'קטגוריית משנה ללא מענה', |
| 1236 | + 'qp_error_non_unique_choice' => 'שאלה זו מחייבת תשובה הצעה ייחודית', |
| 1237 | + 'qp_error_category_name_empty' => 'שם הקטגוריה ריק', |
| 1238 | + 'qp_error_proposal_text_empty' => 'טקסט ההצעה ריק', |
| 1239 | + 'qp_error_too_few_categories' => 'יש להגדיר לפחות שתי קטגוריות', |
| 1240 | + 'qp_error_too_few_spans' => 'כל קבוצת קטגוריות חייבת להכיל לפחות שתי תת־קטגוריות', |
| 1241 | + 'qp_error_no_answer' => 'הצעה שלא נענתה', |
| 1242 | + 'qp_error_unique' => 'לשאלה מסוג unique() יש יותר הצעות ממספר התשובות האפשריות מוגדרות: אי־אפשר להשלים', |
| 1243 | +); |
| 1244 | + |
| 1245 | +/** Upper Sorbian (Hornjoserbsce) |
| 1246 | + * @author Michawiki |
| 1247 | + */ |
| 1248 | +$messages['hsb'] = array( |
| 1249 | + 'pollresults' => 'Wuslědki wothłosowanjow na tutym sydle', |
| 1250 | + 'qp_desc' => 'Zmóžnja wutworjenje wothłosowanjow', |
| 1251 | + 'qp_desc-sp' => '[[Special:PollResults|Specialna strona]] za wobhladowanje wuslědkow wothłosowanjow', |
| 1252 | + 'qp_result_NA' => 'Njewotmołwjeny', |
| 1253 | + 'qp_result_error' => 'Syntaksowy zmylk', |
| 1254 | + 'qp_vote_button' => 'Hłosować', |
| 1255 | + 'qp_vote_again_button' => 'Twoje wothłosowanje změnić', |
| 1256 | + 'qp_polls_list' => 'Wšě wothłosowanja nalistować', |
| 1257 | + 'qp_users_list' => 'Wšěch wužiwarjow nalistować', |
| 1258 | + 'qp_browse_to_poll' => 'Dale k $1', |
| 1259 | + 'qp_browse_to_user' => 'Dale k $1', |
| 1260 | + 'qp_votes_count' => '$1 {{PLURAL:$1|hłós|hłosaj|hłosy|hłosow}}', |
| 1261 | + 'qp_source_link' => 'Žórło', |
| 1262 | + 'qp_stats_link' => 'Statistika', |
| 1263 | + 'qp_users_link' => 'Wužiwarjo', |
| 1264 | + 'qp_voice_link' => 'Wužiwarski hłós', |
| 1265 | + 'qp_voice_link_inv' => 'Wužiwarski hłós?', |
| 1266 | + 'qp_user_polls_link' => 'Wobdźěli so na $1 {{PLURAL:$1|wothłosownju|wothłosowanjomaj|wothłosowanjach|wothłosowanjach}}', |
| 1267 | + 'qp_user_missing_polls_link' => 'Žane wobdźělenje', |
| 1268 | + 'qp_not_participated_link' => 'Njewobdźěleny', |
| 1269 | + 'qp_order_by_username' => 'Porjad po wužiwarskim mjenje', |
| 1270 | + 'qp_order_by_polls_count' => 'Porjad po ličbje wothłosowanjow', |
| 1271 | + 'qp_results_line_qupl' => 'Strona "$1" wothłosowanje "$2": $3', |
| 1272 | + 'qp_results_line_qpl' => 'Strona "$1" wothłosowanje "$2": $3, $4, $5, $6', |
| 1273 | + 'qp_header_line_qpul' => '$1 [ strona "$2" wothłosowanje "$3" ]', |
| 1274 | + 'qp_export_to_xls' => 'Statistiku do XLS-formata eksportować', |
| 1275 | + 'qp_voices_to_xls' => 'Hłosy do XLS-formata eksportować', |
| 1276 | + 'qp_users_answered_questions' => '$1 {{PLURAL:$1|wužiwar je|wužiwarjej staj|wužiwarjo su|wužiwarjow je}} na prašenja {{PLURAL:$1|wotmołwił|wotmołwiłoj|wotmołwili|wotmołwiło}}', |
| 1277 | + 'qp_func_no_such_poll' => 'Žane tajke wothłosowanje ($1)', |
| 1278 | + 'qp_func_missing_question_id' => 'Prošu podaj eksistowacy prašenski ID (započinajo wot 1) za wothłosowanje $1', |
| 1279 | + 'qp_func_invalid_question_id' => 'Njepłaćiwe prašenje id=$2 (žana ličba) za wothłosowanje $1', |
| 1280 | + 'qp_func_missing_proposal_id' => 'Prošu podaj eksistowacy namjetowy ID (započinajo wot 0) za naprašowanje $1, prašenje $2', |
| 1281 | + 'qp_func_invalid_proposal_id' => 'Njepłaćiwy namjet id=$3 (žana ličba) za wothłosowanje $1, prašenje $2', |
| 1282 | + 'qp_error_no_such_poll' => 'Tajke wothłosowanje njeje ($1). |
| 1283 | +Zawěsć, zo wothłosowanje bu deklarowane a składowane, přeswědč so, zo wužiwaš adresowe dźělatko #', |
| 1284 | + 'qp_error_in_question_header' => 'Njepłaćiwy prašenski typ: $1', |
| 1285 | + 'qp_error_id_in_stats_mode' => 'Njeje móžno ID wothłosowanja w statistiskim modusu deklarowác', |
| 1286 | + 'qp_error_dependance_in_stats_mode' => 'Njeje móžno wotwisnosćowy rjećazk wothłosowanja w statistiskim modusu deklarować', |
| 1287 | + 'qp_error_no_stats' => 'Žane statistiske daty k dispoziciji, dokelž dotal nichtó njeje za tute wothłosowanje hłosował (adresa=$1)', |
| 1288 | + 'qp_error_address_in_decl_mode' => 'Njeje móžno adresu wothłosowanja w deklaraciskim modusu dóstać', |
| 1289 | + 'qp_error_question_not_implemented' => 'Prašenja tutoho typa njejsu implementowane: $1', |
| 1290 | + 'qp_error_invalid_question_type' => 'Njepłaćiwy prašenski typ: $1', |
| 1291 | + 'qp_error_type_in_stats_mode' => 'Prašenski typ njeda so w statistiskim zwobraznjenskim modusu definować: $1', |
| 1292 | + 'qp_error_no_poll_id' => 'Taflička Poll njeje atribut ID definował.', |
| 1293 | + 'qp_error_invalid_poll_id' => 'Njepłaćiwy Id wothłosowanja (ID=$1). |
| 1294 | +ID wothłosowanja smě jenož pismiki, ličby a mjezeru wobsahować', |
| 1295 | + 'qp_error_already_used_poll_id' => 'ID wothłosowanja wužiwa so hižo na tutej stronje (ID=$1).', |
| 1296 | + 'qp_error_invalid_dependance_value' => 'Wotwisnosćowy rjećazk wothłosowanja (id=$1) ma njepłaćiwu hódnotu atributa dependance (dependance="$2")', |
| 1297 | + 'qp_error_missed_dependance_title' => 'Wothłosowanje (ID=$1) je wot druheho wothłosowanja (ID=$3) ze strony [[$2]] wotwisne, ale titul [[$2]] njebu namakany. Wotstroń pak atribut dependance pak wobnow [[$2]]', |
| 1298 | + 'qp_error_missed_dependance_poll' => 'Wothłosowanje (ID=$1) je wot druheho wothłosowanja (ID=$3) na stronje $2 wotwisne, ale te wothłosowanje njeeksistuje abo njeje so składowało. |
| 1299 | +Wotstroń pak atribut dependance pak wutwor wothłosowanje z ID=$3 na stronje $2 a składuj jo. |
| 1300 | +Zo by wothłosowanje składował, wotpósćel jo, bjeztoho zo by na namjetowe prašenja wotmołwił.', |
| 1301 | + 'qp_error_vote_dependance_poll' => 'Prošu hłosuj najprjedy za wothłosowanje $1.', |
| 1302 | + 'qp_error_too_many_spans' => 'Přewjele kategorijowych klasow za podkategorije definowane', |
| 1303 | + 'qp_error_unanswered_span' => 'Njewotmołwjena podkategorija', |
| 1304 | + 'qp_error_non_unique_choice' => 'Tute prašenje trjeba jónkróćnu namjetowu wotmołwu', |
| 1305 | + 'qp_error_category_name_empty' => 'Kategorijowe mjeno je prózdne', |
| 1306 | + 'qp_error_proposal_text_empty' => 'Namjetowy tekst je prózdny', |
| 1307 | + 'qp_error_too_few_categories' => 'Znajmjeńša dwě kategoriji dyrbitej so definować', |
| 1308 | + 'qp_error_too_few_spans' => 'Kóžda kategorijowa klasa trjeba znajmjeńša dwě móžnej definowanej wotmołwje', |
| 1309 | + 'qp_error_no_answer' => 'Njewotmołwjeny namjet', |
| 1310 | + 'qp_error_unique' => 'Prašenje typa unique() ma wjace namjetow hač su móžne wotmołwy definowane: njemóžno pokročować', |
| 1311 | +); |
| 1312 | + |
| 1313 | +/** Hungarian (Magyar) |
| 1314 | + * @author Dani |
| 1315 | + * @author Glanthor Reviol |
| 1316 | + */ |
| 1317 | +$messages['hu'] = array( |
| 1318 | + 'pollresults' => 'Az oldal szavazásainak eredményei', |
| 1319 | + 'qp_desc' => 'Lehetővé teszi szavazások készítését', |
| 1320 | + 'qp_desc-sp' => '[[Special:PollResults|Speciális lap]] a szavazások eredményeinek megtekintésére', |
| 1321 | + 'qp_result_NA' => 'Nem válaszolt', |
| 1322 | + 'qp_result_error' => 'Szintaktikai hiba', |
| 1323 | + 'qp_vote_button' => 'Szavazás', |
| 1324 | + 'qp_vote_again_button' => 'Szavazat megváltoztatása', |
| 1325 | + 'qp_polls_list' => 'Szavazások listája', |
| 1326 | + 'qp_users_list' => 'Felhasználók listája', |
| 1327 | + 'qp_browse_to_poll' => 'Ugrás a szavazás helyére: $1', |
| 1328 | + 'qp_browse_to_user' => 'A felhasználó lapja: $1', |
| 1329 | + 'qp_votes_count' => '$1 szavazat', |
| 1330 | + 'qp_source_link' => 'Forrás', |
| 1331 | + 'qp_stats_link' => 'Statisztika', |
| 1332 | + 'qp_users_link' => 'Felhasználók', |
| 1333 | + 'qp_voice_link' => 'A felhasználó szavazatai', |
| 1334 | + 'qp_voice_link_inv' => 'A felhasználó szavazatai?', |
| 1335 | + 'qp_user_polls_link' => '$1 szavazáson vett részt', |
| 1336 | + 'qp_user_missing_polls_link' => 'Nem vett részt', |
| 1337 | + 'qp_not_participated_link' => 'Nem vett részt', |
| 1338 | + 'qp_order_by_username' => 'Rendezés felhasználónév szerint', |
| 1339 | + 'qp_order_by_polls_count' => 'Rendezés a szavazások száma szerint', |
| 1340 | + 'qp_results_line_qupl' => 'Lap: „$1”, szavazás: „$2”: $3', |
| 1341 | + 'qp_results_line_qpl' => 'Lap: „$1”, szavazás: „$2”: $3, $4, $5, $6', |
| 1342 | + 'qp_header_line_qpul' => '$1 [ Lap: „$2”, szavazás: „$3” ]', |
| 1343 | + 'qp_export_to_xls' => 'Statisztikák exportálása XLS-formátumban', |
| 1344 | + 'qp_users_answered_questions' => '$1 felhasználó válaszolt a kérdésekre', |
| 1345 | + 'qp_func_no_such_poll' => 'Nincs ilyen szavazás ($1)', |
| 1346 | + 'qp_func_missing_question_id' => 'Add meg egy létező kérdés azonosítóját (1-től kezdve) a(z) $1 szavazáshoz', |
| 1347 | + 'qp_func_invalid_question_id' => 'Érvénytelen kérdés id=$2 (nem szám) a(z) $1 szavazáshoz', |
| 1348 | + 'qp_func_missing_proposal_id' => 'Add meg egy létező javaslat azonosítóját (0-tól kezdve) a(z) $1 szavazás $2 kérdéséhez', |
| 1349 | + 'qp_func_invalid_proposal_id' => 'Érvénytelen javaslat id=$3 (nem szám) a(z) $1 szavazás $2 kérdéséhez', |
| 1350 | + 'qp_error_no_such_poll' => 'Nincs ilyen szavazás ($1). |
| 1351 | +Győződj meg róla, hogy a szavazás deklarálva van, és elmentetted, valamint hogy használtad-e a címhatároló karaktert (#)', |
| 1352 | + 'qp_error_in_question_header' => 'Érvénytelen kérdés-fejléc: $1', |
| 1353 | + 'qp_error_id_in_stats_mode' => 'Nem deklarálható egy szavazás azonosítója statisztikai módban', |
| 1354 | + 'qp_error_dependance_in_stats_mode' => 'Nem deklarálható a szavazás függőségi lánca statisztikai módban', |
| 1355 | + 'qp_error_no_stats' => 'A statisztikai adatok nem elérhetőek, mert még senki sem szavazott ezen a szavazáson (address=$1)', |
| 1356 | + 'qp_error_address_in_decl_mode' => 'A szavazás címe nem kérhető le deklarációs módban', |
| 1357 | + 'qp_error_question_not_implemented' => 'Az ilyen típusú kérdések nincsenek implementálva: $1', |
| 1358 | + 'qp_error_invalid_question_type' => 'Érvénytelen kérdéstípus: $1', |
| 1359 | + 'qp_error_type_in_stats_mode' => 'A kérdés típusát nem lehet megadni statisztikai módban: $1', |
| 1360 | + 'qp_error_no_poll_id' => 'A szavazás tagnek nincs azonosító (id) attribútuma megadva.', |
| 1361 | + 'qp_error_invalid_poll_id' => 'Érvénytelen szavazásazonosító (id=$1). |
| 1362 | +A szavazásazonosító csak betűket, számokat és szóközt tartalmazhat', |
| 1363 | + 'qp_error_already_used_poll_id' => 'Ez a szavazásazonosító már használva volt korábban ezen a lapon (id=$1).', |
| 1364 | + 'qp_error_invalid_dependance_value' => 'A szavazás (id=$1) függőségi lánca érvénytelen függőségi attribútum-értékkel rendelkezik (dependance="$2")', |
| 1365 | + 'qp_error_missed_dependance_title' => 'A szavazás (id=$1) függ a(z) [[$2]] lapon található másik szavazástól (id=$3), de ez a lap nem található. |
| 1366 | +Vagy távolítsd el a függőségi attribútumot, vagy állítsd helyre a(z) [[$2]] lapot.', |
| 1367 | + 'qp_error_missed_dependance_poll' => 'A szavazás (id=$1) függ egy, a(z) $2 lapon található másik szavazástól (id=$3), de ez a szavazás nem létezik, vagy még nem lett elmentve. |
| 1368 | +Távolítsd el a függőségi attribútumot, vagy készítsd el a(z) id=$3 azonosítóval rendelkező szavazást a(z) $2 lapon, és mentsd el. |
| 1369 | +A szavazás elmentéséhez küldd el azt anélkül, hogy válaszolnál bármelyik kérdésre.', |
| 1370 | + 'qp_error_vote_dependance_poll' => 'Először szavazz a(z) $1 szavazáson.', |
| 1371 | + 'qp_error_too_many_spans' => 'Túl sok kategóriaosztály lett az alkategóriák számára megadva.', |
| 1372 | + 'qp_error_unanswered_span' => 'Megválaszolatlan alkategória', |
| 1373 | + 'qp_error_non_unique_choice' => 'Ennek kérdésnek egyedi javasolt válaszra van szüksége', |
| 1374 | + 'qp_error_category_name_empty' => 'A kategória neve üres', |
| 1375 | + 'qp_error_proposal_text_empty' => 'A javaslat szövege üres', |
| 1376 | + 'qp_error_too_few_categories' => 'Legalább két kategóriát kell megadni', |
| 1377 | + 'qp_error_too_few_spans' => 'Mindegyik kategóriaosztályhoz meg kell adni legalább két lehetséges választ', |
| 1378 | + 'qp_error_no_answer' => 'Megválaszolatlan javaslat', |
| 1379 | + 'qp_error_unique' => 'A unique() típus kérdése több javaslattal rendelkezik, mint a megadott lehetséges válaszol száma: nem lehet befejezni', |
| 1380 | +); |
| 1381 | + |
| 1382 | +/** Interlingua (Interlingua) |
| 1383 | + * @author McDutchie |
| 1384 | + */ |
| 1385 | +$messages['ia'] = array( |
| 1386 | + 'pollresults' => 'Resultatos del sondages in iste sito', |
| 1387 | + 'qp_desc' => 'Permitte le creation de sondages', |
| 1388 | + 'qp_desc-sp' => '[[Special:PollResults|Pagina special]] pro vider le resultatos del sondages', |
| 1389 | + 'qp_result_NA' => 'Sin responsa', |
| 1390 | + 'qp_result_error' => 'Error de syntaxe', |
| 1391 | + 'qp_vote_button' => 'Votar', |
| 1392 | + 'qp_vote_again_button' => 'Modificar tu voto', |
| 1393 | + 'qp_polls_list' => 'Listar tote le sondages', |
| 1394 | + 'qp_users_list' => 'Listar tote le usatores', |
| 1395 | + 'qp_browse_to_poll' => 'Navigar verso $1', |
| 1396 | + 'qp_browse_to_user' => 'Navigar verso $1', |
| 1397 | + 'qp_votes_count' => '$1 {{PLURAL:$1|voto|votos}}', |
| 1398 | + 'qp_source_link' => 'Origine', |
| 1399 | + 'qp_stats_link' => 'Statisticas', |
| 1400 | + 'qp_users_link' => 'Usatores', |
| 1401 | + 'qp_voice_link' => 'Voce del usator', |
| 1402 | + 'qp_voice_link_inv' => 'Voce de usator?', |
| 1403 | + 'qp_user_polls_link' => 'Participava in $1 {{PLURAL:$1|sondage|sondages}}', |
| 1404 | + 'qp_user_missing_polls_link' => 'Nulle participation', |
| 1405 | + 'qp_not_participated_link' => 'Non participate', |
| 1406 | + 'qp_order_by_username' => 'Ordinar per nomine de usator', |
| 1407 | + 'qp_order_by_polls_count' => 'Ordinar per numero de sondages', |
| 1408 | + 'qp_results_line_qupl' => 'Pagina "$1" Sondage "$2": $3', |
| 1409 | + 'qp_results_line_qpl' => 'Pagina "$1" Sondage "$2": $3, $4, $5, $6', |
| 1410 | + 'qp_header_line_qpul' => '$1 [ Pagina "$2" Sondage "$3" ]', |
| 1411 | + 'qp_export_to_xls' => 'Exportar statisticas in formato XLS', |
| 1412 | + 'qp_voices_to_xls' => 'Exportar voces in formato XLS', |
| 1413 | + 'qp_users_answered_questions' => 'usatores respondeva al questiones', |
| 1414 | + 'qp_func_no_such_poll' => 'Sondage non existe ($1)', |
| 1415 | + 'qp_func_missing_question_id' => 'Per favor specifica le ID de un question existente (a partir de 1) pro le sondage $1', |
| 1416 | + 'qp_func_invalid_question_id' => 'Question invalide id=$2 (non un numero) pro le sondage $1', |
| 1417 | + 'qp_func_missing_proposal_id' => 'Per favor specifica un ID de proposition existente (a partir de 0) pro le sondage $1, question $2', |
| 1418 | + 'qp_func_invalid_proposal_id' => 'ID de proposition invalide "$3" (non un numero) pro le sondage $1, question $2', |
| 1419 | + 'qp_error_no_such_poll' => 'Sondage non existe ($1). |
| 1420 | +Verifica que le sondage ha essite declarate e salveguardate, e que le character # es usate como delimitator de adresse.', |
| 1421 | + 'qp_error_in_question_header' => 'Titulo de question invalide: $1', |
| 1422 | + 'qp_error_id_in_stats_mode' => 'Non pote declarar un ID del sondage in modo statistic', |
| 1423 | + 'qp_error_dependance_in_stats_mode' => 'Non pote declarar le catena de dependentia del sondage in modo statistic', |
| 1424 | + 'qp_error_no_stats' => 'Nulle dato statistic es disponibile, proque necuno ha ancora votate pro iste sondage (adresse=$1)', |
| 1425 | + 'qp_error_address_in_decl_mode' => 'Non pote obtener un adresse del sondage in modo declarative', |
| 1426 | + 'qp_error_question_not_implemented' => 'Le questiones de iste typo non es implementate: $1', |
| 1427 | + 'qp_error_invalid_question_type' => 'Typo de question invalide: $1', |
| 1428 | + 'qp_error_type_in_stats_mode' => 'Le typo de question non pote esser definite in modo de presentation statistic: $1', |
| 1429 | + 'qp_error_no_poll_id' => 'Le etiquetta del sondage non ha un attributo "id" definite.', |
| 1430 | + 'qp_error_invalid_poll_id' => 'ID de sondage invalide (id=$1). |
| 1431 | +Le ID del sondage pote continer solmente litteras, numeros e le character de spatio.', |
| 1432 | + 'qp_error_already_used_poll_id' => 'Le ID del sondage ha ja essite usate in iste pagina (id=$1).', |
| 1433 | + 'qp_error_invalid_dependance_value' => 'Le catena de dependentia del sondage (id=$1) ha un valor invalide del attributo de dependentia (dependance="$2")', |
| 1434 | + 'qp_error_missed_dependance_title' => 'Le sondage (id=$1) depende de un altere sondage (id=$3) del pagina [[$2]], ma le titulo [[$2]] non ha essite trovate. |
| 1435 | +O remove le attributo de dependentia, o restaura [[$2]].', |
| 1436 | + 'qp_error_missed_dependance_poll' => 'Le sondage (id=$1) depende de un altere sondage (id=$3) al pagina $2, ma ille sondage non existe o non ha ancora essite salveguardate. |
| 1437 | +O remove le attributo de dependentia, o crea le sondage con id=$3 al pagina $2 e salveguarda lo. |
| 1438 | +Pro salveguardar un sondage, submitte lo sin responder a alcun question de proposition.', |
| 1439 | + 'qp_error_vote_dependance_poll' => 'Per favor vota primo pro le sondage $1.', |
| 1440 | + 'qp_error_too_many_spans' => 'Troppo de classes de categoria pro le subcategorias definite', |
| 1441 | + 'qp_error_unanswered_span' => 'Subcategoria sin responsa', |
| 1442 | + 'qp_error_non_unique_choice' => 'Iste question require un responsa de proposition unic', |
| 1443 | + 'qp_error_category_name_empty' => 'Le nomine del categoria es vacue', |
| 1444 | + 'qp_error_proposal_text_empty' => 'Le texto del proposition es vacue', |
| 1445 | + 'qp_error_too_few_categories' => 'Al minus duo categorias debe esser definite', |
| 1446 | + 'qp_error_too_few_spans' => 'Cata classe de categoria require le definition de al minus duo responsas possibile', |
| 1447 | + 'qp_error_no_answer' => 'Proposition sin responsa', |
| 1448 | + 'qp_error_unique' => 'Pro le question de typo unique() es definite plus propositiones que responsas possibile: non pote completar', |
| 1449 | +); |
| 1450 | + |
| 1451 | +/** Indonesian (Bahasa Indonesia) |
| 1452 | + * @author Farras |
| 1453 | + * @author IvanLanin |
| 1454 | + */ |
| 1455 | +$messages['id'] = array( |
| 1456 | + 'pollresults' => 'Hasil pemilihan di situs ini', |
| 1457 | + 'qp_desc' => 'Izinkan pembuatan pemilihan', |
| 1458 | + 'qp_desc-sp' => '[[Special:PollResults|Halaman khusus]] untuk melihat hasil pemilihan', |
| 1459 | + 'qp_result_NA' => 'Tak dijawab', |
| 1460 | + 'qp_result_error' => 'Kesalahan sintaks', |
| 1461 | + 'qp_vote_button' => 'Pilih', |
| 1462 | + 'qp_vote_again_button' => 'Ubah pilihan Anda', |
| 1463 | + 'qp_polls_list' => 'Daftar semua pemilihan', |
| 1464 | + 'qp_users_list' => 'Daftar semua pengguna', |
| 1465 | + 'qp_browse_to_poll' => 'Cari ke $1', |
| 1466 | + 'qp_browse_to_user' => 'Tamban ke $1', |
| 1467 | + 'qp_votes_count' => '$1 {{PLURAL:$1|suara|suara}}', |
| 1468 | + 'qp_source_link' => 'Sumber', |
| 1469 | + 'qp_stats_link' => 'Statistik', |
| 1470 | + 'qp_users_link' => 'Pengguna', |
| 1471 | + 'qp_voice_link' => 'Suara pengguna', |
| 1472 | + 'qp_voice_link_inv' => 'Suara pengguna?', |
| 1473 | + 'qp_user_polls_link' => 'Berpartisipasi dalam $1 {{PLURAL:$1|pemilihan|pemilihan}}', |
| 1474 | + 'qp_user_missing_polls_link' => 'Tak ada partisipasi', |
| 1475 | + 'qp_not_participated_link' => 'Tidak berpartisipasi', |
| 1476 | + 'qp_order_by_username' => 'Urutan menurut nama pengguna', |
| 1477 | + 'qp_order_by_polls_count' => 'Urutan menurut jumlah pemilihan', |
| 1478 | + 'qp_results_line_qupl' => 'Halaman "$1" Pemilihan "$2": $3', |
| 1479 | + 'qp_results_line_qpl' => 'Halaman "$1" Pemilihan "$2": $3, $4, $5, $6', |
| 1480 | + 'qp_header_line_qpul' => '$1 [ Halaman "$2" Pemilihan "$3" ]', |
| 1481 | + 'qp_export_to_xls' => 'Ekspor statistik ke dalam format XLS', |
| 1482 | + 'qp_voices_to_xls' => 'Ekspor suara ke format XLS', |
| 1483 | + 'qp_users_answered_questions' => '$1 {{PLURAL:$1|pengguna|pengguna}} telah menjawab pertanyaan', |
| 1484 | + 'qp_func_no_such_poll' => 'Tidak ada pemilihan ($1)', |
| 1485 | + 'qp_func_missing_question_id' => 'Silakan masukkan suatu nomor pertanyaan yang ada (mulai dari 1) untuk pemilihan $1', |
| 1486 | + 'qp_func_invalid_question_id' => 'Pertanyaan salah id=$2 (bukan angka) untuk pemilihan $1', |
| 1487 | + 'qp_func_missing_proposal_id' => 'Silakan masukkan suatu nomor proposal yang ada (mulai dari 0) untuk pemilihan $1, pertanyaan $2', |
| 1488 | + 'qp_func_invalid_proposal_id' => 'Proposal salah id=$3 (bukan angka) untuk pemilihan $1, pertanyaan $2', |
| 1489 | + 'qp_error_no_such_poll' => 'Pemilihan tidak ditemukan ($1). |
| 1490 | +Pastikan bahwa pemilihan telah dibuat dan disimpan. Pastikan untuk menggunakan karakter penanda alamat #', |
| 1491 | + 'qp_error_in_question_header' => 'Kepala pertanyaan tidak sah: $1', |
| 1492 | + 'qp_error_id_in_stats_mode' => 'Tidak dapat menetapkan ID pemilihan dalam mode statistik', |
| 1493 | + 'qp_error_dependance_in_stats_mode' => 'Tidak dapat menetapkan rantai dependensi pemilihan dalam modus statistik', |
| 1494 | + 'qp_error_no_stats' => 'Tidak ada data statistik tersedia, karena belum ada yang memilih pada pemilihan ini (address=$1)', |
| 1495 | + 'qp_error_address_in_decl_mode' => 'Tidak dapat memperoleh alamat pemilihan dalam modus deklarasi', |
| 1496 | + 'qp_error_question_not_implemented' => 'Pertanyaan dengan jenis itu belum diberlakukan: $1', |
| 1497 | + 'qp_error_invalid_question_type' => 'Jenis pertanyaan salah: $1', |
| 1498 | + 'qp_error_type_in_stats_mode' => 'Jenis pertanyaan tak dapat ditetapkan dalam mode tampilan statistik: $1', |
| 1499 | + 'qp_error_no_poll_id' => 'Tag pemilihan tidak memiliki atribut nomor.', |
| 1500 | + 'qp_error_invalid_poll_id' => 'ID pemilihan salah (id=$1) |
| 1501 | +ID pemilihan hanya boleh berisi huruf, angka dan spasi', |
| 1502 | + 'qp_error_already_used_poll_id' => 'ID pemilihan telah digunakan di halaman ini (id=$1)', |
| 1503 | + 'qp_error_invalid_dependance_value' => 'Rantai dependensi pemilihan (nomor=$1) memiliki nilai atribut dependensi tidak sah (dependensi="$2")', |
| 1504 | + 'qp_error_missed_dependance_title' => 'Pemilihan (nomor=$1) tergantung kepada pemilihan lain (nomor=$3) dari halaman [[$2]], tetapi judul [[$2]] tidak ditemukan. |
| 1505 | +Hapus atribut dependensi atau pulihkan [[$2]]', |
| 1506 | + 'qp_error_missed_dependance_poll' => 'Pemilihan (id=$1) tergantung kepada pemilihan lain (id=$3) pada halaman $2, tetapi pemilihan tersebut tidak ada atau belum disimpan. |
| 1507 | +Hapus atribut dependensi atau buat dan simpan pemilihan dengan id=$3 pada halaman $2. |
| 1508 | +Untuk menyimpan pemilihan, kirimkan tanpa menjawab pertanyaan proposal.', |
| 1509 | + 'qp_error_vote_dependance_poll' => 'Mohon pilih pada pemilihan $1 dahulu.', |
| 1510 | + 'qp_error_too_many_spans' => 'Terlalu banyak kelas kategori untuk subkategori yang ditetapkan', |
| 1511 | + 'qp_error_unanswered_span' => 'Subkategori belum terjawab', |
| 1512 | + 'qp_error_non_unique_choice' => 'Pertanyaan ini membutuhkan jawaban proposal yang unik', |
| 1513 | + 'qp_error_category_name_empty' => 'Nama kategori kosong', |
| 1514 | + 'qp_error_proposal_text_empty' => 'Teks proposal kosong', |
| 1515 | + 'qp_error_too_few_categories' => 'Sedikitnya dua kategori harus ditetapkan', |
| 1516 | + 'qp_error_too_few_spans' => 'Setiap kelas kategori membutuhkan sedikitnya dua jawaban', |
| 1517 | + 'qp_error_no_answer' => 'Proposal belum terjawab', |
| 1518 | + 'qp_error_unique' => 'Pertanyaan dari jenis unique() memiliki lebih banyak proposal daripada kemungkinan jawaban yang didefinisikan: mustahil untuk menyelesaikan', |
| 1519 | +); |
| 1520 | + |
| 1521 | +/** Italian (Italiano) */ |
| 1522 | +$messages['it'] = array( |
| 1523 | + 'qp_result_error' => 'Errore di sintassi', |
| 1524 | + 'qp_vote_button' => 'Vota', |
| 1525 | + 'qp_source_link' => 'Fonte', |
| 1526 | + 'qp_stats_link' => 'Statistiche', |
| 1527 | + 'qp_users_link' => 'Utenti', |
| 1528 | +); |
| 1529 | + |
| 1530 | +/** Japanese (日本語) |
| 1531 | + * @author Aotake |
| 1532 | + * @author Fryed-peach |
| 1533 | + * @author Whym |
| 1534 | + */ |
| 1535 | +$messages['ja'] = array( |
| 1536 | + 'pollresults' => 'このサイトでの投票結果', |
| 1537 | + 'qp_desc' => '投票を実施できるようにする', |
| 1538 | + 'qp_desc-sp' => '投票結果を見るための[[Special:PollResults|特別ページ]]', |
| 1539 | + 'qp_result_NA' => '回答されていません', |
| 1540 | + 'qp_result_error' => '構文エラー', |
| 1541 | + 'qp_vote_button' => '投票', |
| 1542 | + 'qp_vote_again_button' => 'あなたの票を変更', |
| 1543 | + 'qp_polls_list' => '全投票一覧', |
| 1544 | + 'qp_users_list' => '全利用者一覧', |
| 1545 | + 'qp_browse_to_poll' => '$1 を閲覧', |
| 1546 | + 'qp_browse_to_user' => '$1 を閲覧', |
| 1547 | + 'qp_votes_count' => '$1{{PLURAL:$1|票}}', |
| 1548 | + 'qp_source_link' => '投票場所', |
| 1549 | + 'qp_stats_link' => '統計', |
| 1550 | + 'qp_users_link' => '利用者', |
| 1551 | + 'qp_voice_link' => '利用者の声', |
| 1552 | + 'qp_voice_link_inv' => '利用者の声?', |
| 1553 | + 'qp_user_polls_link' => '$1件の{{PLURAL:$1|投票}}に参加', |
| 1554 | + 'qp_user_missing_polls_link' => '参加なし', |
| 1555 | + 'qp_not_participated_link' => '未参加', |
| 1556 | + 'qp_order_by_username' => '利用者名順に整列', |
| 1557 | + 'qp_order_by_polls_count' => '投票数順に整列', |
| 1558 | + 'qp_results_line_qupl' => 'ページ「$1」投票「$2」: $3', |
| 1559 | + 'qp_results_line_qpl' => 'ページ「$1」投票「$2」: $3、$4、$5、$6', |
| 1560 | + 'qp_header_line_qpul' => '$1 [ ページ「$2」投票「$3」]', |
| 1561 | + 'qp_export_to_xls' => '統計を XLS 形式でエクスポート', |
| 1562 | + 'qp_voices_to_xls' => 'すべての投票をXLS形式でエクスポートする', |
| 1563 | + 'qp_users_answered_questions' => '$1{{PLURAL:$1|人}}の利用者がこの質問に答えました', |
| 1564 | + 'qp_func_no_such_poll' => 'そのような投票はありません ($1)', |
| 1565 | + 'qp_func_missing_question_id' => '投票 $1 に存在する質問 ID を指定してください (1から始まります)', |
| 1566 | + 'qp_func_invalid_question_id' => '投票 $1 に対して無効な質問 ID ($2 は数値ではありません)', |
| 1567 | + 'qp_func_missing_proposal_id' => '投票 $1、質問 $2 に存在する提案 ID を指定してください (1から始まります)', |
| 1568 | + 'qp_func_invalid_proposal_id' => '投票 $1、質問 $2 に対して無効な提案 ID ($3 は数値ではありません)', |
| 1569 | + 'qp_error_no_such_poll' => 'そのような投票はありません ($1)。 |
| 1570 | +その投票が宣言され保存されていること、およびアドレス区切り記号 # を使っていることを確認してください。', |
| 1571 | + 'qp_error_in_question_header' => '無効な質問見出し: $1', |
| 1572 | + 'qp_error_id_in_stats_mode' => '統計モードでは投票の ID を宣言できません', |
| 1573 | + 'qp_error_dependance_in_stats_mode' => '統計モードでは投票の依存性チェーンを宣言できません', |
| 1574 | + 'qp_error_no_stats' => 'まだ誰もこの投票に投票していないので、統計データはありません (アドレス $1)', |
| 1575 | + 'qp_error_address_in_decl_mode' => '宣言モードでは投票のアドレスを取得できません', |
| 1576 | + 'qp_error_question_not_implemented' => 'そのタイプの質問は実装されていません: $1', |
| 1577 | + 'qp_error_invalid_question_type' => '無効な質問タイプ: $1', |
| 1578 | + 'qp_error_type_in_stats_mode' => '質問タイプは統計表示モードでは定義できません: $1', |
| 1579 | + 'qp_error_no_poll_id' => '投票タグに id 属性がありません。', |
| 1580 | + 'qp_error_invalid_poll_id' => '無効な投票 ID (id=$1)。 |
| 1581 | +投票 ID はアルファベット、数字、スペースのみを含むことができます。', |
| 1582 | + 'qp_error_already_used_poll_id' => 'その投票 ID は既にこのページで使われています (id=$1)。', |
| 1583 | + 'qp_error_invalid_dependance_value' => 'この投票 (id=$1) の依存性チェーンには依存性属性に不正な値があります (dependance="$2")', |
| 1584 | + 'qp_error_missed_dependance_title' => 'この投票 (id=$1) はページ [[$2]] の別の投票 (id=$3) に依存していますが、ページ名 [[$2]] は見つかりませんでした。依存性属性を削除するか、[[$2]] を復帰させてください', |
| 1585 | + 'qp_error_missed_dependance_poll' => 'この投票 (id=$1) はページ $2 の別の投票 (id=$3) に依存していますが、その投票が存在しないかまだ保存されていません。依存性属性を削除するか、ページ $2 で id=$3 の投票を作成してください。投票を保存するには、どの提案質問にも答えずに投稿してください。', |
| 1586 | + 'qp_error_vote_dependance_poll' => '初めに投票 $1 に投票してください。', |
| 1587 | + 'qp_error_too_many_spans' => 'このサブカテゴリーに対して定義されているカテゴリーが多すぎます', |
| 1588 | + 'qp_error_unanswered_span' => '未回答のサブカテゴリー', |
| 1589 | + 'qp_error_non_unique_choice' => 'この質問には答えとして独自の提案が必要です', |
| 1590 | + 'qp_error_category_name_empty' => 'カテゴリー名が空です', |
| 1591 | + 'qp_error_proposal_text_empty' => '提案文が空です', |
| 1592 | + 'qp_error_too_few_categories' => '最低でも2つのカテゴリーが定義されなければなりません', |
| 1593 | + 'qp_error_too_few_spans' => 'どのカテゴリーも最低でも2つの回答がとり得るように定義されなければなりません', |
| 1594 | + 'qp_error_no_answer' => '未回答の提案', |
| 1595 | + 'qp_error_unique' => 'タイプが unique() の質問には回答可能なものより多くの質問が定義されています。すべてに記入することはできません', |
| 1596 | +); |
| 1597 | + |
| 1598 | +/** Colognian (Ripoarisch) |
| 1599 | + * @author Purodha |
| 1600 | + */ |
| 1601 | +$messages['ksh'] = array( |
| 1602 | + 'pollresults' => 'Wat bei dä Affschtemmunge en heh däm Wiki eruß gekumme es', |
| 1603 | + 'qp_parentheses' => '(<code>$1</code>)', |
| 1604 | + 'qp_full_category_name' => '$1(<code>$2</code>)', |
| 1605 | + 'qp_desc' => 'Määt Affschtemmunge müjjelesch.', |
| 1606 | + 'qp_desc-sp' => '[[Special:PollResults|{{int:nstab-special}}]] för aanzeloore, wat bei Affschtemmunge erus kohm.', |
| 1607 | + 'qp_result_NA' => 'Kein Antwoot jejovve', |
| 1608 | + 'qp_result_error' => 'Ene Fähler en dä Syntax es opjefalle', |
| 1609 | + 'qp_vote_button' => 'Afschtemme!', |
| 1610 | + 'qp_vote_again_button' => 'Donn Ding Shtemm ändere', |
| 1611 | + 'qp_polls_list' => 'Alle Affschtemmunge opleste', |
| 1612 | + 'qp_users_list' => 'Alle Metmaacher opleste', |
| 1613 | + 'qp_browse_to_poll' => 'Bes $1 bläddere', |
| 1614 | + 'qp_browse_to_user' => 'Bes $1 bläddere', |
| 1615 | + 'qp_votes_count' => '{{PLURAL:$1|ein Schtemm|$1 Schtemme|Kein Schtemm}}', |
| 1616 | + 'qp_source_link' => 'Beschrevve', |
| 1617 | + 'qp_stats_link' => 'Schtatistike', |
| 1618 | + 'qp_users_link' => 'Metmaacher', |
| 1619 | + 'qp_voice_link' => 'Enem Metmaacher sing Stemm', |
| 1620 | + 'qp_voice_link_inv' => 'Enem Metmaacher sing Stemm?', |
| 1621 | + 'qp_user_polls_link' => 'Hät beij {{PLURAL:$1|eine Affschtemmung|$1 Affschtemmunge|keine Affschtemmung}} metjemaat', |
| 1622 | + 'qp_user_missing_polls_link' => 'Keine hät metjemaat', |
| 1623 | + 'qp_not_participated_link' => 'Nit metjmaat', |
| 1624 | + 'qp_order_by_username' => 'Noh de Metmaacher iere Name zoteere', |
| 1625 | + 'qp_order_by_polls_count' => 'Noh e Affschtemmunge ier Zahle zoteere', |
| 1626 | + 'qp_results_line_qupl' => 'Sigg „$1“ Affschtemmung „$2“: $3', |
| 1627 | + 'qp_results_line_qpl' => 'Sigg „$1“ Affschtemmung „$2“: $3, $4, $5, $6', |
| 1628 | + 'qp_header_line_qpul' => '$1 [ Sigg „$2“ Affschtemmung „$3“ ]', |
| 1629 | + 'qp_results_line_qpul' => '$1: $2', |
| 1630 | + 'qp_header_line_qucl' => '$1. $2<br />$3 ??? $4', |
| 1631 | + 'qp_results_line_qucl' => '$1: $2 $3', |
| 1632 | + 'qp_export_to_xls' => 'Donn de Schtatistike em <i lang="en">XLS</i> Fommaat äxpotteere', |
| 1633 | + 'qp_voices_to_xls' => 'Donn de Shtemme em <i lang="en">XLS</i> Fommaat äxpotteere', |
| 1634 | + 'qp_users_answered_questions' => '{{PLURAL:$1|Eine|$1|Keine}} Metmaacher {{PLURAL:$1|hät|han|hät}} op di Froore jeantwoot \\', |
| 1635 | + 'qp_func_no_such_poll' => 'Esu en Affschtemmung ham_mer nit ($1)', |
| 1636 | + 'qp_func_missing_question_id' => 'Bes esu joot, un jif en Kännong aan, di et jitt,för en Frooch (vun 1 aan jezallt) för de Affschtemmung $1', |
| 1637 | + 'qp_func_invalid_question_id' => 'Dat es en onjöltijje Frooch (<code lang="en">id=$2</code>), nämmlesch kein Nommer, för de Affschtemmung $1', |
| 1638 | + 'qp_func_missing_proposal_id' => 'Bes esu joot, un jif en Kännong aan, di et jitt,för ene Vörschlaach (vun 0 aan jezallt) för de Affschtemmung $1 un de Frooch $2', |
| 1639 | + 'qp_func_invalid_proposal_id' => 'Dat es en onjöltijje Kännong för ene Vörschlaach (<code lang="en">id=$3</code>), nämmlesch kein Nommer, för de Affschtemmung $1 un de Frooch $2', |
| 1640 | + 'qp_error_no_such_poll' => 'Mer hann kein esu en Affschtemmung ($1). |
| 1641 | +Bes sescher, dat di Affschtemmung wennjerescht es un affjeschpeijschert, un bes sescher, dat De dat Bejränzungszeijsche # en dä Addräß bruche deihß.', |
| 1642 | + 'qp_error_in_question_header' => 'Dat es en onjöltijje Övverschreff vun en Frooch: $1', |
| 1643 | + 'qp_error_id_in_stats_mode' => 'Mer künne kein Kännung (<code lang="en">id=</code>) fö di Affschtemmung en de Enschtellung för de Schtatistike faßlääje', |
| 1644 | + 'qp_error_dependance_in_stats_mode' => 'Mer künne kein Kett vun Affhängeschkeite fö di Affschtemmung en de Enschtellung för de Schtatistike faßlääje', |
| 1645 | + 'qp_error_no_stats' => 'Ner han kein schtatistesche Daate, weil noch keiner för heh di Affjeschtemmung affjeschtemmp hät. (<code>address=$1</code>)', |
| 1646 | + 'qp_error_address_in_decl_mode' => 'Mer künne kein Addräß vun dä Affschtemmung beij em Fäßlääje vun de Enschtellung un Eijeschaffte krijje', |
| 1647 | + 'qp_error_question_not_implemented' => 'Froore vun dä Zoot sin nit em Projramm: $1', |
| 1648 | + 'qp_error_invalid_question_type' => 'Dat es en onjöltijje Zoot Frooch: $1', |
| 1649 | + 'qp_error_type_in_stats_mode' => 'Froore ier Zoot kam_mer nit en de Enschtellung för de Schtatistike faßlääje: $1', |
| 1650 | + 'qp_error_no_poll_id' => 'Dä Befähl för en Affschtemmung hät kein Kännung (<code>id=</code>) aanjejovve.', |
| 1651 | + 'qp_error_invalid_poll_id' => 'Dat es en onjöltijje Kännung för en Affschtemmung (<code>id=$1</code>) |
| 1652 | +Doh dörfe nur Bochschtabe, Zeffere, un Affschtänd dren sin.', |
| 1653 | + 'qp_error_already_used_poll_id' => 'Di Kännung för en Affschtemmung (<code>id=$1</code>) es ald ens op heh dä Sigg jebruch woode.', |
| 1654 | + 'qp_error_invalid_dependance_value' => 'Di Affschtemmung fö di Kännung (<code>id=$1</code>) ier Kett vun Afhängeschkeite hät en onjöltesch Eijeschaff (dependance="$2")', |
| 1655 | + 'qp_error_missed_dependance_title' => 'Di Affschtemmung met dä Kännung (<code>id=$1</code>) hängk aff vun ene andere Affschtemmung met dä Kännung (<code>id=$3</code>) op dä Sigg „[[$2]]“, ävver di ham_mer nit jefonge. |
| 1656 | +Entweder donn die Eijeschaff met dä Affhängeschkeit fott, udder holl di Sigg „[[$2]]“ wider en et Wiki,', |
| 1657 | + 'qp_error_missed_dependance_poll' => 'Di Affschtemmung met dä Kännung (<code>id=$1</code>) hängk aff vun ene andere Affschtemmung met dä Kännung (<code>id=$3</code>) op dä Sigg „$2“, ävver di Affschtemmung ham_mer doh nit jefonge. |
| 1658 | +Entweder donn die Eijeschaff met dä Affhängeschkeit fott, udder donn en Affschtemmung met dä Kännung (<code>id=$3</code>) op di Sigg „$2“ un donn se afschpeijschere. |
| 1659 | +Öm en Afschtemmung reschtesch ze schpeijschere, donn dat, der ohne op en Frooch jeantwoot ze han.', |
| 1660 | + 'qp_error_vote_dependance_poll' => 'Bes esu joot un donn övver „$1“ et eets affschtemme', |
| 1661 | + 'qp_error_too_many_spans' => 'Et sinn_er zoh vill Zoote-Jroppe för de Ongerknubbelle aanjejovve', |
| 1662 | + 'qp_error_unanswered_span' => 'Ongerknubbel oohne Antwoot', |
| 1663 | + 'qp_error_non_unique_choice' => 'Di Frooch bruch ene einzelne Vörschlaach för en Antwoot', |
| 1664 | + 'qp_error_category_name_empty' => 'Dä Name för dä Knubbel es läddesch', |
| 1665 | + 'qp_error_proposal_text_empty' => 'En däm Täx för dä Vörschlaach schteiht nix dren', |
| 1666 | + 'qp_error_too_few_categories' => 'Winnischsdens zweij Knubbelle möße doh sin', |
| 1667 | + 'qp_error_too_few_spans' => 'För jeede Zoote-Knubbel möte winnischsdens zweij müjjelesche Ongerzoote doh sin', |
| 1668 | + 'qp_error_no_answer' => 'Ene Vörschlaach ohne Antwoot', |
| 1669 | + 'qp_error_unique' => 'En Frooch vun dä Zoot <code>unique()</code> hät mieh Vörschlääsch, wi müjjelesche Antwoote aanjejovve: Dat kam_mer nit ußfölle.', |
| 1670 | +); |
| 1671 | + |
| 1672 | +/** Luxembourgish (Lëtzebuergesch) |
| 1673 | + * @author Robby |
| 1674 | + */ |
| 1675 | +$messages['lb'] = array( |
| 1676 | + 'pollresults' => 'Resultater vun der Ëmfro op dësem Site', |
| 1677 | + 'qp_desc' => "Erlaabt et Ëmfroen z'organiséieren", |
| 1678 | + 'qp_desc-sp' => "[[Special:PollResults|Spezialsäit]] fir d'Resultater vun der Ëmfro ze gesinn", |
| 1679 | + 'qp_result_NA' => 'Keng Äntwert', |
| 1680 | + 'qp_result_error' => 'Syntaxfeeler', |
| 1681 | + 'qp_vote_button' => 'Ofstëmmen', |
| 1682 | + 'qp_vote_again_button' => 'Ännert Är Ofstëmmung', |
| 1683 | + 'qp_polls_list' => 'All Ëmfroe weisen', |
| 1684 | + 'qp_users_list' => 'All Benotzer opzielen', |
| 1685 | + 'qp_browse_to_poll' => 'Op $1 goen', |
| 1686 | + 'qp_browse_to_user' => 'Bäi de(n) $1 goen', |
| 1687 | + 'qp_votes_count' => '$1 {{PLURAL:$1|Stëmm|Stëmmen}}', |
| 1688 | + 'qp_source_link' => 'Quell', |
| 1689 | + 'qp_stats_link' => 'Statistiken', |
| 1690 | + 'qp_users_link' => 'Benotzer', |
| 1691 | + 'qp_voice_link' => 'Stëmm vum Benotzer', |
| 1692 | + 'qp_voice_link_inv' => 'Stëmm vum Benotzer?', |
| 1693 | + 'qp_user_polls_link' => 'huet {{PLURAL:$1|un enger Ëmfro|u(n) $1 Ëmfroen}} deelgeholl', |
| 1694 | + 'qp_user_missing_polls_link' => 'Keng Bedeelegung', |
| 1695 | + 'qp_not_participated_link' => 'Net matgemaach', |
| 1696 | + 'qp_order_by_username' => 'Nom Benotzernumm zortéieren', |
| 1697 | + 'qp_order_by_polls_count' => 'No der Zuel vun den Ënfroen zortéieren', |
| 1698 | + 'qp_results_line_qupl' => 'Säit "$1" Ëmfro "$2": $3', |
| 1699 | + 'qp_results_line_qpl' => 'Säit "$1" Ëmfro "$2": $3, $4, $5, $6', |
| 1700 | + 'qp_header_line_qpul' => '$1 [ Säit "$2" Ëmfro "$3" ]', |
| 1701 | + 'qp_export_to_xls' => "Exportéiert d'Statistiken am XLS-Format", |
| 1702 | + 'qp_users_answered_questions' => "$1 {{PLURAL:$1|Benotzer huet|Benotzer hun}} op d'Froe geäntwert", |
| 1703 | + 'qp_func_no_such_poll' => 'Et gëtt keng esou eng Ëmfro ($1)', |
| 1704 | + 'qp_func_missing_question_id' => "Gitt w.e.g. d'Id vun enger Fro un déi et gëtt (ugefaang mat 1) fir d'Ëmfro $1", |
| 1705 | + 'qp_func_invalid_question_id' => "id vun der Fro=$2 ass net valabel (et ass keng Zuel) fir d'Ëmfro $1", |
| 1706 | + 'qp_error_in_question_header' => 'Iwwerschrëft vun der Fro net valabel: $1', |
| 1707 | + 'qp_error_no_stats' => 'Et gëtt keng statistesch Donnéeën, well bis elo (Adress=$1) kee fir dës Ëmfro gestëmmt huet.', |
| 1708 | + 'qp_error_question_not_implemented' => 'Froe vun esou engem Typ sinn net implementéiert: $1', |
| 1709 | + 'qp_error_invalid_question_type' => 'Net-valabelen Typ vu Fro: $1', |
| 1710 | + 'qp_error_already_used_poll_id' => "D'Ëmfro-Nummer (poll id) gouf op dëser Säit scho benotzt (id=$1).", |
| 1711 | + 'qp_error_vote_dependance_poll' => "Stëmmt w.e.g. fir d'éischt bäi der Ëmfro $1 of.", |
| 1712 | + 'qp_error_unanswered_span' => 'Ënnerkategorie ouni Äntwert', |
| 1713 | + 'qp_error_non_unique_choice' => 'Dës Fro brauch eng Äntwert mat enger eenzeger Propos', |
| 1714 | + 'qp_error_category_name_empty' => 'Den Numm vun der Kategorie ass eidel', |
| 1715 | + 'qp_error_proposal_text_empty' => 'Den Text vum Virschlag ass eidel', |
| 1716 | + 'qp_error_too_few_categories' => 'Et musse mindestens zwou Kategorien definéiert sinn', |
| 1717 | + 'qp_error_too_few_spans' => 'All Kategoriegrupp muss mindestens aus zwou Ënnerkategorie bestoen', |
| 1718 | + 'qp_error_no_answer' => 'Propos ouni Äntwert', |
| 1719 | +); |
| 1720 | + |
| 1721 | +/** Malagasy (Malagasy) |
| 1722 | + * @author Jagwar |
| 1723 | + */ |
| 1724 | +$messages['mg'] = array( |
| 1725 | + 'qp_export_to_xls' => 'Avoaka rakitra XLS ny statistika', |
| 1726 | +); |
| 1727 | + |
| 1728 | +/** Macedonian (Македонски) |
| 1729 | + * @author Bjankuloski06 |
| 1730 | + * @author Brest |
| 1731 | + */ |
| 1732 | +$messages['mk'] = array( |
| 1733 | + 'pollresults' => 'Резултати од анкетите на ова мрежно место', |
| 1734 | + 'qp_desc' => 'Овозможува создавање на анкети', |
| 1735 | + 'qp_desc-sp' => '[[Special:PollResults|Специјална страница]] за преглед на резултати од анкетите', |
| 1736 | + 'qp_result_NA' => 'Без одговор', |
| 1737 | + 'qp_result_error' => 'Синтаксна грешка', |
| 1738 | + 'qp_vote_button' => 'Гласај', |
| 1739 | + 'qp_vote_again_button' => 'Прегласај', |
| 1740 | + 'qp_polls_list' => 'Список на сите анкети', |
| 1741 | + 'qp_users_list' => 'Список на сите корисници', |
| 1742 | + 'qp_browse_to_poll' => 'Прелистај до $1', |
| 1743 | + 'qp_browse_to_user' => 'Прелистај до $1', |
| 1744 | + 'qp_votes_count' => '$1 {{PLURAL:$1|глас|гласа}}', |
| 1745 | + 'qp_source_link' => 'Извор', |
| 1746 | + 'qp_stats_link' => 'Статистики', |
| 1747 | + 'qp_users_link' => 'Корисници', |
| 1748 | + 'qp_voice_link' => 'Кориснички глас', |
| 1749 | + 'qp_voice_link_inv' => 'Кориснички глас?', |
| 1750 | + 'qp_user_polls_link' => 'Учествувал во $1 {{PLURAL:$1|анкета|анкети}}', |
| 1751 | + 'qp_user_missing_polls_link' => 'Без одзив', |
| 1752 | + 'qp_not_participated_link' => 'Не учествувале', |
| 1753 | + 'qp_order_by_username' => 'Подреди по корисничко име', |
| 1754 | + 'qp_order_by_polls_count' => 'Подреди по број на анкети', |
| 1755 | + 'qp_results_line_qupl' => 'Страница „$1“ Анкета „$2“: $3', |
| 1756 | + 'qp_results_line_qpl' => 'Страница „$1“ Анкета „$2“: $3, $4, $5, $6', |
| 1757 | + 'qp_header_line_qpul' => '$1 [ Страница „$2“ Анкета „$3“ ]', |
| 1758 | + 'qp_export_to_xls' => 'Извези ги статистиките во XLS формат', |
| 1759 | + 'qp_voices_to_xls' => 'Извези гласови во XLS-формат', |
| 1760 | + 'qp_users_answered_questions' => 'На прашањата $1 {{PLURAL:$1|одговорил $1 корисник|одговориле $1 корисници}}', |
| 1761 | + 'qp_func_no_such_poll' => 'Нема таква анкета ($1)', |
| 1762 | + 'qp_func_missing_question_id' => 'Назначете постоечка назнака за прашањето (започнувајќи со 1) за анкетата $1', |
| 1763 | + 'qp_func_invalid_question_id' => 'Неважечка назнака на прашањето id=$2 (не е број) за анкетата $1', |
| 1764 | + 'qp_func_missing_proposal_id' => 'Назначете постоечки id-број за предлогот (започнувајќи со 0) за анкетата $1, прашање $2', |
| 1765 | + 'qp_func_invalid_proposal_id' => 'Неважечки предлог id=$3 на предлог (не е број) за анкетата $1, прашање $2', |
| 1766 | + 'qp_error_no_such_poll' => 'Нема таква анкета ($1). |
| 1767 | +Проверете дали анкетата е утврдена и зачувана, и осигурајте се дека во адресата користите разграничен знак #', |
| 1768 | + 'qp_error_in_question_header' => 'Погрешно заглавие за прашањето: $1', |
| 1769 | + 'qp_error_id_in_stats_mode' => 'Не може да се утврди ID-број за анкетата во статистички режим', |
| 1770 | + 'qp_error_dependance_in_stats_mode' => 'Не можете да утврдите ланец на зависност за анкетата во статистички режим', |
| 1771 | + 'qp_error_no_stats' => 'Нема достапни статистички податоци, бидејќи сè уште никој нема гласано на оваа анкета (address=$1)', |
| 1772 | + 'qp_error_address_in_decl_mode' => 'Не може да се дава адреса на анкетата во утврдувачки режим', |
| 1773 | + 'qp_error_question_not_implemented' => 'Прашањата од таков тип не се имплементираат: $1', |
| 1774 | + 'qp_error_invalid_question_type' => 'Неважечки тип на прашање: $1', |
| 1775 | + 'qp_error_type_in_stats_mode' => 'Не може да се определува тип на прашање во статистички режим: $1', |
| 1776 | + 'qp_error_no_poll_id' => 'Ознаката на анкетата нема определено атрибут за id-број.', |
| 1777 | + 'qp_error_invalid_poll_id' => 'Неважечки id-број на анкетата (id=$1). |
| 1778 | +id-бројот може да содржи само букви, бројки и знак за место (проред)', |
| 1779 | + 'qp_error_already_used_poll_id' => 'id-бројот на анкетата веќе се користи на оваа страница (id=$1).', |
| 1780 | + 'qp_error_invalid_dependance_value' => 'Ланецот на зависност за анкетата (id=$1) има неважечка вредност во атрибутот за зависност (dependance="$2")', |
| 1781 | + 'qp_error_missed_dependance_title' => 'Анкетата (id=$1) е зависна од друга анкета (id=$3) од страницата [[$2]], но насловот [[$2]] не беше најден. |
| 1782 | +Или отстранете го атрибутот за зависност, или вратете ја страницата [[$2]]', |
| 1783 | + 'qp_error_missed_dependance_poll' => 'Анкетата (id=$1) е зависна од друга анкета (id=$3) на страницата $2, но таа анкета не постои или сè уште не е зачувана. |
| 1784 | +Или отстранете го атрибутот за зависност, или создајде анкета со id=$3 на страницата $2 и зачувајте ја. |
| 1785 | +За да зачувате анкета, притиснете на „Гласај“ но притоа без да одговорите на ниеден предлог (прашање).', |
| 1786 | + 'qp_error_vote_dependance_poll' => 'Прво одговорете на анкетата $1.', |
| 1787 | + 'qp_error_too_many_spans' => 'Премногу категориски групи за вкупниот број на утврдени поткатегории', |
| 1788 | + 'qp_error_unanswered_span' => 'Неодговорена поткатегорија', |
| 1789 | + 'qp_error_non_unique_choice' => 'Ова прашање бара одговор кој не е даден претходно', |
| 1790 | + 'qp_error_category_name_empty' => 'Името на категоријата е празно', |
| 1791 | + 'qp_error_proposal_text_empty' => 'Текстот за предлог е празен', |
| 1792 | + 'qp_error_too_few_categories' => 'Мора да определите барем две категории', |
| 1793 | + 'qp_error_too_few_spans' => 'Секоја класа на категории бара да определите барем два можни одговора', |
| 1794 | + 'qp_error_no_answer' => 'Неодговорен предлог', |
| 1795 | + 'qp_error_unique' => 'Прашањето од типот unique() има определено повеќе предлози од можни одговори: одговарањето на прашањето е неизводливо', |
| 1796 | +); |
| 1797 | + |
| 1798 | +/** Malay (Bahasa Melayu) |
| 1799 | + * @author Anakmalaysia |
| 1800 | + */ |
| 1801 | +$messages['ms'] = array( |
| 1802 | + 'qp_source_link' => 'Sumber', |
| 1803 | +); |
| 1804 | + |
| 1805 | +/** Dutch (Nederlands) |
| 1806 | + * @author McDutchie |
| 1807 | + * @author Purodha |
| 1808 | + * @author Siebrand |
| 1809 | + */ |
| 1810 | +$messages['nl'] = array( |
| 1811 | + 'pollresults' => 'Resultaten van de stemmingen op deze site', |
| 1812 | + 'qp_desc' => 'Maakt het aanmaken van peilingen mogelijk', |
| 1813 | + 'qp_desc-sp' => '[[Special:PollResults|Speciale pagina]] voor het bekijken van de resultaten van peilingen', |
| 1814 | + 'qp_result_NA' => 'Niet beantwoord', |
| 1815 | + 'qp_result_error' => 'Er zit een fout in de syntaxis', |
| 1816 | + 'qp_vote_button' => 'Stemmen', |
| 1817 | + 'qp_vote_again_button' => 'Stem wijzigen', |
| 1818 | + 'qp_polls_list' => 'Alle peilingen weergeven', |
| 1819 | + 'qp_users_list' => 'Alle gebruikers weergeven', |
| 1820 | + 'qp_browse_to_poll' => 'Naar de peiling $1', |
| 1821 | + 'qp_browse_to_user' => 'Naar gebruiker $1', |
| 1822 | + 'qp_votes_count' => '$1 {{PLURAL:$1|stem|stemmen}}', |
| 1823 | + 'qp_source_link' => 'Bron', |
| 1824 | + 'qp_stats_link' => 'Statistieken', |
| 1825 | + 'qp_users_link' => 'Gebruikers', |
| 1826 | + 'qp_voice_link' => 'Gebruikersstem', |
| 1827 | + 'qp_voice_link_inv' => 'Gebruikersstem?', |
| 1828 | + 'qp_user_polls_link' => 'Heeft deelgenomen aan $1 {{PLURAL:$1|peiling|peilingen}}', |
| 1829 | + 'qp_user_missing_polls_link' => 'Geen deelname', |
| 1830 | + 'qp_not_participated_link' => 'Niet deelgenomen', |
| 1831 | + 'qp_order_by_username' => 'Sorteren op gebruikersnaam', |
| 1832 | + 'qp_order_by_polls_count' => 'Sorteren op peilingenaantal', |
| 1833 | + 'qp_results_line_qupl' => 'Pagina "$1", peiling "$2": $3', |
| 1834 | + 'qp_results_line_qpl' => 'Pagina "$1", peiling "$2": $3, $4, $5, $6', |
| 1835 | + 'qp_header_line_qpul' => '$1 [ pagina "$2", peiling "$3" ]', |
| 1836 | + 'qp_header_line_qucl' => '$1. $2<br />$3 ??? $4', |
| 1837 | + 'qp_export_to_xls' => 'Statistieken naar XLS-formaat exporteren', |
| 1838 | + 'qp_voices_to_xls' => 'Stemmen in XLS-formaat exporteren', |
| 1839 | + 'qp_users_answered_questions' => '$1 {{PLURAL:$1|gebruiker heeft|gebruikers hebben}} de vragen beantwoord', |
| 1840 | + 'qp_func_no_such_poll' => 'Die peiling bestaat niet ($1)', |
| 1841 | + 'qp_func_missing_question_id' => 'Geef alstublieft een vraag-ID op (begin bij 1) voor de peiling $1', |
| 1842 | + 'qp_func_invalid_question_id' => 'Ongeldig vraag-ID ($2 - geen getal) voor de peiling $1', |
| 1843 | + 'qp_func_missing_proposal_id' => 'Geef alstublieft een voorstel-ID op (begin bij 0) voor de peiling $1, vraag $2', |
| 1844 | + 'qp_func_invalid_proposal_id' => 'Ongeldig voorstel-ID ($3 - geen getal) voor de peiling $1, vraag $2', |
| 1845 | + 'qp_error_no_such_poll' => 'Die peiling bestaat niet ($1). |
| 1846 | +Zorg dat de peiling is ingesteld en opgeslagen, en dat het adresscheidingsteken "#" is gebruikt.', |
| 1847 | + 'qp_error_in_question_header' => 'Ongeldige kop voor vraag: $1', |
| 1848 | + 'qp_error_id_in_stats_mode' => 'Het is niet mogelijk een ID voor de peiling te declareren in de statistische modus', |
| 1849 | + 'qp_error_dependance_in_stats_mode' => 'Het is niet mogelijk een afhankelijkheidsketen voor de peiling te declareren in de statistische modus', |
| 1850 | + 'qp_error_no_stats' => 'Er zijn geen statistische gegevens beschikbaar omdat er nog geen gebruikers hebben gestemd in deze peiling (adres $1)', |
| 1851 | + 'qp_error_address_in_decl_mode' => 'Het is niet mogelijk een adres van de peiling op te vragen in de declaratiemodus', |
| 1852 | + 'qp_error_question_not_implemented' => 'Vragen van dit type zijn niet beschikbaar: $1', |
| 1853 | + 'qp_error_invalid_question_type' => 'Ongeldig vraagtype: $1', |
| 1854 | + 'qp_error_type_in_stats_mode' => 'Het vraagtype kan niet gedefinieerd wordne in de statistische weergavemodus: $1', |
| 1855 | + 'qp_error_no_poll_id' => 'De eigenschap "id" is niet gedefinieerd voor de peiling.', |
| 1856 | + 'qp_error_invalid_poll_id' => 'Ongeldig peiling-ID ($1) |
| 1857 | +Het ID mag alleen letters, cijfers en spaties bevatten.', |
| 1858 | + 'qp_error_already_used_poll_id' => 'Het peilingsnummer wordt al gebruikt op deze pagina (ID $1)', |
| 1859 | + 'qp_error_invalid_dependance_value' => 'De peilingafhankelijkheidsketen (ID $1) heeft een ongeldige waarde voor de afhankelijkheidseigenschap (dependance "$2")', |
| 1860 | + 'qp_error_missed_dependance_title' => 'De peiling (ID $1) is afhankelijk van een andere peiling (ID $3) op pagina [[$2]], maar de pagina [[$2]] bestaat niet. |
| 1861 | +Verwijder de eigenschap "dependance" of plaats de pagina [[$2]] terug.', |
| 1862 | + 'qp_error_missed_dependance_poll' => 'De peiling (ID $1) is afhankelijk van een andere peiling (ID $3) op pagina $2, maar die peiling bestaat niet of is nog niet opgeslagen. |
| 1863 | +Verwijder de eigenschap "dependance" of maak een peiling aan met het ID $3 op pagina $2. |
| 1864 | +Sla een peiling op door deze op te slaan zonder dat enig voorstel is beantwoord.', |
| 1865 | + 'qp_error_vote_dependance_poll' => 'Stem alstublieft eerst in de peiling $1.', |
| 1866 | + 'qp_error_too_many_spans' => 'Er zijn te veel categorieklassen voor de subcategorieën gedefinieerd', |
| 1867 | + 'qp_error_unanswered_span' => 'Onbeantwoorde subcategorie', |
| 1868 | + 'qp_error_non_unique_choice' => 'Voor deze vraag is een uniek voorstelantwoord nodig', |
| 1869 | + 'qp_error_category_name_empty' => 'Er is geen categorienaam opgegeven', |
| 1870 | + 'qp_error_proposal_text_empty' => 'Er is geen voorsteltekst opgegeven', |
| 1871 | + 'qp_error_too_few_categories' => 'Er moeten tenminste twee categorieën gedefinieerd worden.', |
| 1872 | + 'qp_error_too_few_spans' => 'Voor iedere categorieklasse dienen tenminste twee mogelijk antwoorden gedefinieerd te zijn', |
| 1873 | + 'qp_error_no_answer' => 'Onbeantwoord voorstel', |
| 1874 | + 'qp_error_unique' => 'Voor de vraag van het type unique() zijn meer voorstellen dan mogelijke antwoorden gedefinieerd. Dat is niet recht te breien.', |
| 1875 | +); |
| 1876 | + |
| 1877 | +/** Norwegian Nynorsk (Norsk (nynorsk)) |
| 1878 | + * @author Gunnernett |
| 1879 | + */ |
| 1880 | +$messages['nn'] = array( |
| 1881 | + 'qp_result_NA' => 'Ikkje svar', |
| 1882 | + 'qp_users_list' => 'List opp alle brukarar', |
| 1883 | + 'qp_source_link' => 'Kjelde', |
| 1884 | + 'qp_stats_link' => 'Statistikk', |
| 1885 | +); |
| 1886 | + |
| 1887 | +/** Norwegian (bokmål) (Norsk (bokmål)) |
| 1888 | + * @author Nghtwlkr |
| 1889 | + */ |
| 1890 | +$messages['no'] = array( |
| 1891 | + 'pollresults' => 'Resultater fra spørreundersøkelsen på denne siden', |
| 1892 | + 'qp_desc' => 'Tillater opprettelse av spørreundersøkelser', |
| 1893 | + 'qp_desc-sp' => '[[Special:PollResults|Spesialside]] for visning av resultater fra spørreundersøkelsene', |
| 1894 | + 'qp_result_NA' => 'Ikke besvart', |
| 1895 | + 'qp_result_error' => 'Syntaksfeil', |
| 1896 | + 'qp_vote_button' => 'Stem', |
| 1897 | + 'qp_vote_again_button' => 'Endre din stemme', |
| 1898 | + 'qp_polls_list' => 'List opp alle spørreundersøkelser', |
| 1899 | + 'qp_users_list' => 'List opp alle brukere', |
| 1900 | + 'qp_browse_to_poll' => 'Bla igjennom til $1', |
| 1901 | + 'qp_browse_to_user' => 'Bla igjennom til $1', |
| 1902 | + 'qp_votes_count' => '{{PLURAL:$1|Én stemme|$1 stemmer}}', |
| 1903 | + 'qp_source_link' => 'Kilde', |
| 1904 | + 'qp_stats_link' => 'Statistikk', |
| 1905 | + 'qp_users_link' => 'Brukere', |
| 1906 | + 'qp_voice_link' => 'Brukerstemme', |
| 1907 | + 'qp_voice_link_inv' => 'Brukerstemme?', |
| 1908 | + 'qp_user_polls_link' => 'Deltok i {{PLURAL:$1|én spørreundersøkelse|$1 spørreundersøkelser}}', |
| 1909 | + 'qp_user_missing_polls_link' => 'Ingen deltakelse', |
| 1910 | + 'qp_not_participated_link' => 'Ikke deltatt', |
| 1911 | + 'qp_order_by_username' => 'Sorter etter brukernavn', |
| 1912 | + 'qp_order_by_polls_count' => 'Sorter etter antall spørreundersøkelser', |
| 1913 | + 'qp_results_line_qupl' => 'Side «$1» Spørreundersøkelse «$2»: $3', |
| 1914 | + 'qp_results_line_qpl' => 'Side «$1» Spørreundersøkelse «$2»: $3, $4, $5, $6', |
| 1915 | + 'qp_header_line_qpul' => '$1 [ Side «$2» Spørreundersøkelse «$3» ]', |
| 1916 | + 'qp_export_to_xls' => 'Eksporter statistikk til XLS-format', |
| 1917 | + 'qp_voices_to_xls' => 'Eksporter stemmer til XLS-format', |
| 1918 | + 'qp_users_answered_questions' => '{{PLURAL:$1|Én bruker|$1 brukere}} besvarte spørsmålene', |
| 1919 | + 'qp_func_no_such_poll' => 'Ingen slik spørreundersøkelse ($1)', |
| 1920 | + 'qp_func_missing_question_id' => 'Vennligst oppgi en eksisterende spørsmåls-ID (starter fra 1) for spørreundersøkelsen $1', |
| 1921 | + 'qp_func_invalid_question_id' => 'Ugyldig spørsmåls-id=$2 (ikke et tall) for spørreundersøkelsen $1', |
| 1922 | + 'qp_func_missing_proposal_id' => 'Vennligst oppgi en eksisterende forslags-id (starter fra 0) for spørreundersøkelsen $1, spørsmål $2', |
| 1923 | + 'qp_func_invalid_proposal_id' => 'Ugyldig forslags-id=$3 (ikke et tall) for spørreundersøkelsen $1, spørsmål $2', |
| 1924 | + 'qp_error_no_such_poll' => 'Ingen slik spørreundersøkelse ($1). |
| 1925 | +Vær sikker på at spørreundersøkelsen ble deklarert og lagret, vær også sikker på at tegnet # blir brukt som addresse avgrenser', |
| 1926 | + 'qp_error_in_question_header' => 'Ugyldig spørsmålsoverskrift: $1', |
| 1927 | + 'qp_error_id_in_stats_mode' => 'Kan ikke deklarere en ID for spørreundersøkelsen i statistikkmodus', |
| 1928 | + 'qp_error_dependance_in_stats_mode' => 'Kan ikke deklarere kjede av avhengigheter for spørreundersøkelsen i statistikkmodus', |
| 1929 | + 'qp_error_no_stats' => 'Ingen statistiske data er tilgjengelig fordi ingen har stemt for denne spørreundersøkelsen enda (address=$1)', |
| 1930 | + 'qp_error_address_in_decl_mode' => 'Kan ikke få en adresse for spørreundersøkelsen i deklareringsmodus', |
| 1931 | + 'qp_error_question_not_implemented' => 'Spørsmål av en slik type er ikke implementert: $1', |
| 1932 | + 'qp_error_invalid_question_type' => 'Ugyldig spørsmålstype: $1', |
| 1933 | + 'qp_error_type_in_stats_mode' => 'Spørsmålstypen kan ikke defineres i statistisk visningsmodus: $1', |
| 1934 | + 'qp_error_no_poll_id' => 'Spørreundersøkelsesmerkelappen har ingen definerte id-atributter.', |
| 1935 | + 'qp_error_invalid_poll_id' => 'Ugyldig spørreundersøkelses-id (id=$1). |
| 1936 | +Spørreundersøkelses-id kan kun inneholde bokstaver, tall og mellomrom', |
| 1937 | + 'qp_error_already_used_poll_id' => 'Spørreundersøkelses-id-en har allerede blitt brukt på denne siden (id=$1).', |
| 1938 | + 'qp_error_invalid_dependance_value' => 'Spørreundersøkelsens (id=$1) kjede av avhengigheter har en ugyldig verdi av avhengighetsatributter (dependance="$2")', |
| 1939 | + 'qp_error_missed_dependance_title' => 'Spørreundersøkelsen (id=$1) avhenger av en annen spørreundersøkelse (id=$3) fra side [[$2]], men tittelen [[$2]] ble ikke funnet. |
| 1940 | +Enten fjern avhengighetsatributten, eller gjenopprett [[$2]]', |
| 1941 | + 'qp_error_missed_dependance_poll' => 'Spørreundersøkelsen (id=$1) avhenger av en annen spørreundersøkelse (id=$3) på side $2, men den spørreundersøkelsen finnes ikke eller har ikke blitt lagret enda. |
| 1942 | +Enten fjern avhengighetsatributten eller opprett spørreundersøkelsen med id=$3 på siden $2 og lagre den. |
| 1943 | +For å lagre en spørreundersøkelse, send den mens du ikke svarer på noen forslagsspørsmål.', |
| 1944 | + 'qp_error_vote_dependance_poll' => 'Vennligst stem for spørreundersøkelsen $1 først.', |
| 1945 | + 'qp_error_too_many_spans' => 'For mange kategorigrupper for det totale antall underkategorier definert', |
| 1946 | + 'qp_error_unanswered_span' => 'Ubesvart underkategori', |
| 1947 | + 'qp_error_non_unique_choice' => 'Dette spørsmålet krever unikt forslagssvar', |
| 1948 | + 'qp_error_category_name_empty' => 'Kategorinavn er tomt', |
| 1949 | + 'qp_error_proposal_text_empty' => 'Forslagstekst er tom', |
| 1950 | + 'qp_error_too_few_categories' => 'Minst to kategorier må defineres', |
| 1951 | + 'qp_error_too_few_spans' => 'Hver kategorigruppe må inneholde minst to underkategorier', |
| 1952 | + 'qp_error_no_answer' => 'Ubesvart forslag', |
| 1953 | + 'qp_error_unique' => 'Spørsmål av typen unique() har flere forslag enn mulige definerte svar: umulig å gjennomføre', |
| 1954 | +); |
| 1955 | + |
| 1956 | +/** Pälzisch (Pälzisch) |
| 1957 | + * @author Xqt |
| 1958 | + */ |
| 1959 | +$messages['pfl'] = array( |
| 1960 | + 'qp_stats_link' => 'Schdadischdik', |
| 1961 | +); |
| 1962 | + |
| 1963 | +/** Polish (Polski) |
| 1964 | + * @author Odder |
| 1965 | + * @author Sp5uhe |
| 1966 | + */ |
| 1967 | +$messages['pl'] = array( |
| 1968 | + 'pollresults' => 'Wyniki ankiet na tej witrynie', |
| 1969 | + 'qp_desc' => 'Pozwala na tworzenie ankiet', |
| 1970 | + 'qp_desc-sp' => '[[Special:PollResults|Strona specjalna]] z wynikami ankiet', |
| 1971 | + 'qp_result_NA' => 'Brak odpowiedzi', |
| 1972 | + 'qp_result_error' => 'Błąd składni', |
| 1973 | + 'qp_vote_button' => 'Zapisz głos', |
| 1974 | + 'qp_vote_again_button' => 'Zmień głos', |
| 1975 | + 'qp_polls_list' => 'Spis wszystkich ankiet', |
| 1976 | + 'qp_users_list' => 'Spis wszystkich użytkowników', |
| 1977 | + 'qp_browse_to_poll' => 'Przeglądaj do $1', |
| 1978 | + 'qp_browse_to_user' => 'Przeglądaj do $1', |
| 1979 | + 'qp_votes_count' => '$1 {{PLURAL:$1|głos|głosy|głosów}}', |
| 1980 | + 'qp_source_link' => 'źródło', |
| 1981 | + 'qp_stats_link' => 'statystyki', |
| 1982 | + 'qp_users_link' => 'użytkownicy', |
| 1983 | + 'qp_voice_link' => 'Głos użytkownika', |
| 1984 | + 'qp_voice_link_inv' => 'Głos użytkownika?', |
| 1985 | + 'qp_user_polls_link' => 'Brał udział w $1 {{PLURAL:$1|ankiecie|ankietach}}', |
| 1986 | + 'qp_user_missing_polls_link' => '{{GENDER:$1|Nie brał|Nie brała|Brak}} udziału', |
| 1987 | + 'qp_not_participated_link' => 'brak udziału', |
| 1988 | + 'qp_order_by_username' => 'Posortowane względem nazwy użytkownika', |
| 1989 | + 'qp_order_by_polls_count' => 'Posortowane względem liczby uczestników ankiety', |
| 1990 | + 'qp_results_line_qupl' => 'Strona „$1” ankieta „$2” – $3', |
| 1991 | + 'qp_results_line_qpl' => 'Strona „$1” ankieta „$2” – $3, $4, $5, $6', |
| 1992 | + 'qp_header_line_qpul' => '$1 [ Strona „$2” ankieta „$3” ]', |
| 1993 | + 'qp_export_to_xls' => 'Eksport statystyk w formacie XLS', |
| 1994 | + 'qp_voices_to_xls' => 'Eksport głosów w formacie XLS', |
| 1995 | + 'qp_users_answered_questions' => '$1 {{PLURAL:$1|użytkownik odpowiedział|użytkowników odpowiedziało}} na pytania', |
| 1996 | + 'qp_func_no_such_poll' => 'Brak takiej ankiety ($1)', |
| 1997 | + 'qp_func_missing_question_id' => 'Określ istniejący identyfikator pytania (zaczynając od 1) dla ankiety $1', |
| 1998 | + 'qp_func_invalid_question_id' => 'Nieprawidłowy identyfikator $2 pytania (nie jest to numer) dla ankiety $1', |
| 1999 | + 'qp_func_missing_proposal_id' => 'Określ identyfikator istniejącej propozycji (zaczynając od 0) dla pytania $2 z ankiety $1', |
| 2000 | + 'qp_func_invalid_proposal_id' => 'Nieprawidłowy identyfikator $3 propozycji (to nie jest numer) pytania $2 w ankiecie $1', |
| 2001 | + 'qp_error_no_such_poll' => 'Brak takiej ankiety ($1). |
| 2002 | +Upewnij się, że ankieta została zadeklarowana i zapisana oraz, że użyłeś jako ogranicznika adresu znaku #', |
| 2003 | + 'qp_error_in_question_header' => 'Nieprawidłowy nagłówek pytania – $1', |
| 2004 | + 'qp_error_id_in_stats_mode' => 'Nie można zadeklarować identyfikatora ankiety w trybie statycznym', |
| 2005 | + 'qp_error_dependance_in_stats_mode' => 'Nie można zadeklarować łańcucha zależności ankiety w trybie statystycznym', |
| 2006 | + 'qp_error_no_stats' => 'Brak danych statystycznych, ponieważ nikt jeszcze nie brał udziału w tej ankiecie (adres=$1)', |
| 2007 | + 'qp_error_address_in_decl_mode' => 'Nie można uzyskać adresu ankiety w trybie deklaracji', |
| 2008 | + 'qp_error_question_not_implemented' => 'Pytania tego typu nie zostały jeszcze zaimplementowane – $1', |
| 2009 | + 'qp_error_invalid_question_type' => 'Nieprawidłowy typ pytania – $1', |
| 2010 | + 'qp_error_type_in_stats_mode' => 'Typ pytania nie może być definiowany w trybie wyświetlania statystyki – $1', |
| 2011 | + 'qp_error_no_poll_id' => 'Znacznik ankiety nie ma zdefiniowanego atrybutu identyfikatora.', |
| 2012 | + 'qp_error_invalid_poll_id' => 'Nieprawidłowy identyfikator ankiety (id=$1). |
| 2013 | +Identyfikator ankiety może zawierać wyłączanie litery, cyfry i znak odstępu', |
| 2014 | + 'qp_error_already_used_poll_id' => 'Identyfikator ankiety został już użyty na tej stronie (id=$1).', |
| 2015 | + 'qp_error_invalid_dependance_value' => 'Łańcuch zależności ankiety (id=$1) ma nieprawidłową wartość atrybutu zależności (dependence=„$2”)', |
| 2016 | + 'qp_error_missed_dependance_title' => 'Ankieta (id=$1) jest uzależniona od innej ankiety (id=$3) ze strony [[$2]], ale tytuł [[$2]] nie został odnaleziony. |
| 2017 | +Należy usunąć atrybut zależności lub przywrócić [[$2]]', |
| 2018 | + 'qp_error_missed_dependance_poll' => 'Ankieta (id=$1) jest uzależniona od innej ankiety (id=$3) na stronie $2, ale ankieta nie istnieje lub nie została jeszcze zapisana. |
| 2019 | +Należy usunąć atrybut zależności lub utworzyć ankietę z id=$3 na stronie $2 i ją zapisać. |
| 2020 | +Aby zapisać ankietę, zapisz ją bez odpowiadania na jakiekolwiek proponowane pytania.', |
| 2021 | + 'qp_error_vote_dependance_poll' => 'Najpierw weź udział w ankiecie $1.', |
| 2022 | + 'qp_error_too_many_spans' => 'Zbyt wiele grup kategorii dla ogólnej liczby zdefiniowanych podkategorii', |
| 2023 | + 'qp_error_unanswered_span' => 'Podkategoria bez odpowiedzi', |
| 2024 | + 'qp_error_non_unique_choice' => 'To pytanie wymaga udzielenia unikalnej odpowiedzi', |
| 2025 | + 'qp_error_category_name_empty' => 'Nazwa kategorii jest pusta', |
| 2026 | + 'qp_error_proposal_text_empty' => 'Tekst odpowiedzi jest pusty', |
| 2027 | + 'qp_error_too_few_categories' => 'Należy wybrać co najmniej dwie kategorie', |
| 2028 | + 'qp_error_too_few_spans' => 'Każda grupa kategorii musi zawierać co najmniej dwie podkategorie', |
| 2029 | + 'qp_error_no_answer' => 'Pytanie bez odpowiedzi', |
| 2030 | + 'qp_error_unique' => 'Pytanie typu unique() ma więcej propozycji odpowiedzi niż zdefiniowano jako dopuszczalne – brak możliwości zakończenia', |
| 2031 | +); |
| 2032 | + |
| 2033 | +/** Piedmontese (Piemontèis) |
| 2034 | + * @author Borichèt |
| 2035 | + * @author Dragonòt |
| 2036 | + */ |
| 2037 | +$messages['pms'] = array( |
| 2038 | + 'pollresults' => 'Arzultà dij sondagi an sto sit-sì', |
| 2039 | + 'qp_desc' => 'A përmet la creassion ëd sondagi', |
| 2040 | + 'qp_desc-sp' => "[[Special:PollResults|Pàgina special]] për vëdde j'arzultà dij sondagi", |
| 2041 | + 'qp_result_NA' => 'Pa arspondù', |
| 2042 | + 'qp_result_error' => 'Eror ëd sintassi', |
| 2043 | + 'qp_vote_button' => 'Vot', |
| 2044 | + 'qp_vote_again_button' => 'Cangia tò vot', |
| 2045 | + 'qp_polls_list' => 'Lista tùit ij sondagi', |
| 2046 | + 'qp_users_list' => "Lista tùit j'utent", |
| 2047 | + 'qp_browse_to_poll' => 'Andé fin-a a $1', |
| 2048 | + 'qp_browse_to_user' => 'Andé fin-a a $1', |
| 2049 | + 'qp_votes_count' => '$1 {{PLURAL:$1|vot|vot}}', |
| 2050 | + 'qp_source_link' => 'Sorgiss', |
| 2051 | + 'qp_stats_link' => 'Statìstiche', |
| 2052 | + 'qp_users_link' => 'Utent', |
| 2053 | + 'qp_voice_link' => "Vos ëd l'utent", |
| 2054 | + 'qp_voice_link_inv' => "Vos ëd l'utent?", |
| 2055 | + 'qp_user_polls_link' => 'Partessipà a $1 {{PLURAL:$1|sondagi|sondagi}}', |
| 2056 | + 'qp_user_missing_polls_link' => 'Gnun-e partessipassion', |
| 2057 | + 'qp_not_participated_link' => 'Pa partessipà', |
| 2058 | + 'qp_order_by_username' => 'Ordiné për nòm utent', |
| 2059 | + 'qp_order_by_polls_count' => 'Ordiné për nùmer ëd sondagi', |
| 2060 | + 'qp_results_line_qupl' => 'Pàgina "$1" Sondagi "$2": "$3"', |
| 2061 | + 'qp_results_line_qpl' => 'Pàgina "$1" Sondagi "$2": $3, $4, $5, $6', |
| 2062 | + 'qp_header_line_qpul' => '$1 [ Pàgina "$2" Sondagi "$3" ]', |
| 2063 | + 'qp_export_to_xls' => 'Espòrta statìstiche an formà XLS', |
| 2064 | + 'qp_voices_to_xls' => 'Espòrta ij vot an formà XLS', |
| 2065 | + 'qp_users_answered_questions' => "$1 {{PLURAL:$1|utent|utent}} a l'han arspondù a la custion", |
| 2066 | + 'qp_func_no_such_poll' => 'Ël sondagi a esist pa ($1)', |
| 2067 | + 'qp_func_missing_question_id' => "Për piasì specìfica n'id ëd custion esistent (partend da 1) për ël sondagi $1", |
| 2068 | + 'qp_func_invalid_question_id' => 'Id custion=$2 pa bon (pa un nùmer) për ël sondagi $1', |
| 2069 | + 'qp_func_missing_proposal_id' => "Për piasì specifica n'id propòsta esistent (an partend da 0) për ël sondagi $1, chestion $2", |
| 2070 | + 'qp_func_invalid_proposal_id' => 'Id propòsta=$3 pa bon (pa un nùmer) për ël sondagi $1, chestion $2', |
| 2071 | + 'qp_error_no_such_poll' => "Sondagi pa esistent ($1). |
| 2072 | +Sicurte che ël sondagi a sia diciarà e salvà, ëdcò sicurte ëd dovré ël caràter delimitador d'adrësse #", |
| 2073 | + 'qp_error_in_question_header' => 'Antestassion dla chestion pa bon-a: $1', |
| 2074 | + 'qp_error_id_in_stats_mode' => "As peul pa diciaresse n'ID ëd sondagi an manera statìstica", |
| 2075 | + 'qp_error_dependance_in_stats_mode' => 'As peul pa diciaresse na caden-a ëd dipendensa dël sondagi an manera statìstica', |
| 2076 | + 'qp_error_no_stats' => "Pa gnun dat statìstich a son disponìbij, përchè gnun a l'ha votà për sto sondagi-sì, për adess (adrëssa=$1)", |
| 2077 | + 'qp_error_address_in_decl_mode' => "As peul pa pijé n'adrëssa dël sondagi an manera diciarativa", |
| 2078 | + 'qp_error_question_not_implemented' => 'Chestion dë sta sòrt-sì a son pa sostnùe: $1', |
| 2079 | + 'qp_error_invalid_question_type' => 'Sòrt ëd custion pa bon-a: $1', |
| 2080 | + 'qp_error_type_in_stats_mode' => 'Le Sòrt ëd custion a peulo pa esse definìe an manera statìstica: $1', |
| 2081 | + 'qp_error_no_poll_id' => "L'etichëtta dël sondagi a l'ha gnun atribù definì.", |
| 2082 | + 'qp_error_invalid_poll_id' => "Id dël sondagi pa bon (id=$1). |
| 2083 | +L'id dël sondagi a peul conten-e mach litre, nùmer e caràter dë spassi", |
| 2084 | + 'qp_error_already_used_poll_id' => "L'id dël sondagi a l'é già stàit dovrà an sta pàgina (id=$1).", |
| 2085 | + 'qp_error_invalid_dependance_value' => 'La caden-a ëd dipendensa dël sondagi (id=$1) a l\'ha valor pa bon ëd l\'atribù ëd dipendensa (dipendensa="$2")', |
| 2086 | + 'qp_error_missed_dependance_title' => "Ël sondagi (id=$1) a l'é dipendent da n'àutr sondagi (id=$3) ëd pàgina [[$2]], ma ël tìtol [[$2]] a l'é pa stàit trovà. |
| 2087 | +Ch'a gava l'atribù ëd dipendensa, o ch'a buta torna [[$2]]", |
| 2088 | + 'qp_error_missed_dependance_poll' => "Ël sondagi (id=$1) a l'é dipendent da n'àutr sondagi (id=$3) a pàgina $2, ma ël sondagi a esist pa o a l'é pa stàit ancor salvà. |
| 2089 | +Ch'a gava l'atribù ëd dipendensa, o ch'a crea ël sondagi con id=$3 a la pàgina $2 e ch'a lo salva. |
| 2090 | +Për salvé un sondagi, ch'a lo spedissa sensa arsponde a gnun-e custion ëd propòsta.", |
| 2091 | + 'qp_error_vote_dependance_poll' => 'Për piasì vòta për ël sondagi $1 prima.', |
| 2092 | + 'qp_error_too_many_spans' => 'Tròpe partìe ëd categorìe për ël nùmer total ëd sot-categorìe definìe', |
| 2093 | + 'qp_error_unanswered_span' => 'Sotcategorìe pa arspondùe', |
| 2094 | + 'qp_error_non_unique_choice' => 'Sta custion-sì a veul na sola arspòsta ëd propòsta', |
| 2095 | + 'qp_error_category_name_empty' => "Ël nòm categorìa a l'é veuid", |
| 2096 | + 'qp_error_proposal_text_empty' => "Ël test ëd propòsta a l'é veuid", |
| 2097 | + 'qp_error_too_few_categories' => 'Almanch doe categorìe a devo esse definìe', |
| 2098 | + 'qp_error_too_few_spans' => 'Minca partìa ëd categorìe a deuv conten-e almanch doe sot-categorìe', |
| 2099 | + 'qp_error_no_answer' => 'Propòsta sensa rispòsta', |
| 2100 | + 'qp_error_unique' => "La custion ëd sòrt ùnica() a l'ha pi propòste che arspòste possìbij definìe: impossìbil da completé", |
| 2101 | +); |
| 2102 | + |
| 2103 | +/** Pashto (پښتو) |
| 2104 | + * @author Ahmed-Najib-Biabani-Ibrahimkhel |
| 2105 | + */ |
| 2106 | +$messages['ps'] = array( |
| 2107 | + 'qp_result_NA' => 'بې ځوابه', |
| 2108 | + 'qp_vote_button' => 'رايه ورکول', |
| 2109 | + 'qp_vote_again_button' => 'خپله رايه بدلول', |
| 2110 | + 'qp_users_list' => 'د ټولو کارنانو لړليک جوړول', |
| 2111 | + 'qp_votes_count' => '$1 {{PLURAL:$1|رايه|رايې}}', |
| 2112 | + 'qp_source_link' => 'سرچينه', |
| 2113 | + 'qp_users_link' => 'کارنان', |
| 2114 | + 'qp_order_by_username' => 'د کارن-نوم له مخې اوډل', |
| 2115 | + 'qp_users_answered_questions' => '$1 {{PLURAL:$1|کارن|کارنانو}} پوښتنې ځواب کړې', |
| 2116 | + 'qp_error_invalid_question_type' => 'د ناسمې پوښتنې ډول: $1', |
| 2117 | + 'qp_error_unanswered_span' => 'بې ځوابه څېرمه وېشنيزه', |
| 2118 | + 'qp_error_category_name_empty' => 'د وېشنيزې نوم تش دی', |
| 2119 | + 'qp_error_no_answer' => 'بې ځوابه وړانديز', |
| 2120 | +); |
| 2121 | + |
| 2122 | +/** Portuguese (Português) |
| 2123 | + * @author Hamilton Abreu |
| 2124 | + */ |
| 2125 | +$messages['pt'] = array( |
| 2126 | + 'pollresults' => 'Resultados das sondagens neste síte', |
| 2127 | + 'qp_desc' => 'Permite a criação de sondagens', |
| 2128 | + 'qp_desc-sp' => '[[Special:PollResults|Página especial]] para ver os resultados das sondagens', |
| 2129 | + 'qp_result_NA' => 'Sem resposta', |
| 2130 | + 'qp_result_error' => 'Erro sintáctico', |
| 2131 | + 'qp_vote_button' => 'Vote', |
| 2132 | + 'qp_vote_again_button' => 'Altere o seu voto', |
| 2133 | + 'qp_polls_list' => 'Listar todas as sondagens', |
| 2134 | + 'qp_users_list' => 'Listar todos os utilizadores', |
| 2135 | + 'qp_browse_to_poll' => 'Navegar para $1', |
| 2136 | + 'qp_browse_to_user' => 'Navegar para $1', |
| 2137 | + 'qp_votes_count' => '$1 {{PLURAL:$1|voto|votos}}', |
| 2138 | + 'qp_source_link' => 'Fonte', |
| 2139 | + 'qp_stats_link' => 'Estatísticas', |
| 2140 | + 'qp_users_link' => 'Utilizadores', |
| 2141 | + 'qp_voice_link' => 'Voz do utilizador', |
| 2142 | + 'qp_voice_link_inv' => 'Voz do utilizador?', |
| 2143 | + 'qp_user_polls_link' => 'Participou {{PLURAL:$1|numa sondagem|em $1 sondagens}}', |
| 2144 | + 'qp_user_missing_polls_link' => 'Nenhuma participação', |
| 2145 | + 'qp_not_participated_link' => 'Não participada', |
| 2146 | + 'qp_order_by_username' => 'Ordenar por utilizador', |
| 2147 | + 'qp_order_by_polls_count' => 'Ordenar por contagem de sondagens', |
| 2148 | + 'qp_results_line_qupl' => 'Página "$1" Sondagem "$2": $3', |
| 2149 | + 'qp_results_line_qpl' => 'Página "$1" Sondagem "$2": $3, $4, $5, $6', |
| 2150 | + 'qp_header_line_qpul' => '$1 [ Página "$2" Sondagem "$3" ]', |
| 2151 | + 'qp_export_to_xls' => 'Exportar estatísticas para o formato XLS', |
| 2152 | + 'qp_voices_to_xls' => 'Exportar vozes para o formato XLS', |
| 2153 | + 'qp_users_answered_questions' => '{{PLURAL:$1|Um utilizador respondeu|$1 utilizadores responderam}} às questões', |
| 2154 | + 'qp_func_no_such_poll' => 'Sondagem inexistente ($1)', |
| 2155 | + 'qp_func_missing_question_id' => 'Por favor, especifique o número de uma pergunta existente (começando a partir de 1) para a sondagem $1', |
| 2156 | + 'qp_func_invalid_question_id' => 'Número de pergunta=$2 é inválido (não é numérico) para a sondagem $1', |
| 2157 | + 'qp_func_missing_proposal_id' => 'Por favor, especifique o número de uma proposta existente (começando a partir de 0) para a sondagem $1, pergunta $2', |
| 2158 | + 'qp_func_invalid_proposal_id' => 'Número de proposta=$3 é inválido (não é numérico) para a sondagem $1, pergunta $2', |
| 2159 | + 'qp_error_no_such_poll' => 'Sondagem inexistente ($1). |
| 2160 | +Verifique que a sondagem foi declarada e gravada, certifique-se também de que foi usado o carácter delimitador #', |
| 2161 | + 'qp_error_in_question_header' => 'Cabeçalho de pergunta inválido: $1', |
| 2162 | + 'qp_error_id_in_stats_mode' => 'Não é possível declarar um identificador da sondagem em modo estatístico', |
| 2163 | + 'qp_error_dependance_in_stats_mode' => 'Não é possível declarar uma cadeia de dependências da sondagem em modo estatístico', |
| 2164 | + 'qp_error_no_stats' => 'Não estão disponíveis dados estatísticos, porque ainda ninguém votou nesta sondagem (endereço=$1)', |
| 2165 | + 'qp_error_address_in_decl_mode' => 'Não é possível obter um endereço da sondagem em modo declarativo', |
| 2166 | + 'qp_error_question_not_implemented' => 'Não estão implementadas perguntas do tipo: $1', |
| 2167 | + 'qp_error_invalid_question_type' => 'Tipo de pergunta inválido: $1', |
| 2168 | + 'qp_error_type_in_stats_mode' => 'Não é possível definir no modo de visionamento estatístico o tipo de pergunta: $1', |
| 2169 | + 'qp_error_no_poll_id' => "Não foi definido um atributo de identificação no marcador ''(tag)'' da sondagem", |
| 2170 | + 'qp_error_invalid_poll_id' => 'Identificador de sondagem inválido (id=$1). |
| 2171 | +O identificador só pode conter letras, números e espaços', |
| 2172 | + 'qp_error_already_used_poll_id' => 'O identificador da sondagem (id=$1) já foi usado nesta página', |
| 2173 | + 'qp_error_invalid_dependance_value' => 'A cadeia de dependências da sondagem (id=$1) tem um valor inválido no atributo da dependência (dependance="$2")', |
| 2174 | + 'qp_error_missed_dependance_title' => 'A sondagem (id=$1) está dependente de outra sondagem (id=$3) da página [[$2]], mas o título [[$2]] não foi encontrado. |
| 2175 | +Remova o atributo da dependência ou restaure a página [[$2]]', |
| 2176 | + 'qp_error_missed_dependance_poll' => 'A sondagem (id=$1) está dependente de outra sondagem (id=$3) da página $2, mas essa sondagem não existe ou ainda não foi gravada. |
| 2177 | +Remova o atributo da dependência ou crie a sondagem com id=$3 na página $2 e grave-a. |
| 2178 | +Para gravar uma sondagem, submeta-a sem ter respondido a nenhuma pergunta.', |
| 2179 | + 'qp_error_vote_dependance_poll' => 'Por favor, vote na sondagem $1 antes.', |
| 2180 | + 'qp_error_too_many_spans' => 'Demasiadas classes de categorias para as subcategorias definidas', |
| 2181 | + 'qp_error_unanswered_span' => 'Subcategoria sem resposta', |
| 2182 | + 'qp_error_non_unique_choice' => 'Esta pergunta requer resposta a uma única proposta', |
| 2183 | + 'qp_error_category_name_empty' => 'O nome da categoria está vazio', |
| 2184 | + 'qp_error_proposal_text_empty' => 'O texto da proposta está vazio', |
| 2185 | + 'qp_error_too_few_categories' => 'Deve definir pelo menos duas categorias', |
| 2186 | + 'qp_error_too_few_spans' => 'Cada classe de categorias requer pelo menos duas respostas possíveis definidas', |
| 2187 | + 'qp_error_no_answer' => 'Proposta sem resposta', |
| 2188 | + 'qp_error_unique' => 'Pergunta do tipo unique() tem mais propostas definidas do que respostas possíveis: impossível de completar', |
| 2189 | +); |
| 2190 | + |
| 2191 | +/** Brazilian Portuguese (Português do Brasil) |
| 2192 | + * @author Giro720 |
| 2193 | + * @author Helder.wiki |
| 2194 | + * @author Heldergeovane |
| 2195 | + * @author Luckas Blade |
| 2196 | + * @author Raylton P. Sousa |
| 2197 | + */ |
| 2198 | +$messages['pt-br'] = array( |
| 2199 | + 'pollresults' => "Resultados de enquetes neste ''site''", |
| 2200 | + 'qp_desc' => 'Habilita a criação de enquetes', |
| 2201 | + 'qp_desc-sp' => '[[Special:PollResults|Página especial]] para visulizar os resultados das enquetes', |
| 2202 | + 'qp_result_NA' => 'Não respondido', |
| 2203 | + 'qp_result_error' => 'Erro de sintaxe', |
| 2204 | + 'qp_vote_button' => 'Votar', |
| 2205 | + 'qp_vote_again_button' => 'Alterar o seu voto', |
| 2206 | + 'qp_polls_list' => 'Listar todas as enquetes', |
| 2207 | + 'qp_users_list' => 'Listar todos os usuários', |
| 2208 | + 'qp_browse_to_poll' => 'Navegar para $1', |
| 2209 | + 'qp_browse_to_user' => 'Navegar para $1', |
| 2210 | + 'qp_votes_count' => '$1 {{PLURAL:$1|voto|votos}}', |
| 2211 | + 'qp_source_link' => 'Fonte', |
| 2212 | + 'qp_stats_link' => 'Estatísticas', |
| 2213 | + 'qp_users_link' => 'Usuários', |
| 2214 | + 'qp_voice_link' => 'Voz do usuário', |
| 2215 | + 'qp_voice_link_inv' => 'Voz do usuário?', |
| 2216 | + 'qp_user_polls_link' => 'Participou {{PLURAL:$1|numa sondagem|em $1 sondagens}}', |
| 2217 | + 'qp_user_missing_polls_link' => 'Nenhuma participação', |
| 2218 | + 'qp_not_participated_link' => 'Não participada', |
| 2219 | + 'qp_order_by_username' => 'Ordenar por nome de usuário', |
| 2220 | + 'qp_order_by_polls_count' => 'Ordenar por contagem de sondagens', |
| 2221 | + 'qp_results_line_qupl' => 'Página "$1" Sondagem "$2": $3', |
| 2222 | + 'qp_results_line_qpl' => 'Página "$1" Sondagem "$2": $3, $4, $5, $6', |
| 2223 | + 'qp_header_line_qpul' => '$1 [ Página "$2" Sondagem "$3" ]', |
| 2224 | + 'qp_export_to_xls' => 'Exportar estatísticas para o formato XLS', |
| 2225 | + 'qp_voices_to_xls' => 'Exportar vozes para o formato XLS', |
| 2226 | + 'qp_users_answered_questions' => '{{PLURAL:$1|Um usuário respondeu|$1 usuários responderam}} às questões', |
| 2227 | + 'qp_func_no_such_poll' => 'Sondagem inexistente ($1)', |
| 2228 | + 'qp_func_missing_question_id' => 'Por favor, especifique o número de uma pergunta existente (começando a partir de 1) para a sondagem $1', |
| 2229 | + 'qp_func_invalid_question_id' => 'Número de pergunta=$2 é inválido (não é numérico) para a sondagem $1', |
| 2230 | + 'qp_func_missing_proposal_id' => 'Por favor, especifique o número de uma proposta existente (começando a partir de 0) para a sondagem $1, pergunta $2', |
| 2231 | + 'qp_func_invalid_proposal_id' => 'Número de proposta=$3 é inválido (não é numérico) para a sondagem $1, pergunta $2', |
| 2232 | + 'qp_error_no_such_poll' => 'Sondagem inexistente ($1). |
| 2233 | +Verifique que a sondagem foi declarada e gravada, certifique-se também de que foi usado o carácter delimitador #', |
| 2234 | + 'qp_error_in_question_header' => 'Cabeçalho de pergunta inválido: $1', |
| 2235 | + 'qp_error_id_in_stats_mode' => 'Não é possível declarar um identificador da sondagem em modo estatístico', |
| 2236 | + 'qp_error_dependance_in_stats_mode' => 'Não é possível declarar uma cadeia de dependências da sondagem em modo estatístico', |
| 2237 | + 'qp_error_no_stats' => 'Não estão disponíveis dados estatísticos, porque ainda ninguém votou nesta sondagem (endereço=$1)', |
| 2238 | + 'qp_error_address_in_decl_mode' => 'Não é possível obter um endereço da sondagem em modo declarativo', |
| 2239 | + 'qp_error_question_not_implemented' => 'Não estão implementadas perguntas do tipo: $1', |
| 2240 | + 'qp_error_invalid_question_type' => 'Tipo de pergunta inválido: $1', |
| 2241 | + 'qp_error_type_in_stats_mode' => 'Não é possível definir no modo de visualização estatística o tipo de pergunta: $1', |
| 2242 | + 'qp_error_no_poll_id' => 'Não foi definido um atributo de identificação no marcador da sondagem', |
| 2243 | + 'qp_error_invalid_poll_id' => 'Identificador de sondagem inválido (id=$1). |
| 2244 | +O identificador só pode conter letras, números e espaços', |
| 2245 | + 'qp_error_already_used_poll_id' => 'O identificador da sondagem (id=$1) já foi usado nesta página', |
| 2246 | + 'qp_error_invalid_dependance_value' => 'A cadeia de dependências da sondagem (id=$1) tem um valor inválido no atributo da dependência (dependance="$2")', |
| 2247 | + 'qp_error_missed_dependance_title' => 'A sondagem (id=$1) está dependente de outra sondagem (id=$3) da página [[$2]], mas o título [[$2]] não foi encontrado. |
| 2248 | +Remova o atributo da dependência ou restaure a página [[$2]]', |
| 2249 | + 'qp_error_missed_dependance_poll' => 'A sondagem (id=$1) está dependente de outra sondagem (id=$3) da página $2, mas essa sondagem não existe ou ainda não foi salva. |
| 2250 | +Remova o atributo da dependência ou crie a sondagem com id=$3 na página $2 e salve-a. |
| 2251 | +Para gravar uma sondagem, submeta-a sem ter respondido a nenhuma pergunta.', |
| 2252 | + 'qp_error_vote_dependance_poll' => 'Por favor, vote na sondagem $1 antes.', |
| 2253 | + 'qp_error_too_many_spans' => 'Demasiadas classes de categorias para as subcategorias definidas', |
| 2254 | + 'qp_error_unanswered_span' => 'Subcategoria sem resposta', |
| 2255 | + 'qp_error_non_unique_choice' => 'Esta pergunta requer resposta a uma única proposta', |
| 2256 | + 'qp_error_category_name_empty' => 'O nome da categoria está vazio', |
| 2257 | + 'qp_error_proposal_text_empty' => 'O texto da proposta está vazio', |
| 2258 | + 'qp_error_too_few_categories' => 'Pelo menos duas categorias devem ser definidas', |
| 2259 | + 'qp_error_too_few_spans' => 'Cada classe de categorias requer pelo menos duas respostas possíveis definidas', |
| 2260 | + 'qp_error_no_answer' => 'Proposta sem resposta', |
| 2261 | + 'qp_error_unique' => 'Pergunta do tipo unique() tem mais propostas definidas do que respostas possíveis: impossível de completar', |
| 2262 | +); |
| 2263 | + |
| 2264 | +/** Romanian (Română) |
| 2265 | + * @author Firilacroco |
| 2266 | + * @author Stelistcristi |
| 2267 | + */ |
| 2268 | +$messages['ro'] = array( |
| 2269 | + 'qp_result_error' => 'Eroare de sintaxă', |
| 2270 | + 'qp_vote_button' => 'Votați', |
| 2271 | + 'qp_polls_list' => 'Arătați toate sondajele', |
| 2272 | + 'qp_users_list' => 'Arătați toți utilizatorii', |
| 2273 | + 'qp_source_link' => 'Sursa', |
| 2274 | + 'qp_stats_link' => 'Statistici', |
| 2275 | + 'qp_users_link' => 'Utilizatori', |
| 2276 | + 'qp_voice_link' => 'Vocea utilizatorului', |
| 2277 | + 'qp_voice_link_inv' => 'Vocea utilizatorului?', |
| 2278 | + 'qp_order_by_username' => 'Ordonează după numele utilizatorilor', |
| 2279 | +); |
| 2280 | + |
| 2281 | +/** Tarandíne (Tarandíne) |
| 2282 | + * @author Joetaras |
| 2283 | + */ |
| 2284 | +$messages['roa-tara'] = array( |
| 2285 | + 'qp_vote_button' => 'Vote', |
| 2286 | + 'qp_stats_link' => 'Statisteche', |
| 2287 | + 'qp_users_link' => 'Utinde', |
| 2288 | +); |
| 2289 | + |
| 2290 | +/** Russian (Русский) |
| 2291 | + * @author QuestPC |
| 2292 | + * @author Александр Сигачёв |
| 2293 | + */ |
| 2294 | +$messages['ru'] = array( |
| 2295 | + 'pollresults' => 'Результаты опросов на сайте', |
| 2296 | + 'qp_desc' => 'Позволяет создавать опросы', |
| 2297 | + 'qp_desc-sp' => '[[Special:PollResults|Специальная страница]] для просмотра результатов опросов', |
| 2298 | + 'qp_result_NA' => 'Нет ответа', |
| 2299 | + 'qp_result_error' => 'Синтаксическая ошибка', |
| 2300 | + 'qp_vote_button' => 'Проголосовать', |
| 2301 | + 'qp_vote_again_button' => 'Переголосовать', |
| 2302 | + 'qp_polls_list' => 'Список всех опросов', |
| 2303 | + 'qp_users_list' => 'Список всех участников', |
| 2304 | + 'qp_browse_to_poll' => 'Перейти к $1', |
| 2305 | + 'qp_browse_to_user' => 'Перейти к $1', |
| 2306 | + 'qp_votes_count' => '$1 {{PLURAL:$1|голос|голоса|голосов}}', |
| 2307 | + 'qp_source_link' => 'Исходный код', |
| 2308 | + 'qp_stats_link' => 'Статистика', |
| 2309 | + 'qp_users_link' => 'Участники', |
| 2310 | + 'qp_voice_link' => 'Голос участника', |
| 2311 | + 'qp_voice_link_inv' => 'Голос участника?', |
| 2312 | + 'qp_user_polls_link' => 'Участвовал в $1 {{PLURAL:$1|опросе|опросах|опросах}}', |
| 2313 | + 'qp_user_missing_polls_link' => 'Неучастие в опросах', |
| 2314 | + 'qp_not_participated_link' => 'Список неучаствовавших', |
| 2315 | + 'qp_order_by_username' => 'Сортировать по имени пользователя', |
| 2316 | + 'qp_order_by_polls_count' => 'Сортировать по количеству опросов', |
| 2317 | + 'qp_results_line_qupl' => 'Страница "$1" Опрос "$2": $3', |
| 2318 | + 'qp_results_line_qpl' => 'Страница "$1" Опрос "$2": $3, $4, $5, $6', |
| 2319 | + 'qp_header_line_qpul' => '$1 [ Страница "$2" Опрос "$3" ]', |
| 2320 | + 'qp_results_line_qpul' => '$1: $2', |
| 2321 | + 'qp_header_line_qucl' => '$1. $2<br />$3 ??? $4', |
| 2322 | + 'qp_results_line_qucl' => '$1: $2 $3', |
| 2323 | + 'qp_export_to_xls' => 'Экспортировать статистику в XLS формате', |
| 2324 | + 'qp_voices_to_xls' => 'Экспортировать голоса в XLS формате', |
| 2325 | + 'qp_users_answered_questions' => 'На вопросы {{PLURAL:$1|ответил $1 участник|ответило $1 участника|ответили $1 участников}}', |
| 2326 | + 'qp_func_no_such_poll' => 'Опрос не найден ($1)', |
| 2327 | + 'qp_func_missing_question_id' => 'Укажите существующий идентификатор вопроса (начинающийся с единицы) для опроса $1', |
| 2328 | + 'qp_func_invalid_question_id' => 'Ошибочный идентификатор вопроса (question id=$2 - требуется числовое значение) для опроса $1', |
| 2329 | + 'qp_func_missing_proposal_id' => 'Укажите идентификатор строки (начинающийся с нуля) для опроса $1, вопроса $2', |
| 2330 | + 'qp_func_invalid_proposal_id' => 'Ошибочный идентификатор строки (proposal id=$3 - требуется числовое значение) для опроса $1, вопроса $2', |
| 2331 | + 'qp_error_no_such_poll' => 'Опрос не найден ($1). Убедитесь что заданный опрос определён и сохранён, а также что используется символ разделителя адреса #', |
| 2332 | + 'qp_error_in_question_header' => 'Неверный заголовок вопроса: $1', |
| 2333 | + 'qp_error_id_in_stats_mode' => 'Недопустимо определять идентификатор опроса (id) в статистическом режиме вывода', |
| 2334 | + 'qp_error_dependance_in_stats_mode' => 'Недопустимо определять атрибут зависимости опроса (dependance) в статистическом режиме', |
| 2335 | + 'qp_error_no_stats' => 'Статистика голосования недоступна, так как еще никто не голосовал в этом опросе (address=$1)', |
| 2336 | + 'qp_error_address_in_decl_mode' => 'Недопустимо задавать адрес опроса (address) в режиме определения', |
| 2337 | + 'qp_error_question_not_implemented' => 'Вопросы данного типа не реализованы в коде расширения: $1', |
| 2338 | + 'qp_error_invalid_question_type' => 'Недопустимый тип вопроса: $1', |
| 2339 | + 'qp_error_type_in_stats_mode' => 'Недопустимо определять тип вопроса в статистическом режиме: $1', |
| 2340 | + 'qp_error_no_poll_id' => 'Тэг опроса не имеет атрибута id.', |
| 2341 | + 'qp_error_invalid_poll_id' => 'Недопустимый идентификатор опроса (id=$1). Идентификатор опроса может содержать только буквы, цифры и символ пробела', |
| 2342 | + 'qp_error_already_used_poll_id' => 'Установленный атрибут id опроса уже используется другим опросом на данной странице (id=$1).', |
| 2343 | + 'qp_error_invalid_dependance_value' => 'В цепочке зависимости опросов для опроса (id=$1) было найдено синтаксически неверное значение атрибута зависимости (dependance="$2")', |
| 2344 | + 'qp_error_missed_dependance_title' => 'Опрос с идентификатором id=$1 имеет атрибут зависимости от другого опроса (id=$3), находящегося на отсутствующей странице [[$2]]. Необходимо убрать атрибут зависимости от другого опроса, либо восстановить страницу [[$2]]', |
| 2345 | + 'qp_error_missed_dependance_poll' => 'Опрос с идентификатором id=$1 требует прохождения другого опроса с идентификатором id=$3, находящегося на странице $2. Однако же, последний не был найден. Необходимо удалить атрибут зависимости из опроса (id=$1), либо создать опрос с идентификатором id=$3 на странице $2 и сохранить его. Для сохранения опроса будет достаточно нажать кнопку "Проголосовать", не отвечая ни на один вопрос.', |
| 2346 | + 'qp_error_vote_dependance_poll' => 'Пожалуйста ответьте сначала на опрос $1.', |
| 2347 | + 'qp_error_too_many_spans' => 'Определено слишком много классов для подкатегорий вопросов', |
| 2348 | + 'qp_error_unanswered_span' => 'Подкатегория вопроса без ответа', |
| 2349 | + 'qp_error_non_unique_choice' => 'Данный вопрос требует чтобы выбранный вариант ответа не использовался ранее', |
| 2350 | + 'qp_error_category_name_empty' => 'Отсутствует название варианта ответа', |
| 2351 | + 'qp_error_proposal_text_empty' => 'Отсутствует текст строки вопроса', |
| 2352 | + 'qp_error_too_few_categories' => 'Каждый вопрос должен иметь по крайней мере два варианта ответа', |
| 2353 | + 'qp_error_too_few_spans' => 'Каждая подкатегория вопроса требует по меньшей мере два варианта ответа', |
| 2354 | + 'qp_error_no_answer' => 'Нет ответа на вопрос', |
| 2355 | + 'qp_error_unique' => 'Опрос, имеющий тип unique(), не должен иметь больше ответов чем вопросов', |
| 2356 | +); |
| 2357 | + |
| 2358 | +/** Rusyn (Русиньскый) |
| 2359 | + * @author Gazeb |
| 2360 | + */ |
| 2361 | +$messages['rue'] = array( |
| 2362 | + 'qp_stats_link' => 'Штатістікы', |
| 2363 | + 'qp_users_link' => 'Хоснователї', |
| 2364 | +); |
| 2365 | + |
| 2366 | +/** Serbian Cyrillic ekavian (Српски (ћирилица)) |
| 2367 | + * @author Rancher |
| 2368 | + * @author Михајло Анђелковић |
| 2369 | + */ |
| 2370 | +$messages['sr-ec'] = array( |
| 2371 | + 'qp_desc' => 'Омогућава покретање анкета', |
| 2372 | + 'qp_result_NA' => 'Није одговорено', |
| 2373 | + 'qp_result_error' => 'Синтаксна грешка', |
| 2374 | + 'qp_vote_button' => 'Гласај', |
| 2375 | + 'qp_vote_again_button' => 'Промените свој глас', |
| 2376 | + 'qp_polls_list' => 'Прикажи све анкете', |
| 2377 | + 'qp_users_list' => 'Прикажи све кориснике', |
| 2378 | + 'qp_votes_count' => '$1 {{PLURAL:$1|глас|гласа|гласа|гласа|гласова}}', |
| 2379 | + 'qp_stats_link' => 'Статистика', |
| 2380 | + 'qp_users_link' => 'Корисници', |
| 2381 | + 'qp_user_polls_link' => 'Учествовао у $1 {{PLURAL:$1|анкети|анкета}}', |
| 2382 | +); |
| 2383 | + |
| 2384 | +/** Serbian Latin ekavian (Srpski (latinica)) */ |
| 2385 | +$messages['sr-el'] = array( |
| 2386 | + 'qp_desc' => 'Omogućava pokretanje anketa', |
| 2387 | + 'qp_result_NA' => 'Nije odgovoreno', |
| 2388 | + 'qp_result_error' => 'Sintaksna greška', |
| 2389 | + 'qp_vote_button' => 'Glasaj', |
| 2390 | + 'qp_vote_again_button' => 'Promenite svoj glas', |
| 2391 | + 'qp_polls_list' => 'Prikaži sve ankete', |
| 2392 | + 'qp_users_list' => 'Prikaži sve korisnike', |
| 2393 | + 'qp_votes_count' => '$1 {{PLURAL:$1|glas|glasa|glasa|glasa|glasova}}', |
| 2394 | + 'qp_stats_link' => 'Statistike', |
| 2395 | + 'qp_users_link' => 'Korisnici', |
| 2396 | + 'qp_user_polls_link' => 'Učestvovao u $1 {{PLURAL:$1|anketi|anketa}}', |
| 2397 | +); |
| 2398 | + |
| 2399 | +/** Swedish (Svenska) |
| 2400 | + * @author Ozp |
| 2401 | + * @author Per |
| 2402 | + */ |
| 2403 | +$messages['sv'] = array( |
| 2404 | + 'pollresults' => 'Resultat av omröstningarna på denna sida', |
| 2405 | + 'qp_desc' => 'Tillåter skapandet av frågeundersökningar', |
| 2406 | + 'qp_desc-sp' => '[[Special:PollResults|Specialsida]] för visning av resultat av omröstningarna', |
| 2407 | + 'qp_result_NA' => 'Inte besvarad', |
| 2408 | + 'qp_result_error' => 'Syntaxfel', |
| 2409 | + 'qp_vote_button' => 'Rösta', |
| 2410 | + 'qp_vote_again_button' => 'Ändra din röst', |
| 2411 | + 'qp_polls_list' => 'Lista alla röstningar', |
| 2412 | + 'qp_users_list' => 'Lista alla användare', |
| 2413 | + 'qp_browse_to_poll' => 'Bläddra till $1', |
| 2414 | + 'qp_browse_to_user' => 'Bläddra till $1', |
| 2415 | + 'qp_votes_count' => '$1 {{PLURAL:$1|röst|röster}}', |
| 2416 | + 'qp_source_link' => 'Källa', |
| 2417 | + 'qp_stats_link' => 'Statistik', |
| 2418 | + 'qp_users_link' => 'Användare', |
| 2419 | + 'qp_voice_link' => 'Användaråsikt', |
| 2420 | + 'qp_voice_link_inv' => 'Användaråsikt?', |
| 2421 | + 'qp_user_polls_link' => 'Deltagit i $1 {{PLURAL:$1|omröstning|omröstningar}}', |
| 2422 | + 'qp_user_missing_polls_link' => 'Ingen deltagelse', |
| 2423 | + 'qp_not_participated_link' => 'Inte deltagit', |
| 2424 | + 'qp_order_by_username' => 'Sortera efter användarnanm', |
| 2425 | + 'qp_order_by_polls_count' => 'Sortera efter antal omröstningar', |
| 2426 | + 'qp_results_line_qupl' => 'Sida "$1" Undersökning "$2": $3', |
| 2427 | + 'qp_results_line_qpl' => 'Sida "$1" Undersökning "$2": $3, $4, $5, $6', |
| 2428 | + 'qp_header_line_qpul' => '$1 [ Sida "$2" Frågeundersökning "$3" ]', |
| 2429 | + 'qp_export_to_xls' => 'Exportera statistik till XLS-format', |
| 2430 | + 'qp_users_answered_questions' => '$1 {{PLURAL:$1|användare|användare}} besvarade frågorna', |
| 2431 | + 'qp_func_no_such_poll' => 'Ingen sådan undersökning ($1)', |
| 2432 | + 'qp_error_no_such_poll' => 'Ingen sådan omröstning ($1). |
| 2433 | +Var säker på att omröstningen deklarerades och sparades, var också med att använda adressavgränsar-tecknet #', |
| 2434 | + 'qp_error_no_stats' => 'Ingen statistik är tillgänglig eftersom ingen ännu har röstat på denna undersökning (adress=$1)', |
| 2435 | + 'qp_error_question_not_implemented' => 'Frågor av den typen är inte implementerade: $1', |
| 2436 | + 'qp_error_invalid_question_type' => 'Ogiltig frågetyp:$1', |
| 2437 | + 'qp_error_already_used_poll_id' => 'Detta omröstnings-id har redan använts på denna sida (id=$1).', |
| 2438 | + 'qp_error_vote_dependance_poll' => 'Vänligen rösta i undersökningen $1 först.', |
| 2439 | + 'qp_error_too_many_spans' => 'För många kategorigrupper för det totala antalet underkategorier definerade', |
| 2440 | + 'qp_error_unanswered_span' => 'Obesvarad underkategori', |
| 2441 | + 'qp_error_non_unique_choice' => 'Denna fråga kräver unika svarsförslag', |
| 2442 | + 'qp_error_category_name_empty' => 'Kategorinamn är tomt', |
| 2443 | + 'qp_error_proposal_text_empty' => 'Förslagstext är tom', |
| 2444 | + 'qp_error_too_few_categories' => 'Minst två kategorier måste definieras', |
| 2445 | + 'qp_error_too_few_spans' => 'Varje kategorigrupp måste innehålla minst två underkategorier', |
| 2446 | + 'qp_error_no_answer' => 'Obesvarat förslag', |
| 2447 | +); |
| 2448 | + |
| 2449 | +/** Telugu (తెలుగు) |
| 2450 | + * @author Veeven |
| 2451 | + */ |
| 2452 | +$messages['te'] = array( |
| 2453 | + 'qp_votes_count' => '$1 {{PLURAL:$1|వోటు|వోట్లు}}', |
| 2454 | + 'qp_stats_link' => 'గణాంకాలు', |
| 2455 | + 'qp_users_link' => 'వాడుకరులు', |
| 2456 | + 'qp_users_answered_questions' => '$1 {{PLURAL:$1|వాడుకరి|గురు వాడుకరులు}} ప్రశ్నలకు జవాబిచ్చారు', |
| 2457 | + 'qp_error_category_name_empty' => 'వర్గం పేరు ఖాళీగా ఉంది', |
| 2458 | +); |
| 2459 | + |
| 2460 | +/** Turkmen (Türkmençe) |
| 2461 | + * @author Hanberke |
| 2462 | + */ |
| 2463 | +$messages['tk'] = array( |
| 2464 | + 'qp_users_link' => 'Ulanyjylar', |
| 2465 | +); |
| 2466 | + |
| 2467 | +/** Tagalog (Tagalog) |
| 2468 | + * @author AnakngAraw |
| 2469 | + */ |
| 2470 | +$messages['tl'] = array( |
| 2471 | + 'pollresults' => 'Mga resulta ng halalan sa sityong ito', |
| 2472 | + 'qp_desc' => 'Nagpapahintulot sa paglikha ng mga halalan', |
| 2473 | + 'qp_desc-sp' => '[[Special:PollResults|Natatnging pahina]] para sa pagtingin sa mga resulta ng mga halalan', |
| 2474 | + 'qp_result_NA' => 'Hindi sinagutan', |
| 2475 | + 'qp_result_error' => 'Kamalian sa palaugnayan', |
| 2476 | + 'qp_vote_button' => 'Bumoto', |
| 2477 | + 'qp_vote_again_button' => 'Baguhin ang boto mo', |
| 2478 | + 'qp_polls_list' => 'Talaan ng lahat ng mga pagboto', |
| 2479 | + 'qp_users_list' => 'Itala ang lahat ng mga tagagamit', |
| 2480 | + 'qp_browse_to_poll' => 'Tumingin-tingin sa $1', |
| 2481 | + 'qp_browse_to_user' => 'Tumingin-tingin sa $1', |
| 2482 | + 'qp_votes_count' => '$1 {{PLURAL:$1|boto|mga boto}}', |
| 2483 | + 'qp_source_link' => 'Pinagmulan', |
| 2484 | + 'qp_stats_link' => 'Estadistika', |
| 2485 | + 'qp_users_link' => 'Mga tagagamit', |
| 2486 | + 'qp_voice_link' => 'Tinig ng tagagamit', |
| 2487 | + 'qp_voice_link_inv' => 'Tinig ng tagagamit?', |
| 2488 | + 'qp_user_polls_link' => 'Nakilahok sa $1 {{PLURAL:$1|botohan|mga botohan}}', |
| 2489 | + 'qp_user_missing_polls_link' => 'Walang pakikilahok', |
| 2490 | + 'qp_not_participated_link' => 'Hindi lumahok', |
| 2491 | + 'qp_order_by_username' => 'Pagkakasunud-sunod ayon sa pangalan ng tagagamit', |
| 2492 | + 'qp_order_by_polls_count' => 'Pagkakasunud-sunod ayon sa bilang ng botohan', |
| 2493 | + 'qp_results_line_qupl' => 'Pahina "$1" Botohan "$2": $3', |
| 2494 | + 'qp_results_line_qpl' => 'Pahina "$1" Botohan "$2": $3, $4, $5, $6', |
| 2495 | + 'qp_header_line_qpul' => '$1 [ Pahina "$2" Botohan "$3" ]', |
| 2496 | + 'qp_export_to_xls' => 'Iluwas ang estadistika sa anyong XLS', |
| 2497 | + 'qp_voices_to_xls' => 'Iluwas ang mga tinig papaloob sa anyong XLS', |
| 2498 | + 'qp_users_answered_questions' => '$1 {{PLURAL:$1|tagagamit|mga tagagamit}} sumagot sa mga tanong', |
| 2499 | + 'qp_func_no_such_poll' => 'Walang ganyang botohan ($1)', |
| 2500 | + 'qp_func_missing_question_id' => 'Mangyaring tukuyin ang isang umiiral na id ng tanong (simula sa 1) para sa botohang $1', |
| 2501 | + 'qp_func_invalid_question_id' => 'Hindi tanggap na tanong na id=$2 (hindi isang bilang) para sa botohang $1', |
| 2502 | + 'qp_func_missing_proposal_id' => 'Mangyaring tukuyin ang isang umiiral na iminungkahing id (simula sa 0) para sa botohang $1, tanong $2', |
| 2503 | + 'qp_func_invalid_proposal_id' => 'Hindi tanggap na mungkahing id=$3 (hindi isang bilang) para sa botohang $1, tanong $2', |
| 2504 | + 'qp_error_no_such_poll' => 'Walang ganyang botohan ($1). |
| 2505 | +Tiyaking na nagpahayag ang botohan at nasagip, tiyakin ding ginamit ang panghanggang tirahan ng panitik na #', |
| 2506 | + 'qp_error_in_question_header' => 'Hindi tanggap na paulo ng tanong: $1', |
| 2507 | + 'qp_error_id_in_stats_mode' => 'Hindi maipahayag ang ID ng botohan sa modalidad ng pang-estadistika', |
| 2508 | + 'qp_error_dependance_in_stats_mode' => 'Hindi maipahayag ang tanikalang pangsandig ng botohan sa modalidad na pang-estadistika', |
| 2509 | + 'qp_error_no_stats' => 'Walang makuhang datong pang-estadistika, dahil wala pang bumoboto para sa halalang ito, (tirahan=$1)', |
| 2510 | + 'qp_error_address_in_decl_mode' => 'Hindi makakuha ng tirahan ng botohan sa modalidad ng pagpapahayag', |
| 2511 | + 'qp_error_question_not_implemented' => 'Hindi ipinapatupad ang ganyang uri ng mga tanong: $1', |
| 2512 | + 'qp_error_invalid_question_type' => 'Hindi tanggap na uri ng tanong: $1', |
| 2513 | + 'qp_error_type_in_stats_mode' => 'Hindi mabigyang kahulugan ang uri ng tanong sa modalidad ng nagpapakita ng estadistika: $1', |
| 2514 | + 'qp_error_no_poll_id' => 'Walang tinukoy na id ng katangian ng tatak ng botohan.', |
| 2515 | + 'qp_error_invalid_poll_id' => 'Hindi tanggap na id ng botohan (id=$1). |
| 2516 | +Maaaring maglaman lang ang id ng botohan ng mga titik, mga bilang at patlang na panitik', |
| 2517 | + 'qp_error_already_used_poll_id' => 'Nagamit na ang id ng botohan sa pahinang ito (id=$1).', |
| 2518 | + 'qp_error_invalid_dependance_value' => 'Ang tanikala ng pagsandig ng botohan (id=$1) ay may hindi tanggap na halaga ng katangian ng pagsandig (pagsandig="$2")', |
| 2519 | + 'qp_error_missed_dependance_title' => 'Ang botohan (id=$1) ay nakasandig sa ibang botohan (id=$3) mula sa pahinang [[$2]], subalit hindi natagpuan ang pamagat na [[$2]]. |
| 2520 | +Maaaring tanggalin ang katangian ng pagsandig, o ibalik ang [[$2]]', |
| 2521 | + 'qp_error_missed_dependance_poll' => 'Ang botohang (id=$1) ay nakasandig sa ibang botohan (id=$3) sa pahinang $2, subalit hindi umiiral ang botohang iyon o hindi pa nasasagip. |
| 2522 | +Maaaring tanggalin ang katangian ng pagsandig, o likhain ang botohan na may id=$3 sa pahinang $2 at sagipin ito. |
| 2523 | +To save a poll, submit it while not answering to any proposal questions.', |
| 2524 | + 'qp_error_vote_dependance_poll' => 'Mangyaring bumoto muna para sa botohang $1.', |
| 2525 | + 'qp_error_too_many_spans' => 'Napakaraming tinukoy na mga pangkat ng kategorya para sa kabuoang bilang ng kabahaging mga kategorya', |
| 2526 | + 'qp_error_unanswered_span' => 'Hindi sinagot na kabahaging kategorya', |
| 2527 | + 'qp_error_non_unique_choice' => 'Nangangailangan ang tanong na ito ng natatanging sagot na pangmungkahi', |
| 2528 | + 'qp_error_category_name_empty' => 'Walang laman ang pangalan ng kategorya', |
| 2529 | + 'qp_error_proposal_text_empty' => 'Walang laman ang teksto ng mungkahi', |
| 2530 | + 'qp_error_too_few_categories' => 'Dapat na tumukoy ng kahit na dalawang mga kategorya', |
| 2531 | + 'qp_error_too_few_spans' => 'Dapat na maglaman ang bawat pangkat ng kategorya ng kahit na dalawang kabahaging mga kategorya', |
| 2532 | + 'qp_error_no_answer' => 'Hindi tinugunang mungkahi', |
| 2533 | + 'qp_error_unique' => 'Ang tanong ng uring natatangi() ay may mas maraming mga mungkahi kaysa tinukoy na maaaring mga tugon: hindi maaaring makumpleto', |
| 2534 | +); |
| 2535 | + |
| 2536 | +/** Turkish (Türkçe) |
| 2537 | + * @author Vito Genovese |
| 2538 | + */ |
| 2539 | +$messages['tr'] = array( |
| 2540 | + 'pollresults' => 'Bu sitedeki anketlerin sonuçları', |
| 2541 | + 'qp_desc' => 'Anket oluşturulmasını mümkün kılar', |
| 2542 | + 'qp_desc-sp' => 'Anketlerin sonuçlarının görüntülenmesi amaçlı [[Special:PollResults|özel sayfa]]', |
| 2543 | + 'qp_result_NA' => 'Cevaplanmadı', |
| 2544 | + 'qp_result_error' => 'Sözdizimi hatası', |
| 2545 | + 'qp_vote_button' => 'Oy ver', |
| 2546 | + 'qp_vote_again_button' => 'Oyunu değiştir', |
| 2547 | + 'qp_polls_list' => 'Tüm anketleri listele', |
| 2548 | + 'qp_users_list' => 'Tüm kullanıcıları listele', |
| 2549 | + 'qp_browse_to_poll' => '$1 adlı sayfaya gözat', |
| 2550 | + 'qp_browse_to_user' => '$1 adlı sayfaya gözat', |
| 2551 | + 'qp_votes_count' => '$1 {{PLURAL:$1|oy|oy}}', |
| 2552 | + 'qp_source_link' => 'Kaynak', |
| 2553 | + 'qp_stats_link' => 'İstatistikler', |
| 2554 | + 'qp_users_link' => 'Kullanıcılar', |
| 2555 | + 'qp_user_polls_link' => '$1 {{PLURAL:$1|ankete|ankete}} katılmış', |
| 2556 | + 'qp_user_missing_polls_link' => 'Katılım yok', |
| 2557 | + 'qp_not_participated_link' => 'Katılmadı', |
| 2558 | + 'qp_order_by_username' => 'Kullanıcı adına göre sırala', |
| 2559 | + 'qp_order_by_polls_count' => 'Anket sayılarına göre sırala', |
| 2560 | + 'qp_results_line_qupl' => 'Sayfa "$1" Anket "$2": $3', |
| 2561 | + 'qp_export_to_xls' => 'İstatistikleri XLS formatına aktar', |
| 2562 | + 'qp_users_answered_questions' => 'Sorulara $1 {{PLURAL:$1|kullanıcı|kullanıcı}} cevap verdi', |
| 2563 | + 'qp_func_no_such_poll' => 'Böyle bir anket yok ($1)', |
| 2564 | + 'qp_error_dependance_in_stats_mode' => 'İstatistik modunda anketin bağımlılık zinciri bildirilemiyor', |
| 2565 | + 'qp_error_no_stats' => 'İstatistiksel veri mevcut değil, çünkü hiç kimse bu anket için oy vermemiş (adres=$1)', |
| 2566 | + 'qp_error_question_not_implemented' => 'Bu türdeki sorular uygulamaya koyulmamaktadır: $1', |
| 2567 | + 'qp_error_invalid_question_type' => 'Geçersiz soru türü: $1', |
| 2568 | + 'qp_error_no_poll_id' => 'Anket etiketinin tanımlanmış bir kimlik değeri yok.', |
| 2569 | + 'qp_error_already_used_poll_id' => 'Anket kimliği bu sayfada önceden kullanılmış (kimlik=$1).', |
| 2570 | + 'qp_error_vote_dependance_poll' => 'Lütfen ilk olarak $1. anket için oy verin.', |
| 2571 | + 'qp_error_unanswered_span' => 'Cevaplanmamış alt kategori', |
| 2572 | + 'qp_error_category_name_empty' => 'Kategori adı boş', |
| 2573 | + 'qp_error_proposal_text_empty' => 'Teklif metni boş', |
| 2574 | + 'qp_error_too_few_categories' => 'En az iki kategori tanımlanmalı', |
| 2575 | + 'qp_error_too_few_spans' => 'Tüm kategori grupları en az iki alt kategori içermelidir', |
| 2576 | + 'qp_error_no_answer' => 'Cevaplanmamış teklif', |
| 2577 | +); |
| 2578 | + |
| 2579 | +/** Tatar (Cyrillic) (Татарча/Tatarça (Cyrillic)) |
| 2580 | + * @author Ильнар |
| 2581 | + */ |
| 2582 | +$messages['tt-cyrl'] = array( |
| 2583 | + 'qp_user_missing_polls_link' => 'Сорауларда катнашмау', |
| 2584 | + 'qp_not_participated_link' => 'Сорауларда катнашмаучылар исемлеге', |
| 2585 | + 'qp_order_by_username' => 'Кулланучы исеме буенча тәртипкә салу', |
| 2586 | + 'qp_order_by_polls_count' => 'Сорау алулар саны буенча тәртипкә салу', |
| 2587 | + 'qp_results_line_qupl' => '"$1" бит "$2": $3 сорау алу', |
| 2588 | + 'qp_results_line_qpl' => '"$1" бит "$2": $3, $4, $5, $6 сорау алу', |
| 2589 | + 'qp_header_line_qpul' => '$1 [ "$2" бит "$3" сорау алу ]', |
| 2590 | +); |
| 2591 | + |
| 2592 | +/** Ukrainian (Українська) |
| 2593 | + * @author NickK |
| 2594 | + * @author Prima klasy4na |
| 2595 | + * @author Тест |
| 2596 | + */ |
| 2597 | +$messages['uk'] = array( |
| 2598 | + 'qp_desc' => 'Дозволяє створювати опитування', |
| 2599 | + 'qp_result_error' => 'Синтаксична помилка', |
| 2600 | + 'qp_vote_button' => 'Проголосувати', |
| 2601 | + 'qp_source_link' => 'Джерело', |
| 2602 | + 'qp_stats_link' => 'Статистика', |
| 2603 | + 'qp_users_link' => 'Користувачі', |
| 2604 | + 'qp_users_answered_questions' => 'На питання {{PLURAL:$1|відповів $1 користувач|відповіли $1 користувачі|відповіли $1 користувачів}}', |
| 2605 | +); |
| 2606 | + |
| 2607 | +/** Yiddish (ייִדיש) |
| 2608 | + * @author פוילישער |
| 2609 | + */ |
| 2610 | +$messages['yi'] = array( |
| 2611 | + 'qp_vote_button' => 'שטימען', |
| 2612 | + 'qp_source_link' => 'מקור', |
| 2613 | +); |
| 2614 | + |
| 2615 | +/** Simplified Chinese (中文(简体)) |
| 2616 | + * @author Hydra |
| 2617 | + */ |
| 2618 | +$messages['zh-hans'] = array( |
| 2619 | + 'qp_vote_button' => '投票', |
| 2620 | + 'qp_vote_again_button' => '改变您的投票', |
| 2621 | + 'qp_source_link' => '来源', |
| 2622 | + 'qp_stats_link' => '统计', |
| 2623 | + 'qp_users_link' => '用户', |
| 2624 | +); |
| 2625 | + |
| 2626 | +/** Traditional Chinese (中文(繁體)) |
| 2627 | + * @author Mark85296341 |
| 2628 | + */ |
| 2629 | +$messages['zh-hant'] = array( |
| 2630 | + 'qp_result_NA' => '未回答', |
| 2631 | + 'qp_result_error' => '語法錯誤', |
| 2632 | + 'qp_vote_button' => '投票', |
| 2633 | + 'qp_vote_again_button' => '修改你的投票', |
| 2634 | + 'qp_polls_list' => '所有投票名單', |
| 2635 | + 'qp_users_list' => '列出所有使用者', |
| 2636 | + 'qp_source_link' => '來源', |
| 2637 | + 'qp_stats_link' => '統計', |
| 2638 | + 'qp_users_link' => '用戶', |
| 2639 | +); |
| 2640 | + |
Property changes on: trunk/extensions/QPoll/qp_i18n.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 2641 | + native |
Index: trunk/extensions/QPoll/qp_user.css |
— | — | @@ -9,7 +9,7 @@ |
10 | 10 | .qpoll table.object .spans { color:gray; } |
11 | 11 | .qpoll table.object .categories { color:#444455; } |
12 | 12 | .qpoll table.object .proposal { } |
13 | | -.qpoll .proposalerror { color:red; font-weight:600; } |
| 13 | +.qpoll .proposalerror { color:red; } |
14 | 14 | .qpoll .settings td { padding: 0.1em 0.4em 0.1em 0.4em } |
15 | 15 | .qpoll table.settings { background-color:transparent; } |
16 | 16 | /* Part for the basic types's inputs. */ |
— | — | @@ -26,27 +26,17 @@ |
27 | 27 | .qpoll .signl { text-align:center; border-bottom:1px solid gray; border-top: 1px solid gray; border-left: 1px solid gray; } |
28 | 28 | .qpoll .signc { text-align:center; border-bottom:1px solid gray; border-top: 1px solid gray; } |
29 | 29 | .qpoll .signr { text-align:center; border-bottom:1px solid gray; border-top: 1px solid gray; border-right: 1px solid gray; } |
30 | | -.qpoll .signt { text-align:center; border-left: 1px solid gray; border-right: 1px solid gray; border-top: 1px solid gray; } |
31 | | -.qpoll .signm { text-align:center; border-left: 1px solid gray; border-right: 1px solid gray; } |
| 30 | +.qpoll .signt { text-align:center; border-left: 1px solid gray; border-right: 1px solid gray; border-top:1px solid gray; } |
| 31 | +.qpoll .signm { text-align:center; border-left: 1px solid gray; border-right:1px solid gray; } |
32 | 32 | .qpoll .signb { text-align:center; border-left: 1px solid gray; border-right: 1px solid gray; border-bottom:1px solid gray; } |
33 | 33 | /* Part for the inputfields */ |
34 | | -.qpoll a.input, .qpoll a.input:hover, .qpoll a.input:active, .qpoll a.input:visited { text-decoration:none; color:black; outline: 0 } |
| 34 | +.qpoll a.input, .qpoll a.input:hover, .qpoll a.input:active, .qpoll a.input:visited { text-decoration:none; color:black; outline:0 } |
35 | 35 | .qpoll a.input span { outline:#7F9DB9 solid 1px; border:1px solid #7F9DB9; } /* *border is for IE6/7 star is removed due to ff console error */ |
36 | | -.qpoll .interp_error { border: 2px solid gray; padding: 0.5em; color: white; background-color: red; } |
37 | | -.qpoll .interp_answer { border: 2px solid gray; padding: 0.5em; color: black; background-color: lightblue; } |
38 | 36 | |
39 | | -.qpoll .cell_errror { background-color: #D700D7; } |
40 | | - |
41 | | -/* script view */ |
42 | | -.qpoll .line_numbers { font-family: monospace, "Courier New"; white-space:pre; color:green; background-color: lightgray; float:left; border-left: 1px solid darkgray; border-top: 1px solid darkgray; border-bottom: 1px solid darkgray; padding: 0.5em; } |
43 | | -.qpoll .script_view { font-family: monospace, "Courier New"; white-space:pre; overflow:auto; color:black; background-color: lightgray; border-right: 1px solid darkgray; border-top: 1px solid darkgray; border-bottom: 1px solid darkgray; padding: 0.5em; } |
44 | | - |
45 | 37 | /* LTR part (RTL is included from separate file */ |
46 | | -.qpoll .no_more_attempts { border: 1px solid gray; padding: 0.1em 0.5em 0.1em 0.5em; color: black; background-color: lightblue; margin-left: 1em; } |
47 | 38 | .qpoll .question { margin-left:2em; } |
48 | 39 | .qpoll .margin { padding-left:20px; } |
49 | 40 | .qpoll .header .questionId { font-size: 1.1em; font-weight: bold; float: left; } |
50 | 41 | .qpoll .header .questionId { *padding-right: 0.5em; } /* applies to IE7 and below */ |
51 | 42 | .qpoll a.input em { color:black; background-color:#DFDFDF; margin-right:1px; } |
52 | 43 | .qpoll a.input input { padding-left:2px; border:0; } |
53 | | -.qpoll .error_mark { border-left: 3px solid #D700D7; } |
Index: trunk/extensions/QPoll/qpoll.sql |
— | — | @@ -0,0 +1,75 @@ |
| 2 | +/* WARNING: do not use directly in case your wiki DB setup uses table prefixes |
| 3 | + * use Special:PollResults page instead |
| 4 | + * this file is primarily for debugging |
| 5 | + */ |
| 6 | + |
| 7 | +DROP TABLE IF EXISTS `qp_poll_desc`; |
| 8 | +CREATE TABLE `qp_poll_desc` ( |
| 9 | + `pid` int unsigned NOT NULL auto_increment, |
| 10 | + `article_id` int unsigned NOT NULL, |
| 11 | + `poll_id` tinytext NOT NULL, |
| 12 | + `order_id` int unsigned NOT NULL, |
| 13 | + `dependance` mediumtext NOT NULL, |
| 14 | + PRIMARY KEY poll (pid), |
| 15 | + UNIQUE INDEX article_poll (article_id,poll_id(128)) |
| 16 | +) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
| 17 | + |
| 18 | +DROP TABLE IF EXISTS `qp_question_desc`; |
| 19 | +CREATE TABLE `qp_question_desc` ( |
| 20 | + `pid` int unsigned NOT NULL, |
| 21 | + `question_id` int unsigned NOT NULL, |
| 22 | + `type` tinytext NOT NULL, |
| 23 | + `common_question` mediumtext NOT NULL, |
| 24 | + PRIMARY KEY question (pid,question_id), |
| 25 | + INDEX poll (pid) |
| 26 | +) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
| 27 | + |
| 28 | +/* spans are going there, too - separated with | */ |
| 29 | +DROP TABLE IF EXISTS `qp_question_categories`; |
| 30 | +CREATE TABLE `qp_question_categories` ( |
| 31 | + `pid` int unsigned NOT NULL, |
| 32 | + `question_id` int unsigned NOT NULL, |
| 33 | + `cat_id` int unsigned NOT NULL, |
| 34 | + `cat_name` tinytext NOT NULL, |
| 35 | + PRIMARY KEY category (pid,question_id,cat_id), |
| 36 | + INDEX poll (pid) |
| 37 | +) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
| 38 | + |
| 39 | +DROP TABLE IF EXISTS `qp_question_proposals`; |
| 40 | +CREATE TABLE `qp_question_proposals` ( |
| 41 | + `pid` int unsigned NOT NULL, |
| 42 | + `question_id` int unsigned NOT NULL, |
| 43 | + `proposal_id` int unsigned NOT NULL, |
| 44 | + `proposal_text` tinytext NOT NULL, |
| 45 | + PRIMARY KEY proposal (pid,question_id,proposal_id), |
| 46 | + INDEX poll (pid) |
| 47 | +) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
| 48 | + |
| 49 | +DROP TABLE IF EXISTS `qp_question_answers`; |
| 50 | +CREATE TABLE `qp_question_answers` ( |
| 51 | + `uid` int unsigned NOT NULL, |
| 52 | + `pid` int unsigned NOT NULL, |
| 53 | + `question_id` int unsigned NOT NULL, |
| 54 | + `proposal_id` int unsigned NOT NULL, |
| 55 | + `cat_id` int unsigned NOT NULL, |
| 56 | + `text_answer` mediumtext, |
| 57 | + PRIMARY KEY answer (uid,pid,question_id,proposal_id,cat_id), |
| 58 | + INDEX user_vote (uid,pid), |
| 59 | + INDEX poll_question (pid,question_id) |
| 60 | +) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
| 61 | + |
| 62 | +DROP TABLE IF EXISTS `qp_users_polls`; |
| 63 | +CREATE TABLE `qp_users_polls` ( |
| 64 | + `uid` int unsigned NOT NULL, |
| 65 | + `pid` int unsigned NOT NULL, |
| 66 | + PRIMARY KEY user_poll (uid,pid) |
| 67 | +) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
| 68 | + |
| 69 | +DROP TABLE IF EXISTS `qp_users`; |
| 70 | +CREATE TABLE `qp_users` ( |
| 71 | + `uid` int unsigned NOT NULL auto_increment, |
| 72 | + `name` tinytext NOT NULL, |
| 73 | + PRIMARY KEY unique_name (uid,name(64)), |
| 74 | + INDEX user_id (uid), |
| 75 | + INDEX username (name(64)) |
| 76 | +) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
Property changes on: trunk/extensions/QPoll/qpoll.sql |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 77 | + native |
Index: trunk/extensions/QPoll/INSTALL |
— | — | @@ -1,4 +1,4 @@ |
2 | | -MediaWiki extension QPoll, version 0.8.0a |
| 2 | +MediaWiki extension QPoll, version 0.7.0 |
3 | 3 | |
4 | 4 | * download the latest available version and extract it to your wiki extension directory. |
5 | 5 | * add the following line to LocalSettings.php |
— | — | @@ -7,7 +7,4 @@ |
8 | 8 | * check out Special:Version page to verify the installation |
9 | 9 | * login as user that has administrative rights, and go to Special:PollResults page. Database tables will be set up. Alternatively, you may load qpoll.sql to mysql database manually (remember that $wgDBprefix for the tables won't be used!). |
10 | 10 | |
11 | | -=== Upgrade === |
12 | | -Do not forget to open Special:Pollresults page to update DB schema (the script runs just once). |
13 | | - |
14 | 11 | See http://mediawiki.org/wiki/Extension:QPoll for further details. |
\ No newline at end of file |
Index: trunk/extensions/QPoll/qp_user_rtl.css |
— | — | @@ -1,8 +1,5 @@ |
2 | | -.qpoll .no_more_attempts { border: 1px solid gray; padding: 0.1em 0.5em 0.1em 0.5em; color: black; background-color: lightblue; margin-right: 1em; } |
3 | 2 | .qpoll .question { margin-right:2em; } |
4 | 3 | .qpoll .margin { padding-right:20px; } |
5 | 4 | .qpoll .header .questionId {font-size: 1.1em; font-weight: bold; float: right;} |
6 | | -.qpoll .header .questionId { *padding-left: 0.5em; } /* applies to IE7 and below */ |
7 | 5 | .qpoll a.input em { color:black; background-color:#DFDFDF; margin-left:1px; } |
8 | 6 | .qpoll a.input input { padding-right:2px; border:0; } |
9 | | -.qpoll .error_mark { border-right: 3px solid #D700D7; } |
Index: trunk/extensions/QPoll/qp_results.php |
— | — | @@ -28,11 +28,10 @@ |
29 | 29 | * * Add this line at the end of your LocalSettings.php file : |
30 | 30 | * require_once "$IP/extensions/QPoll/qp_user.php"; |
31 | 31 | * |
32 | | - * @version 0.8.0a |
| 32 | + * @version 0.7.0 |
33 | 33 | * @link http://www.mediawiki.org/wiki/Extension:QPoll |
34 | 34 | * @author QuestPC <questpc@rambler.ru> |
35 | 35 | */ |
36 | | - |
37 | 36 | if ( !defined( 'MEDIAWIKI' ) ) { |
38 | 37 | die( "This file is part of the QPoll extension. It is not a valid entry point.\n" ); |
39 | 38 | } |
— | — | @@ -40,50 +39,28 @@ |
41 | 40 | class PollResults extends SpecialPage { |
42 | 41 | |
43 | 42 | public function __construct() { |
44 | | - parent::__construct( 'PollResults', 'read' ); |
| 43 | + global $wgVersion; |
| 44 | + parent::__construct( 'PollResults', 'delete' ); |
45 | 45 | # for MW 1.15 (still being used by many customers) |
46 | | - # please do not remove until 2012 |
47 | | - if ( self::mediaWikiVersionCompare( '1.16' ) ) { |
48 | | - wfLoadExtensionMessages( 'QPoll' ); |
| 46 | + if ( version_compare( $wgVersion, '1.16', '<' ) ) { |
| 47 | + |
49 | 48 | } |
50 | 49 | } |
51 | 50 | |
52 | | - static $accessPermissions = array( 'read', 'showresults' ); |
53 | | - |
54 | 51 | static $skin = null; |
55 | 52 | static $UsersLink = ""; |
56 | 53 | static $PollsLink = ""; |
57 | 54 | |
58 | | - /** |
59 | | - * Checks if the given user (identified by an object) can execute this special page |
60 | | - * @param $user User: the user to check |
61 | | - * @return Boolean: does the user have permission to view the page? |
62 | | - */ |
63 | | - public function userCanExecute( $user ) { |
64 | | - # this fn is used to decide whether to show the page link at Special:Specialpages |
65 | | - foreach ( self::$accessPermissions as $permission ) { |
66 | | - if ( !$user->isAllowed( $permission ) ) { |
67 | | - return false; |
68 | | - } |
69 | | - } |
70 | | - return true; |
71 | | - } |
72 | | - |
73 | 55 | public function execute( $par ) { |
74 | 56 | global $wgOut, $wgRequest; |
75 | 57 | global $wgServer; // "http://www.yourserver.org" |
76 | 58 | // (should be equal to 'http://'.$_SERVER['SERVER_NAME']) |
77 | 59 | global $wgScript; // "/subdirectory/of/wiki/index.php" |
78 | 60 | global $wgUser; |
79 | | - |
80 | | - # check whether the user has sufficient permissions |
81 | | - foreach ( self::$accessPermissions as $permission ) { |
82 | | - if ( !$wgUser->isAllowed( $permission ) ) { |
83 | | - $wgOut->permissionRequired( $permission ); |
84 | | - return; |
85 | | - } |
| 61 | + if ( !$wgUser->isAllowed( 'delete' ) ) { |
| 62 | + $wgOut->permissionRequired('delete'); |
| 63 | + return; |
86 | 64 | } |
87 | | - |
88 | 65 | if ( class_exists( 'ResourceLoader' ) ) { |
89 | 66 | # MW 1.17+ |
90 | 67 | // $wgOut->addModules( 'jquery' ); |
— | — | @@ -104,7 +81,8 @@ |
105 | 82 | $wgOut->addHTML( '<div class="qpoll">' ); |
106 | 83 | $output = ""; |
107 | 84 | $this->setHeaders(); |
108 | | - if ( ( $result = $this->checkTables() ) !== true ) { |
| 85 | + $db = & wfGetDB( DB_SLAVE ); |
| 86 | + if ( ( $result = $this->checkTables( $db ) ) !== true ) { |
109 | 87 | # tables check failed |
110 | 88 | $wgOut->addHTML( $result ); |
111 | 89 | return; |
— | — | @@ -191,30 +169,10 @@ |
192 | 170 | $wgOut->addHTML( $output . '</div>' ); |
193 | 171 | } |
194 | 172 | |
195 | | - /** |
196 | | - * check for the existence of multiple fields in the selected database table |
197 | | - * @param $table table name |
198 | | - * @param $fields field names |
199 | | - */ |
200 | | - private function fieldsExists( $table, $fields ) { |
201 | | - $db = & wfGetDB( DB_SLAVE ); |
202 | | - if ( !is_array( $fields ) ) { |
203 | | - $fields = array( $fields ); |
204 | | - } |
205 | | - foreach( $fields as $field ) { |
206 | | - if ( !$db->fieldExists( $table, $field ) ) { |
207 | | - return false; |
208 | | - } |
209 | | - } |
210 | | - return true; |
211 | | - } |
212 | | - |
213 | | - /** |
214 | | - * check whether the extension tables exist in DB |
215 | | - * @return true if tables are found, string with error message otherwise |
216 | | - */ |
217 | | - private function checkTables() { |
218 | | - $db = & wfGetDB( DB_SLAVE ); |
| 173 | + # check whether the extension tables exist in DB |
| 174 | + # @param $db - MediaWiki database object |
| 175 | + # @return true if tables are found, string with error message otherwise |
| 176 | + private function checkTables( $db ) { |
219 | 177 | $sql_tables = array( |
220 | 178 | "qp_poll_desc", |
221 | 179 | "qp_question_desc", |
— | — | @@ -223,78 +181,33 @@ |
224 | 182 | "qp_question_answers", |
225 | 183 | "qp_users_polls", |
226 | 184 | "qp_users"); |
227 | | - $addFields = array( |
228 | | - 'qpoll_interpretation.src' => array( |
229 | | - 'qp_poll_desc' => array( 'interpretation_namespace', 'interpretation_title' ), |
230 | | - 'qp_users_polls' => array( 'attempts', 'short_interpretation', 'long_interpretation' ) |
231 | | - ) |
232 | | - ); |
233 | 185 | // check whether the tables were initialized |
234 | 186 | $tablesFound = 0; |
235 | 187 | $result = true; |
236 | 188 | foreach ( $sql_tables as $table ) { |
237 | | - if ( $db->tableExists( $table ) ) { |
| 189 | + $tname = str_replace( "`", "'", $db->tableName( $table ) ); |
| 190 | + $res = $db->query( "SHOW TABLE STATUS LIKE $tname" ); |
| 191 | + if ( $db->numRows( $res ) > 0 ) { |
238 | 192 | $tablesFound++; |
239 | 193 | } |
240 | 194 | } |
241 | | - if ( $tablesFound != count( $sql_tables ) ) { |
242 | | - # some tables are missing, serious DB error |
243 | | - return "Some of the extension database tables are missing.<br />Please restore from backup or drop the remaining extension tables, then reload this page."; |
244 | | - } |
245 | 195 | if ( $tablesFound == 0 ) { |
246 | | - # no tables were found, initialize the DB completely with minimal version |
247 | | - if ( ( $r = $db->sourceFile( qp_Setup::$ExtDir . '/tables/qpoll_0.7.0.src' ) ) !== true ) { |
248 | | - return $r; |
| 196 | + # no tables were found, initialize the DB completely |
| 197 | + $r = $db->sourceFile( qp_Setup::$ExtDir . "/qpoll.src" ); |
| 198 | + if ( $r === true ) { |
| 199 | + $result = 'Tables were initialized.<br />Please <a href="#" onclick="window.location.reload()">reload</a> this page to view future page edits.'; |
| 200 | + } else { |
| 201 | + $result = $r; |
249 | 202 | } |
| 203 | + } else { |
| 204 | + if ( $tablesFound != count( $sql_tables ) ) { |
| 205 | + # some tables are missing, serious DB error |
| 206 | + $result = "Some of the extension database tables are missing.<br />Please restore from backup or drop the remaining extension tables, then reload this page."; |
| 207 | + } |
250 | 208 | } |
251 | | - /* start of SQL updates */ |
252 | | - $scriptsToRun = array(); |
253 | | - foreach( $addFields as $script => &$table_list ) { |
254 | | - foreach( $table_list as $table => &$fields_list ) { |
255 | | - if ( !$this->fieldsExists( $table, $fields_list ) ) { |
256 | | - $scriptsToRun[$script] = true; |
257 | | - } |
258 | | - } |
259 | | - } |
260 | | - foreach( $scriptsToRun as $script => $val ) { |
261 | | - if ( ( $r = $db->sourceFile( qp_Setup::$ExtDir . "/archives/{$script}" ) ) !== true ) { |
262 | | - return $r; |
263 | | - } |
264 | | - } |
265 | | - /* end of SQL updates */ |
266 | | - if ( $tablesFound == 0 ) { |
267 | | - $result = 'Tables were initialized.'; |
268 | | - } |
269 | | - if ( count( $scriptsToRun ) > 0 ) { |
270 | | - $result = 'Tables were upgraded.'; |
271 | | - } |
272 | | - if ( is_string( $result ) ) { |
273 | | - $result .= '<br />Please <a href="#" onclick="window.location.reload()">reload</a> this page to view future page edits.'; |
274 | | - } |
275 | 209 | return $result; |
276 | 210 | } |
277 | 211 | |
278 | | - private function showAnswerHeader( qp_PollStore $pollStore ) { |
279 | | - $out = '<div style="font-weight:bold;">' . wfMsg( 'qp_results_submit_attempts', intval( $pollStore->attempts ) ) . '</div>'; |
280 | | - $interpTitle = $pollStore->getInterpTitle(); |
281 | | - if ( $interpTitle === null ) { |
282 | | - $out .= wfMsg( 'qp_poll_has_no_interpretation' ); |
283 | | - return $out; |
284 | | - } |
285 | | - /* |
286 | | - # currently, error is not stored in DB, only the vote and long / short interpretations |
287 | | - # todo: is it worth to store it? |
288 | | - if ( $pollStore->interpAnswer->error != '' ) { |
289 | | - return '<strong class="error">' . qp_Setup::specialchars( $pollStore->interpAnswer->error ) . '</strong>'; |
290 | | - } |
291 | | - */ |
292 | | - $out .= '<div class="interp_answer">' . wfMsg( 'qp_results_interpretation_header' ) . |
293 | | - '<div class="interp_answer_body">' . nl2br( wfMsg( 'qp_results_short_interpretation', qp_Setup::specialChars( $pollStore->interpAnswer->short ) ) ) . '</div>' . |
294 | | - '<div class="interp_answer_body">' . nl2br( wfMsg( 'qp_results_long_interpretation', qp_Setup::specialChars( $pollStore->interpAnswer->long ) ) ) . '</div>' . |
295 | | - '</div>'; |
296 | | - return $out; |
297 | | - } |
298 | | - |
299 | 212 | private function showUserVote( $pid, $uid ) { |
300 | 213 | $output = ""; |
301 | 214 | if ( $pid !== null && $uid !== null ) { |
— | — | @@ -308,11 +221,10 @@ |
309 | 222 | $pollStore->setLastUser( $userName, false ); |
310 | 223 | if ( $pollStore->loadUserVote() ) { |
311 | 224 | $poll_title = $pollStore->getTitle(); |
312 | | - # 'parentheses' is unavailable in MediaWiki 1.15.x |
| 225 | + # 'parentheses' is unavailable in 1.14.x |
313 | 226 | $poll_link = self::$skin->link( $poll_title, $poll_title->getPrefixedText() . wfMsg( 'word-separator' ) . wfMsg( 'qp_parentheses', $pollStore->mPollId ) ); |
314 | 227 | $output .= wfMsg( 'qp_browse_to_user', $user_link ) . "<br />\n"; |
315 | 228 | $output .= wfMsg( 'qp_browse_to_poll', $poll_link ) . "<br />\n"; |
316 | | - $output .= $this->showAnswerHeader( $pollStore ); |
317 | 229 | foreach ( $pollStore->Questions as $qkey => &$qdata ) { |
318 | 230 | $output .= "<br />\n<b>" . $qkey . ".</b> " . qp_Setup::entities( $qdata->CommonQuestion ) . "<br />\n"; |
319 | 231 | $output .= $this->displayUserQuestionVote( $qdata ); |
— | — | @@ -894,7 +806,7 @@ |
895 | 807 | |
896 | 808 | function formatResult( $skin, $result ) { |
897 | 809 | global $wgLang, $wgContLang; |
898 | | - $poll_title = Title::makeTitle( $result->ns, $result->title, qp_AbstractPoll::s_getPollTitleFragment( $result->poll_id, '' ) ); |
| 810 | + $poll_title = Title::makeTitle( $result->ns, $result->title, qp_AbstractPoll::getPollTitleFragment( $result->poll_id, '' ) ); |
899 | 811 | $pagename = qp_Setup::specialchars( $wgContLang->convert( $poll_title->getPrefixedText() ) ); |
900 | 812 | $pollname = qp_Setup::specialchars( $result->poll_id ); |
901 | 813 | $goto_link = self::$skin->link( $poll_title, wfMsg( 'qp_source_link' ) ); |
Index: trunk/extensions/QPoll/qp_results.css |
— | — | @@ -6,5 +6,3 @@ |
7 | 7 | .qpoll table.pollresults td.stats {background-color: Azure;} |
8 | 8 | .qpoll table.pollresults td.spaneven {background-color: Aquamarine;} |
9 | 9 | .qpoll table.pollresults td.spanodd {background-color: Moccasin;} |
10 | | -.qpoll .interp_answer { border: 1px solid gray; padding: 0; margin: 0; color: black; background-color: lightgray; font-weight:bold; line-height:2em; } |
11 | | -.qpoll .interp_answer_body { border: none; border-top: 1px solid gray; padding: 0.5em; margin-top: 0; color: black; background-color: Azure; font-weight: normal; line-height:normal; } |
Index: trunk/extensions/QPoll/qp_pollstore.php |
— | — | @@ -106,115 +106,24 @@ |
107 | 107 | return true; |
108 | 108 | } |
109 | 109 | |
110 | | -} /* end of qp_QuestionData class */ |
| 110 | +} |
111 | 111 | |
112 | | -class qp_InterpAnswer { |
113 | | - # short answer. it is supposed to be sortable and accountable in statistics |
114 | | - # blank value means short answer is unavailable |
115 | | - var $short = ''; |
116 | | - # long answer. it is supposed to be understandable by amateur users |
117 | | - # blank value means long answer is unavailable |
118 | | - var $long = ''; |
119 | | - # error message. non-blank value indicates interpretation script error |
120 | | - # either due to incorrect script code, or a script-generated one |
121 | | - var $error = ''; |
122 | | - # 2d array of errors generated for [question][proposal], false if no errors |
123 | | - var $qpErrors = false; |
124 | | - |
125 | | - /** |
126 | | - * @param $init - optional array of properties to be initialized |
127 | | - */ |
128 | | - function __construct( $init = null ) { |
129 | | - $props = array( 'short', 'long', 'error' ); |
130 | | - if ( is_array( $init ) ) { |
131 | | - foreach ( $props as $prop ) { |
132 | | - if ( array_key_exists( $prop, $init ) ) { |
133 | | - $this->{$prop} = $init[$prop]; |
134 | | - } |
135 | | - } |
136 | | - return; |
137 | | - } |
138 | | - } |
139 | | - |
140 | | - /** |
141 | | - * "global" error message |
142 | | - */ |
143 | | - function setError( $msg ) { |
144 | | - $this->error = $msg; |
145 | | - return $this; |
146 | | - } |
147 | | - |
148 | | - /** |
149 | | - * set question / proposal error message (for quizes) |
150 | | - * |
151 | | - * @param $qidx int index of poll's question |
152 | | - * @param $pidx int index of question's proposal |
153 | | - * @param $msg string error message for [question][proposal] pair |
154 | | - */ |
155 | | - function setQPerror( $qidx, $pidx, $msg ) { |
156 | | - if ( !is_array( $this->qpErrors ) ) { |
157 | | - $this->qpErrors = array(); |
158 | | - } |
159 | | - if ( !isset( $this->qpErrors[$qidx] ) ) { |
160 | | - $this->qpErrors[$qidx] = array(); |
161 | | - } |
162 | | - $this->qpErrors[$qidx][$pidx] = $msg; |
163 | | - } |
164 | | - |
165 | | - function isError() { |
166 | | - return $this->error != '' || is_array( $this->qpErrors ); |
167 | | - } |
168 | | - |
169 | | -} /* end of qp_InterpAnswer class */ |
170 | | - |
171 | | -/** |
172 | | - * poll storage and retrieval using DB |
| 112 | +/* poll storage and retrieval using DB |
173 | 113 | * one poll may contain several questions |
174 | 114 | */ |
175 | 115 | class qp_PollStore { |
176 | 116 | |
177 | 117 | static $db = null; |
178 | | - /// DB keys |
| 118 | + // DB keys |
179 | 119 | var $pid = null; |
180 | 120 | var $last_uid = null; |
181 | | - /// common properties |
| 121 | + // common properties |
182 | 122 | var $mArticleId = null; |
183 | | - # unique id of poll, used for addressing, also with 'qp_' prefix as the fragment part of the link |
184 | | - var $mPollId = null; |
185 | | - # order of poll on the page |
186 | | - var $mOrderId = null; |
187 | | - # dependance from other poll address in the following format: "page#otherpollid" |
188 | | - var $dependsOn = null; |
189 | | - # attempts of voting (passing the quiz). number of resubmits |
190 | | - # note: resubmits are counted for syntax-correct answer (the vote is stored), |
191 | | - # yet the answer still might be logically incorrect (quiz is not passed / partially passed) |
192 | | - var $attempts = 0; |
193 | | - |
194 | | - # NS & DBkey of Title object representing interpretation template for Special:Pollresults page |
195 | | - var $interpNS = 0; |
196 | | - var $interpDBkey = null; |
197 | | - # interpretation of user answer |
198 | | - var $interpAnswer; |
199 | | - |
200 | | - # array of QuestionData instances (data from/to DB) |
201 | | - var $Questions = null; |
202 | | - # poll processing state, read with getState() |
203 | | - # |
204 | | - # 'NA' - object just was created |
205 | | - # |
206 | | - # 'incomplete', self::stateIncomplete() |
207 | | - # http post: not every proposals were answered: do not update DB |
208 | | - # http get: this is not the post: do not update DB |
209 | | - # |
210 | | - # 'error', self::stateError() |
211 | | - # http get: invalid question syntax, parse errors will cause submit button disabled |
212 | | - # |
213 | | - # 'complete', self::stateComplete() |
214 | | - # check whether the poll was successfully submitted |
215 | | - # store user vote to the DB (when the poll is fine) |
216 | | - # |
| 123 | + var $mPollId = null; // unique id of poll, used for addressing, also with 'qp_' prefix as the fragment part of the link |
| 124 | + var $mOrderId = null; // order of poll on the page |
| 125 | + var $dependsOn = null; // dependance from other poll address in the following format: "page#otherpollid" |
| 126 | + var $Questions = null; // array of QuestionData instances (data from/to DB) |
217 | 127 | var $mCompletedPostData; |
218 | | - # true, after the poll results have been successfully stored to DB |
219 | 128 | var $voteDone = false; |
220 | 129 | |
221 | 130 | /* $argv[ 'from' ] indicates type of construction, other elements of $argv vary according to 'from' |
— | — | @@ -222,9 +131,8 @@ |
223 | 132 | function __construct( $argv = null ) { |
224 | 133 | global $wgParser; |
225 | 134 | if ( self::$db == null ) { |
226 | | - self::$db = & wfGetDB( DB_MASTER ); |
| 135 | + self::$db = & wfGetDB( DB_SLAVE ); |
227 | 136 | } |
228 | | - $this->interpAnswer = new qp_InterpAnswer(); |
229 | 137 | if ( is_array($argv) && array_key_exists( "from", $argv ) ) { |
230 | 138 | $this->Questions = Array(); |
231 | 139 | $this->mCompletedPostData = 'NA'; |
— | — | @@ -248,18 +156,6 @@ |
249 | 157 | $argv[ 'dependance' ] !== false ) { |
250 | 158 | $this->dependsOn = $argv[ 'dependance' ]; |
251 | 159 | } |
252 | | - if ( array_key_exists( 'interpretation', $argv ) ) { |
253 | | - # (0,'') indicates that interpretation template does not exists |
254 | | - $this->interpNS = 0; |
255 | | - $this->interpDBkey = ''; |
256 | | - if ( $argv['interpretation'] != '' ) { |
257 | | - $interp = Title::newFromText( $argv['interpretation'], NS_QP_INTERPRETATION ); |
258 | | - if ( $interp instanceof Title ) { |
259 | | - $this->interpNS = $interp->getNamespace(); |
260 | | - $this->interpDBkey = $interp->getDBkey(); |
261 | | - } |
262 | | - } |
263 | | - } |
264 | 160 | if ( $is_post ) { |
265 | 161 | $this->setPid(); |
266 | 162 | } else { |
— | — | @@ -270,7 +166,7 @@ |
271 | 167 | if ( array_key_exists( 'pid', $argv ) ) { |
272 | 168 | $pid = intval( $argv[ 'pid' ] ); |
273 | 169 | $res = self::$db->select( 'qp_poll_desc', |
274 | | - array( 'article_id', 'poll_id','order_id', 'dependance', 'interpretation_namespace', 'interpretation_title' ), |
| 170 | + array( 'article_id', 'poll_id','order_id', 'dependance' ), |
275 | 171 | array( 'pid'=>$pid ), |
276 | 172 | __METHOD__ . ":create from pid" ); |
277 | 173 | $row = self::$db->fetchObject( $res ); |
— | — | @@ -280,8 +176,6 @@ |
281 | 177 | $this->mPollId = $row->poll_id; |
282 | 178 | $this->mOrderId = $row->order_id; |
283 | 179 | $this->dependsOn = $row->dependance; |
284 | | - $this->interpNS = $row->interpretation_namespace; |
285 | | - $this->interpDBkey = $row->interpretation_title; |
286 | 180 | } |
287 | 181 | } |
288 | 182 | break; |
— | — | @@ -305,13 +199,13 @@ |
306 | 200 | 'title'=>$pollTitle, |
307 | 201 | 'poll_id'=>$pollId ) ); |
308 | 202 | } else { |
309 | | - return qp_Setup::ERROR_MISSED_TITLE; |
| 203 | + return QP_ERROR_MISSED_TITLE; |
310 | 204 | } |
311 | 205 | } else { |
312 | | - return qp_Setup::ERROR_MISSED_TITLE; |
| 206 | + return QP_ERROR_MISSED_TITLE; |
313 | 207 | } |
314 | 208 | } else { |
315 | | - return qp_Setup::ERROR_INVALID_ADDRESS; |
| 209 | + return QP_ERROR_INVALID_ADDRESS; |
316 | 210 | } |
317 | 211 | } |
318 | 212 | |
— | — | @@ -324,19 +218,11 @@ |
325 | 219 | $res = null; |
326 | 220 | if ( $this->mArticleId !==null && $this->mPollId !== null ) { |
327 | 221 | $res = Title::newFromID( $this->mArticleId ); |
328 | | - $res->setFragment( qp_AbstractPoll::s_getPollTitleFragment( $this->mPollId ) ); |
| 222 | + $res->setFragment( qp_AbstractPoll::getPollTitleFragment( $this->mPollId ) ); |
329 | 223 | } |
330 | 224 | return $res; |
331 | 225 | } |
332 | 226 | |
333 | | - /** |
334 | | - * @return Title instance of interpretation template |
335 | | - */ |
336 | | - function getInterpTitle() { |
337 | | - $title = Title::newFromText( $this->interpDBkey, $this->interpNS ); |
338 | | - return ( $title instanceof Title ) ? $title : null; |
339 | | - } |
340 | | - |
341 | 227 | // warning: will work only after successful loadUserAlreadyVoted() or loadUserVote() |
342 | 228 | function isAlreadyVoted() { |
343 | 229 | if ( is_array( $this->Questions ) && count( $this->Questions > 0 ) ) { |
— | — | @@ -471,7 +357,6 @@ |
472 | 358 | } |
473 | 359 | |
474 | 360 | // load single user vote |
475 | | - // also loads short & long answer interpretation, when available |
476 | 361 | // will be written into self::Questions[]->ProposalCategoryId,ProposalCategoryText,alreadyVoted |
477 | 362 | // may be used only after loadQuestions() |
478 | 363 | // returns true when any of currently defined questions has the votes, false otherwise |
— | — | @@ -667,32 +552,20 @@ |
668 | 553 | } |
669 | 554 | |
670 | 555 | function setLastUser( $username, $store_new_user_to_db = true ) { |
671 | | - if ( $this->pid === null ) { |
672 | | - return; |
673 | | - } |
674 | | - $res = self::$db->select( 'qp_users','uid','name=' . self::$db->addQuotes( $username ), __METHOD__ ); |
675 | | - $row = self::$db->fetchObject( $res ); |
676 | | - if ( $row == false ) { |
677 | | - if ( $store_new_user_to_db ) { |
678 | | - self::$db->insert( 'qp_users', array( 'name'=>$username ), __METHOD__ . ':UpdateUser' ); |
679 | | - $this->last_uid = self::$db->insertId(); |
| 556 | + if ( $this->pid !== null ) { |
| 557 | + $res = self::$db->select( 'qp_users','uid','name=' . self::$db->addQuotes( $username ), __METHOD__ ); |
| 558 | + $row = self::$db->fetchObject( $res ); |
| 559 | + if ( $row==false ) { |
| 560 | + if ( $store_new_user_to_db ) { |
| 561 | + self::$db->insert( 'qp_users', array( 'name'=>$username ), __METHOD__ . ':UpdateUser' ); |
| 562 | + $this->last_uid = self::$db->insertId(); |
| 563 | + } else { |
| 564 | + $this->last_uid = null; |
| 565 | + } |
680 | 566 | } else { |
681 | | - $this->last_uid = null; |
| 567 | + $this->last_uid = $row->uid; |
682 | 568 | } |
683 | | - } else { |
684 | | - $this->last_uid = $row->uid; |
685 | 569 | } |
686 | | - $res = self::$db->select( 'qp_users_polls', |
687 | | - array( 'attempts', 'short_interpretation', 'long_interpretation' ), |
688 | | - array( 'pid'=>$this->pid, 'uid'=>$this->last_uid ), |
689 | | - __METHOD__ . ':load short & long answer interpretation' ); |
690 | | - if ( self::$db->numRows( $res ) != 0 ) { |
691 | | - $row = self::$db->fetchObject( $res ); |
692 | | - $this->attempts = $row->attempts; |
693 | | - $this->interpAnswer = new qp_InterpAnswer(); |
694 | | - $this->interpAnswer->short = $row->short_interpretation; |
695 | | - $this->interpAnswer->long = $row->long_interpretation; |
696 | | - } |
697 | 570 | // todo: change to "insert ... on duplicate key update ..." when last_insert_id() bugs will be fixed |
698 | 571 | } |
699 | 572 | |
— | — | @@ -709,7 +582,7 @@ |
710 | 583 | |
711 | 584 | private function loadPid() { |
712 | 585 | $res = self::$db->select( 'qp_poll_desc', |
713 | | - array( 'pid', 'order_id', 'dependance', 'interpretation_namespace', 'interpretation_title' ), |
| 586 | + array( 'pid', 'order_id', 'dependance' ), |
714 | 587 | 'article_id=' . self::$db->addQuotes( $this->mArticleId ) . ' and ' . |
715 | 588 | 'poll_id=' . self::$db->addQuotes( $this->mPollId ), |
716 | 589 | __METHOD__ ); |
— | — | @@ -723,23 +596,19 @@ |
724 | 597 | if ( $this->dependsOn === null ) { |
725 | 598 | $this->dependsOn = $row->dependance; |
726 | 599 | } |
727 | | - if ( $this->interpDBkey === null ) { |
728 | | - $this->interpNS = $row->interpretation_namespace; |
729 | | - $this->interpDBkey = $row->interpretation_title; |
730 | | - } |
731 | 600 | $this->updatePollAttributes( $row ); |
732 | 601 | } |
733 | 602 | } |
734 | 603 | |
735 | 604 | private function setPid() { |
736 | 605 | $res = self::$db->select( 'qp_poll_desc', |
737 | | - array( 'pid', 'order_id', 'dependance', 'interpretation_namespace', 'interpretation_title' ), |
| 606 | + array( 'pid', 'order_id', 'dependance' ), |
738 | 607 | 'article_id=' . self::$db->addQuotes( $this->mArticleId ) . ' and ' . |
739 | 608 | 'poll_id=' . self::$db->addQuotes( $this->mPollId ) ); |
740 | 609 | $row = self::$db->fetchObject( $res ); |
741 | | - if ( $row == false ) { |
| 610 | + if ( $row==false ) { |
742 | 611 | self::$db->insert( 'qp_poll_desc', |
743 | | - array( 'article_id'=>$this->mArticleId, 'poll_id'=>$this->mPollId, 'order_id'=>$this->mOrderId, 'dependance'=>$this->dependsOn, 'interpretation_namespace'=>$this->interpNS, 'interpretation_title'=>$this->interpDBkey ), |
| 612 | + array( 'article_id'=>$this->mArticleId, 'poll_id'=>$this->mPollId, 'order_id'=>$this->mOrderId, 'dependance'=>$this->dependsOn ), |
744 | 613 | __METHOD__ . ':update poll' ); |
745 | 614 | $this->pid = self::$db->insertId(); |
746 | 615 | } else { |
— | — | @@ -750,13 +619,10 @@ |
751 | 620 | } |
752 | 621 | |
753 | 622 | private function updatePollAttributes( $row ) { |
754 | | - if ( $this->mOrderId != $row->order_id || |
755 | | - $this->dependsOn != $row->dependance || |
756 | | - $this->interpNS != $row->interpretation_namespace || |
757 | | - $this->interpDBkey != $row->interpretation_title ) { |
| 623 | + if ( $this->mOrderId != $row->order_id || $this->dependsOn != $row->dependance ) { |
758 | 624 | $res = self::$db->replace( 'qp_poll_desc', |
759 | 625 | '', |
760 | | - array( 'pid'=>$this->pid, 'article_id'=>$this->mArticleId, 'poll_id'=>$this->mPollId, 'order_id'=>$this->mOrderId, 'dependance'=>$this->dependsOn, 'interpretation_namespace'=>$this->interpNS, 'interpretation_title'=>$this->interpDBkey ), |
| 626 | + array( 'pid'=>$this->pid, 'article_id'=>$this->mArticleId, 'poll_id'=>$this->mPollId, 'order_id'=>$this->mOrderId, 'dependance'=>$this->dependsOn ), |
761 | 627 | __METHOD__ . ':poll attributes update' |
762 | 628 | ); |
763 | 629 | } |
— | — | @@ -808,41 +674,6 @@ |
809 | 675 | } |
810 | 676 | } |
811 | 677 | |
812 | | - /** |
813 | | - * Prepares an array of user answer to the current poll and interprets these |
814 | | - * Stores the result in $this->interpAnswer |
815 | | - */ |
816 | | - private function interpretVote() { |
817 | | - $this->interpAnswer = new qp_InterpAnswer(); |
818 | | - $interpTitle = $this->getInterpTitle(); |
819 | | - if ( $interpTitle === null ) { |
820 | | - return; |
821 | | - } |
822 | | - $interpArticle = new Article( $interpTitle, 0 ); |
823 | | - if ( !$interpArticle->exists() ) { |
824 | | - return; |
825 | | - } |
826 | | - # prepare array of user answers that will be passed to the interpreter |
827 | | - $poll_answer = array(); |
828 | | - foreach ( $this->Questions as $qkey => &$qdata ) { |
829 | | - $questions = array(); |
830 | | - foreach( $qdata->ProposalText as $propkey => &$proposal_text ) { |
831 | | - $proposals = array(); |
832 | | - foreach ( $qdata->Categories as $catkey => &$cat_name ) { |
833 | | - $text_answer = ''; |
834 | | - if ( array_key_exists( $propkey, $qdata->ProposalCategoryId ) && |
835 | | - ( $id_key = array_search( $catkey, $qdata->ProposalCategoryId[ $propkey ] ) ) !== false ) { |
836 | | - $proposals[$catkey] = $qdata->ProposalCategoryText[ $propkey ][ $id_key ]; |
837 | | - } |
838 | | - } |
839 | | - $questions[] = $proposals; |
840 | | - } |
841 | | - $poll_answer[] = $questions; |
842 | | - } |
843 | | - # interpret the poll answer to get interpretation answer |
844 | | - $this->interpAnswer = qp_Interpret::getAnswer( $interpArticle, $poll_answer ); |
845 | | - } |
846 | | - |
847 | 678 | // warning: requires qp_PollStorage::last_uid to be set |
848 | 679 | private function setAnswers() { |
849 | 680 | $insert = Array(); |
— | — | @@ -860,40 +691,32 @@ |
861 | 692 | __METHOD__ . ':delete previous answers of current user to the same poll' |
862 | 693 | ); |
863 | 694 | # vote |
| 695 | + $old_user_abort = ignore_user_abort( true ); |
864 | 696 | if ( count( $insert ) > 0 ) { |
865 | 697 | self::$db->replace( 'qp_question_answers', |
866 | 698 | '', |
867 | 699 | $insert, |
868 | 700 | __METHOD__ ); |
869 | | - $this->interpretVote(); |
870 | | - # update interpretation result and number of syntax-valid resubmit attempts |
871 | | - $qp_users_polls = self::$db->tableName( 'qp_users_polls' ); |
872 | | - $short = self::$db->addQuotes( $this->interpAnswer->short ); |
873 | | - $long = self::$db->addQuotes( $this->interpAnswer->long ); |
874 | | - $stmt = "INSERT INTO {$qp_users_polls} (uid,pid,short_interpretation,long_interpretation)\n VALUES ( " . intval( $this->last_uid ) . ", " . intval( $this->pid ) . ", {$short}, {$long} )\n ON DUPLICATE KEY UPDATE attempts = attempts + 1, short_interpretation = {$short} , long_interpretation = {$long}"; |
875 | | - self::$db->query( $stmt, __METHOD__ ); |
| 701 | + self::$db->replace( 'qp_users_polls', |
| 702 | + '', |
| 703 | + array( 'uid'=>$this->last_uid, 'pid'=>$this->pid ), |
| 704 | + __METHOD__ ); |
876 | 705 | } |
| 706 | + ignore_user_abort( $old_user_abort ); |
877 | 707 | } |
878 | 708 | |
879 | | - /** |
880 | | - * Please call after the poll has been loaded but before it's being submitted |
881 | | - */ |
882 | | - function noMoreAttempts() { |
883 | | - return qp_Setup::$max_submit_attempts > 0 && $this->attempts >= qp_Setup::$max_submit_attempts; |
884 | | - } |
885 | | - |
886 | | - # when the user votes and poll wasn't previousely voted yet, it also creates the poll structures in DB |
| 709 | + # when the user votes and poll wasn't previousely voted yet, it also creates the poll in DB |
887 | 710 | function setUserVote() { |
888 | 711 | if ( $this->pid !==null && |
889 | 712 | $this->last_uid !== null && |
890 | 713 | $this->mCompletedPostData == "complete" && |
891 | 714 | is_array( $this->Questions ) && count( $this->Questions ) > 0 ) { |
892 | | - self::$db->begin(); |
| 715 | + $old_user_abort = ignore_user_abort( true ); |
893 | 716 | $this->setQuestionDesc(); |
894 | 717 | $this->setCategories(); |
895 | 718 | $this->setProposals(); |
896 | 719 | $this->setAnswers(); |
897 | | - self::$db->commit(); |
| 720 | + ignore_user_abort( $old_user_abort ); |
898 | 721 | $this->voteDone = true; |
899 | 722 | } |
900 | 723 | } |
Index: trunk/extensions/QPoll/qp_user.js |
— | — | @@ -27,7 +27,7 @@ |
28 | 28 | * * Add this line at the end of your LocalSettings.php file : |
29 | 29 | * require_once "$IP/extensions/QPoll/qp_user.php"; |
30 | 30 | * |
31 | | - * @version 0.8.0a |
| 31 | + * @version 0.7.0 |
32 | 32 | * @link http://www.mediawiki.org/wiki/Extension:QPoll |
33 | 33 | * @author QuestPC <questpc@rambler.ru> |
34 | 34 | */ |
Index: trunk/extensions/QPoll/README |
— | — | @@ -1,4 +1,4 @@ |
2 | | -MediaWiki extension QPoll, version 0.8.0a |
| 2 | +MediaWiki extension QPoll, version 0.7.0 |
3 | 3 | |
4 | 4 | This extension allows to create polls embedded into the wikipages. Every poll |
5 | 5 | may contain a set of the questions of various types. The polls can be "chained" |
— | — | @@ -10,14 +10,4 @@ |
11 | 11 | proposal text on the user's choice of category in another previously voted |
12 | 12 | poll. |
13 | 13 | |
14 | | -=== v0.8.0a === |
15 | | -Now it is possible to: |
16 | | - |
17 | | -* Create interpretation scripts for psychological tests and quizes |
18 | | -* Generate and store interpretations / marks / scores |
19 | | -* Highlight wrong answers to question proposals |
20 | | -* Log and limit number of answer attempts |
21 | | - |
22 | | -which allows to use the extension as education tool. |
23 | | - |
24 | 14 | See http://mediawiki.org/wiki/Extension:QPoll for further details. |
\ No newline at end of file |
Index: trunk/extensions/QPoll/qp_question.php |
— | — | @@ -0,0 +1,1206 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +if ( !defined( 'MEDIAWIKI' ) ) { |
| 5 | + die( "This file is part of the QPoll extension. It is not a valid entry point.\n" ); |
| 6 | +} |
| 7 | + |
| 8 | +abstract class qp_AbstractQuestion { |
| 9 | + |
| 10 | + var $parser; // an instance of parser from parser tag hook |
| 11 | + var $ppframe; // an instance of PPFrame (parser context) |
| 12 | + var $mState = ''; // current state of question parsing (no error) |
| 13 | + # error message which occured during the question header parsing that will be output later at rendering stage |
| 14 | + var $headerErrorMessage = 'Unknown error'; |
| 15 | + # default type and subtype of the question; should always be properly initialized in $this->parseParameters(); |
| 16 | + var $mType = 'unknown'; |
| 17 | + var $mSubType = ''; // some questions has a subtype, see $this->parseParameters() |
| 18 | + var $mCategories = Array(); |
| 19 | + var $mCategorySpans = Array(); |
| 20 | + var $mCommonQuestion = ''; // GET common question of the poll |
| 21 | + var $mProposalText = Array(); // an array of question proposals |
| 22 | + var $mBeingCorrected = false; // true, when user is posting this question via the poll's form |
| 23 | + var $alreadyVoted = false; // whether the selected user has already voted this question ? |
| 24 | + |
| 25 | + # whether to show the current stats to the users |
| 26 | + # the following values are defined: |
| 27 | + # false - use value of pollShowResults, Array(0) - suppress, Array(1) - percents, Array(2) - bars |
| 28 | + var $showResults = false; |
| 29 | + var $pollShowResults; |
| 30 | + // display layout |
| 31 | + var $proposalsFirst = false; |
| 32 | + var $transposed = false; |
| 33 | + var $spanType = 'colspan'; |
| 34 | + var $categoriesStyle = ''; |
| 35 | + var $proposalTextStyle = 'padding-left: 10px;'; |
| 36 | + var $textInputStyle = ''; |
| 37 | + // statistics |
| 38 | + var $Percents = null; |
| 39 | + var $mRenderTable = Array(); |
| 40 | + |
| 41 | + # Constructor |
| 42 | + # @public |
| 43 | + # @param $parser an instance of parser from parser tag hook |
| 44 | + # @param $frame an instance of PPFrame (parser context) |
| 45 | + # @param $beingCorrected boolean |
| 46 | + # @param $questionId the identifier of the question used to gernerate input names |
| 47 | + # @param $showResults poll's showResults (may be overriden in the question) |
| 48 | + function __construct( &$parser, &$frame, $beingCorrected, $questionId, $showResults ) { |
| 49 | + global $wgRequest; |
| 50 | + $this->parser = &$parser; |
| 51 | + $this->ppframe = &$frame; |
| 52 | + $this->mRequest = &$wgRequest; |
| 53 | + $this->mQuestionId = $questionId; |
| 54 | + $this->mBeingCorrected = $beingCorrected; |
| 55 | + $this->pollShowResults = $showResults; |
| 56 | + $this->mProposalPattern = '`^[^\|\!].*`u'; |
| 57 | + $this->mCategoryPattern = '`^\|(\n|[^\|].*\n)`u'; |
| 58 | + } |
| 59 | + |
| 60 | + /** |
| 61 | + * Mutator of the question state |
| 62 | + * |
| 63 | + * @protected |
| 64 | + * @param $pState - state of the question |
| 65 | + * @param $error_message - optional main_header_parsing error message |
| 66 | + */ |
| 67 | + function setState( $pState, $error_message = null ) { |
| 68 | + if ( $this->mState != 'error' ) { |
| 69 | + $this->mState = $pState; |
| 70 | + } |
| 71 | + if ( $error_message !== null ) { |
| 72 | + # store header error message that cannot be output now, but will be displayed at later stage |
| 73 | + $this->headerErrorMessage = $error_message; |
| 74 | + } |
| 75 | + } |
| 76 | + |
| 77 | + /** |
| 78 | + * Accessor of the question state. |
| 79 | + * |
| 80 | + * @protected |
| 81 | + */ |
| 82 | + function getState() { |
| 83 | + return $this->mState; |
| 84 | + } |
| 85 | + |
| 86 | + function getHeaderError() { |
| 87 | + return '<div class="proposalerror">' . $this->headerErrorMessage . '</div>'; |
| 88 | + } |
| 89 | + |
| 90 | + # outputs question body parser error/warning message |
| 91 | + # @param $msg - text of message |
| 92 | + # @param $state - sets new question state (note that the 'error' state cannot be changed) |
| 93 | + function bodyErrorMessage( $msg, $state ) { |
| 94 | + $prev_state = $this->getState(); |
| 95 | + $this->setState( $state, $msg ); |
| 96 | + # return the message only for the first error occured |
| 97 | + # (this one has to be short, that's why title attribute is being used) |
| 98 | + return ( $prev_state == '' ) ? '<span class="proposalerror" title="' . $msg . '">???</span> ' : ''; |
| 99 | + } |
| 100 | + |
| 101 | + # builds internal & visual representation of question attributes (all attributes but type) |
| 102 | + # @param $attr_str - source text with question attributes |
| 103 | + # @return string : type of the question, empty when not defined |
| 104 | + function parseAttributes( $attr_str ) { |
| 105 | + $paramkeys = array( 't[yi]p[eo]'=>null, 'layout'=>null, 'textwidth'=>null, 'showresults'=>null ); |
| 106 | + foreach( $paramkeys as $key=>&$val ) { |
| 107 | + preg_match( '`' . $key . '?="(.*?)"`u', $attr_str, $val ); |
| 108 | + } |
| 109 | + $type = $paramkeys[ 't[yi]p[eo]' ]; |
| 110 | + $type = isset( $type[1] ) ? trim( $type[1] ) : ''; |
| 111 | + $layout = $paramkeys[ 'layout' ]; |
| 112 | + $textwidth = $paramkeys[ 'textwidth' ]; |
| 113 | + $showresults = $paramkeys[ 'showresults' ]; |
| 114 | + if ( count( $layout ) > 0 ) { |
| 115 | + $this->transposed = strpos( $layout[1], 'transpose' ) !== false; |
| 116 | + $this->proposalsFirst = strpos( $layout[1], 'proposals' ) !== false; |
| 117 | + } |
| 118 | + # setup question layout parameters |
| 119 | + if ( $this->transposed ) { |
| 120 | + $this->spanType = 'rowspan'; |
| 121 | + $this->categoriesStyle = 'text-align:left; vertical-align:middle; '; |
| 122 | + $this->signClass = array( 'first'=>'signt', 'middle'=>'signm', 'last'=>'signb' ); |
| 123 | + $this->proposalTextStyle = 'text-align:center; padding-left: 5px; padding-right: 5px; '; |
| 124 | + $this->proposalTextStyle .= ( $this->proposalsFirst ) ? ' vertical-align: bottom;' : 'vertical-align:top;'; |
| 125 | + } else { |
| 126 | + $this->spanType = 'colspan'; |
| 127 | + $this->categoriesStyle = ''; |
| 128 | + $this->signClass = array( 'first'=>'signl', 'middle'=>'signc', 'last'=>'signr' ); |
| 129 | + $this->proposalTextStyle = 'vertical-align:middle; '; |
| 130 | + $this->proposalTextStyle .= ( $this->proposalsFirst ) ? 'padding-right: 10px;' : 'padding-left: 10px;'; |
| 131 | + } |
| 132 | + if ( count( $textwidth ) > 0 ) { |
| 133 | + $textwidth = intval( $textwidth[1] ); |
| 134 | + if ( $textwidth > 0 ) { |
| 135 | + $this->textInputStyle = 'width:' . $textwidth . 'em;'; |
| 136 | + } |
| 137 | + } |
| 138 | + # setup question's showresults when global showresults != 0 |
| 139 | + if ( qp_Setup::$global_showresults != 0 && count( $showresults ) > 0 ) { |
| 140 | + # use the value from the question |
| 141 | + $this->showResults = qp_AbstractPoll::parse_ShowResults( $showresults[1] ); |
| 142 | + # apply undefined attributes from the poll's showresults definition |
| 143 | + foreach( $this->pollShowResults as $attr => $val ) { |
| 144 | + if ( $attr != 'type' && !isset( $this->showResults[$attr] ) ) { |
| 145 | + $this->showResults[$attr] = $val; |
| 146 | + } |
| 147 | + } |
| 148 | + } else { |
| 149 | + # use the value "inherited" from the poll |
| 150 | + $this->showResults = $this->pollShowResults; |
| 151 | + } |
| 152 | + # initialize cell template for the selected showresults |
| 153 | + # this can be moved to {$this->mType}ParseBody in the future, |
| 154 | + # if needed to setup templates depending on question type |
| 155 | + # right now, cell templates depends only on input type and showresults type |
| 156 | + if ( $this->showResults['type'] != 0 ) { |
| 157 | + $this->{'cellTemplate' . $this->showResults['type']}(); |
| 158 | + } |
| 159 | + return $type; |
| 160 | + } |
| 161 | + |
| 162 | + function addRow( $row, $rowattrs = "", $celltag = "td", $attribute_maps = null ) { |
| 163 | + if ( $this->transposed ) { |
| 164 | + qp_Renderer::addColumn( $this->mRenderTable, $row, $rowattrs, $celltag, $attribute_maps ); |
| 165 | + } else { |
| 166 | + qp_Renderer::addRow( $this->mRenderTable, $row, $rowattrs, $celltag, $attribute_maps ); |
| 167 | + } |
| 168 | + } |
| 169 | + |
| 170 | + # function to draw borders via css in the question table according to category spans (metacategories) |
| 171 | + function renderSpan( &$name, $catDesc, &$text, &$rawClass, &$spanState ) { |
| 172 | + if ( array_key_exists( 'spanId', $catDesc ) ) { |
| 173 | + $spanState->id = $catDesc[ 'spanId' ]; |
| 174 | + $name .= 's' . $spanState->id; |
| 175 | + # there can't be more category spans than the categories |
| 176 | + if ( $this->mCategorySpans[ $spanState->id ]['count'] > count( $this->mCategories ) ) { |
| 177 | + $text = $this->bodyErrorMessage( wfMsg( 'qp_error_too_many_spans' ), 'error' ) . $text; |
| 178 | + $rawClass = 'proposalerror'; |
| 179 | + } |
| 180 | + if ( $spanState->prevId != $spanState->id ) { |
| 181 | + # begin of new span |
| 182 | + $spanState->wasChecked = false; |
| 183 | + $spanState->prevId = $spanState->id; |
| 184 | + $spanState->cellsLeft = $this->mCategorySpans[ $spanState->id ]['count']; |
| 185 | + if ( $spanState->cellsLeft < 2 ) { |
| 186 | + $text = $this->bodyErrorMessage( wfMsg( 'qp_error_too_few_spans' ), 'error' ) . $text; |
| 187 | + QP_Renderer::addClass( $row[ $catId ], 'error' ); |
| 188 | + } |
| 189 | + $spanState->isDrawing = $spanState->cellsLeft != 1 && $spanState->cellsLeft != count( $this->mCategories ); |
| 190 | + # hightlight only spans of count != 1 and count != count(categories) |
| 191 | + if ( $spanState->isDrawing ) { |
| 192 | + $spanState->className = $this->signClass[ 'first' ]; |
| 193 | + } |
| 194 | + } else { |
| 195 | + $spanState->cellsLeft--; |
| 196 | + if ( $spanState->isDrawing ) { |
| 197 | + $spanState->className = ( $spanState->cellsLeft > 1 ) ? $this->signClass[ 'middle' ] : $this->signClass[ 'last' ]; |
| 198 | + } |
| 199 | + } |
| 200 | + } |
| 201 | + } |
| 202 | + |
| 203 | + function getPercents( $proposalId, $catId ) { |
| 204 | + if ( is_array( $this->Percents ) && array_key_exists( $proposalId, $this->Percents ) && |
| 205 | + is_array( $this->Percents[ $proposalId ] ) && array_key_exists( $catId, $this->Percents[ $proposalId ] ) ) { |
| 206 | + return intval( round( 100 * $this->Percents[ $proposalId ][ $catId ] ) ); |
| 207 | + } else { |
| 208 | + return false; |
| 209 | + } |
| 210 | + } |
| 211 | + |
| 212 | +} |
| 213 | + |
| 214 | +/* parsing, checking ans visualisation of Question in statistical display mode (UI input/output) |
| 215 | + */ |
| 216 | +class qp_QuestionStats extends qp_AbstractQuestion { |
| 217 | + |
| 218 | + # Constructor |
| 219 | + # @public |
| 220 | + # @param $parser an instance of parser from parser tag hook |
| 221 | + # @param $frame an instance of PPFrame (parser context) |
| 222 | + # @param $type type of question (taken from DB) |
| 223 | + # @param $questionId the identifier of the question used to gernerate input names |
| 224 | + # @param $showResults poll's showResults (may be overriden in the question) |
| 225 | + function __construct( &$parser, &$frame, $type, $questionId, $showResults ) { |
| 226 | + parent::__construct( $parser, $frame, false, $questionId, $showResults ); |
| 227 | + $this->mType = $type; |
| 228 | + } |
| 229 | + |
| 230 | + # load some question fields from qp_QuestionData given |
| 231 | + # (usually qp_QuestionData is an array property of qp_PollStore instance) |
| 232 | + # @param $qdata - an instance of qp_QuestionData |
| 233 | + function loadAnswer( qp_QuestionData &$qdata ) { |
| 234 | + $this->alreadyVoted = $qdata->alreadyVoted; |
| 235 | + $this->mCommonQuestion = $qdata->CommonQuestion; |
| 236 | + $this->mProposalText = $qdata->ProposalText; |
| 237 | + $this->mCategories = $qdata->Categories; |
| 238 | + $this->mCategorySpans = $qdata->CategorySpans; |
| 239 | + if ( isset( $qdata->Percents ) && is_array( $qdata->Percents ) ) { |
| 240 | + $this->Percents = $qdata->Percents; |
| 241 | + } else { |
| 242 | + # no percents - no stats |
| 243 | + $this->showResults = Array( 'type'=>0 ); |
| 244 | + } |
| 245 | + } |
| 246 | + |
| 247 | + # populates an instance of qp_Question with data from qp_QuestionData |
| 248 | + # input: the object of type qp_Question |
| 249 | + function getQuestionAnswer( qp_PollStore &$pollStore ) { |
| 250 | + if ( $pollStore->pid !== null ) { |
| 251 | + if ( $pollStore->questionExists( $this->mQuestionId ) ) { |
| 252 | + $qdata = $pollStore->Questions[ $this->mQuestionId ]; |
| 253 | + $this->loadAnswer( $qdata ); |
| 254 | + return true; |
| 255 | + } |
| 256 | + } |
| 257 | + return false; |
| 258 | + } |
| 259 | + |
| 260 | + function parseCategories() { |
| 261 | + $row = Array(); |
| 262 | + if ( $this->proposalsFirst ) { |
| 263 | + // add empty <th> at the begin of row to "compensate" proposal text |
| 264 | + $row[] = array( '__tag'=>'td', 0=>"", 'style'=>'border:none;', '__end'=>"\n" ); |
| 265 | + } |
| 266 | + foreach( $this->mCategories as &$cat ) { |
| 267 | + $row[] = $this->parser->recursiveTagParse( $cat['name'], $this->ppframe ); |
| 268 | + } |
| 269 | + if ( !$this->proposalsFirst ) { |
| 270 | + // add empty <th> at the end of row to "compensate" proposal text |
| 271 | + $row[] = array( '__tag'=>'td', 0=>"", 'style'=>'border:none;', '__end'=>"\n" ); |
| 272 | + } |
| 273 | + return $row; |
| 274 | + } |
| 275 | + |
| 276 | + function parseCategorySpans() { |
| 277 | + $row = Array(); |
| 278 | + if ( $this->mType == 'singleChoice' ) { |
| 279 | + # real category spans have sense only for radiobuttons |
| 280 | + if ( $this->proposalsFirst ) { |
| 281 | + // add empty <th> at the begin of row to "compensate" proposal text |
| 282 | + $row[] = array( '__tag'=>'td', 0=>"", 'style'=>'border:none;', '__end'=>"\n" ); |
| 283 | + } |
| 284 | + foreach( $this->mCategorySpans as &$span ) { |
| 285 | + $row[] = array( "count"=>$span['count'], 0=>$this->parser->recursiveTagParse( $span['name'], $this->ppframe ) ); |
| 286 | + } |
| 287 | + if ( !$this->proposalsFirst ) { |
| 288 | + // add empty <th> at the end of row to "compensate" proposal text |
| 289 | + $row[] = array( '__tag'=>'td', 0=>"", 'style'=>'border:none;', '__end'=>"\n" ); |
| 290 | + } |
| 291 | + } |
| 292 | + return $row; |
| 293 | + } |
| 294 | + |
| 295 | + function renderStats() { |
| 296 | + if ( $this->getState() == 'error' ) { |
| 297 | + return $this->getHeaderError(); |
| 298 | + } |
| 299 | + $catRow = $this->parseCategories(); |
| 300 | + if ( count( $this->mCategorySpans ) > 0 ) { |
| 301 | + $spansRow = $this->parseCategorySpans(); |
| 302 | + # if there are multiple spans, "turn on" borders for span and category cells |
| 303 | + if ( count( $this->mCategorySpans ) > 1 ) { |
| 304 | + $this->categoriesStyle .= 'border:1px solid gray;'; |
| 305 | + } |
| 306 | + if ( $this->categoriesStyle != '' ) { |
| 307 | + qp_Renderer::applyAttrsToRow( $spansRow, array( 'style'=>$this->categoriesStyle ) ); |
| 308 | + } |
| 309 | + $this->addRow( $spansRow, array( 'class'=>'spans' ), 'th', array( 'count'=>$this->spanType, 'name'=>0 ) ); |
| 310 | + } |
| 311 | + if ( $this->categoriesStyle != '' ) { |
| 312 | + qp_Renderer::applyAttrsToRow( $catRow, array( 'style'=>$this->categoriesStyle ) ); |
| 313 | + } |
| 314 | + $this->addRow( $catRow, array( 'class'=>'categories' ), 'th', array( 'name'=>0 ) ); |
| 315 | + foreach ( $this->mProposalText as $proposalId => $text ) { |
| 316 | + $row = Array(); |
| 317 | + $rawClass = 'proposal'; |
| 318 | + $spanState = (object) array( 'id'=>0, 'prevId'=>-1, 'wasChecked'=>true, 'isDrawing'=>false, 'cellsLeft'=>0, 'className'=>'sign' ); |
| 319 | + foreach ( $this->mCategories as $catId => $catDesc ) { |
| 320 | + $row[ $catId ] = Array(); |
| 321 | + $spanState->className = 'sign'; |
| 322 | + switch ( $this->mType ) { |
| 323 | + case 'singleChoice' : |
| 324 | + # category spans have sense only with single choice proposals |
| 325 | + $this->renderSpan( $name, $catDesc, $text, $rawClass, $spanState ); |
| 326 | + break; |
| 327 | + } |
| 328 | + QP_Renderer::addClass( $row[ $catId ], $spanState->className ); |
| 329 | + if ( $this->showResults['type'] != 0 ) { |
| 330 | + # there ars some stat in row (not necessarily all cells, because size of question table changes dynamically) |
| 331 | + $row[ $catId ][ 0 ] = $this->{'addShowResults' . $this->showResults['type']}( $proposalId, $catId ); |
| 332 | + } else { |
| 333 | + $row[ $catId ][ 0 ] = ''; |
| 334 | + } |
| 335 | + } |
| 336 | + $text = array( '__tag'=>'td', '__end'=>"\n", 'class'=>'proposaltext', 'style'=>$this->proposalTextStyle, 0=>$this->parser->recursiveTagParse( $text, $this->ppframe ) ); |
| 337 | + if ( $this->proposalsFirst ) { |
| 338 | + # first element is proposaltext |
| 339 | + array_unshift( $row, $text ); |
| 340 | + } else { |
| 341 | + # last element is proposaltext |
| 342 | + $row[] = $text; |
| 343 | + } |
| 344 | + $this->addRow( $row, array( 'class'=>$rawClass ), 'td' ); |
| 345 | + } |
| 346 | + return qp_Renderer::renderHTMLobject( $this->mRenderTable ); |
| 347 | + } |
| 348 | + |
| 349 | + /*** cell templates ***/ |
| 350 | + |
| 351 | + # cell templates for the selected showresults |
| 352 | + var $cellTemplate = Array(); |
| 353 | + var $cellTemplateParam = Array( 'percents'=>'', 'bar1style'=>'', 'bar2style'=>'' ); |
| 354 | + |
| 355 | + # setup a template for showresults=1 |
| 356 | + # showresults=1 cellTemplate has only one variant |
| 357 | + function cellTemplate1() { |
| 358 | + $this->cellTemplate = |
| 359 | + array( |
| 360 | + 0=>array( '__tag'=>'div', 'class'=>'stats', 0=>&$this->cellTemplateParam['percents'] ) |
| 361 | + ); |
| 362 | + if ( isset( $this->showResults['color'] ) ) { |
| 363 | + $this->cellTemplate[0]['style'] = 'color:' . $this->showResults['color'] . ';'; |
| 364 | + } |
| 365 | + if ( isset( $this->showResults['background'] ) ) { |
| 366 | + $this->cellTemplate[0]['style'] .= 'background:' . $this->showResults['background'] . ';'; |
| 367 | + } |
| 368 | + } |
| 369 | + |
| 370 | + # transform input according to showresults=1 (numerical percents) |
| 371 | + # *** warning! parameters should be passed only by value, not by reference *** |
| 372 | + function addShowResults1( $proposalId, $catId ) { |
| 373 | + $this->cellTemplateParam['percents'] = ' '; |
| 374 | + if ( ( $percents = $this->getPercents( $proposalId, $catId ) ) !== false ) { |
| 375 | + # there is a stat in cell |
| 376 | + $this->cellTemplateParam['percents'] = $percents . '%'; |
| 377 | + # template has to be rendered immediately, because $this->cellTemplateParam[] are used as pointers and thus, |
| 378 | + # will always be overwritten |
| 379 | + return QP_Renderer::renderHTMLobject( $this->cellTemplate ); |
| 380 | + } else { |
| 381 | + return ''; |
| 382 | + } |
| 383 | + } |
| 384 | + |
| 385 | + # setup a template for showresults=2 |
| 386 | + function cellTemplate2() { |
| 387 | + # statical styles |
| 388 | + $percentstyle = ''; |
| 389 | + if ( isset( $this->showResults['textcolor'] ) ) { |
| 390 | + $percentstyle = 'color:' . $this->showResults['textcolor'] . ';'; |
| 391 | + } |
| 392 | + if ( isset( $this->showResults['textbackground'] ) ) { |
| 393 | + $percentstyle .= 'background:' . $this->showResults['textbackground'] . ';'; |
| 394 | + } |
| 395 | + # has one available template ('bar') |
| 396 | + $this->cellTemplate = array( |
| 397 | + 'bar'=>array( '__tag'=>'div', 'class'=>'stats2', |
| 398 | + 0=>array( '__tag'=>'div', 'class'=>'bar1', 'style'=>&$this->cellTemplateParam['bar1style'], 0=>' ' ), |
| 399 | + 1=>array( '__tag'=>'div', 'class'=>'bar2', 'style'=>&$this->cellTemplateParam['bar2style'], 0=>' ' ), |
| 400 | + 2=>array( '__tag'=>'div', 'class'=>'bar3', 'style'=>$percentstyle, 0=>&$this->cellTemplateParam['percents'] ) |
| 401 | + ), |
| 402 | + # the following entries are not real templates, but pre-calculated values of css attributes taken from showresults parameter |
| 403 | + 'bar1showres'=>'', |
| 404 | + 'bar2showres'=>'' |
| 405 | + ); |
| 406 | + # dynamical styles, width: in percents will be added during rendering in addShowResults |
| 407 | + if ( isset( $this->showResults['color'] ) ) { |
| 408 | + $this->cellTemplate['bar1showres'] .= 'background:' . $this->showResults['color'] . ';'; |
| 409 | + } |
| 410 | + if ( isset( $this->showResults['background'] ) ) { |
| 411 | + $this->cellTemplate['bar2showres'] .= 'background:' . $this->showResults['background'] . ';'; |
| 412 | + } |
| 413 | + } |
| 414 | + |
| 415 | + # transform input according to showresults=2 (bars) |
| 416 | + # *** warning! parameters should be passed only by value, not by reference *** |
| 417 | + function addShowResults2( $proposalId, $catId ) { |
| 418 | + $this->cellTemplateParam['percents'] = ' '; |
| 419 | + if ( ( $percents = $this->getPercents( $proposalId, $catId ) ) !== false ) { |
| 420 | + # there is a stat in cell |
| 421 | + $this->cellTemplateParam['percents'] = $percents . '%'; |
| 422 | + $this->cellTemplateParam['bar1style'] = 'width:' . $percents . 'px;' . $this->cellTemplate[ 'bar1showres' ]; |
| 423 | + $this->cellTemplateParam['bar2style'] = 'width:' . (100 - $percents) . 'px;' . $this->cellTemplate[ 'bar2showres' ]; |
| 424 | + return qp_Renderer::renderHTMLobject( $this->cellTemplate['bar'] ); |
| 425 | + } else { |
| 426 | + return ''; |
| 427 | + } |
| 428 | + } |
| 429 | + |
| 430 | + /*** end of cell templates ***/ |
| 431 | + |
| 432 | +} |
| 433 | + |
| 434 | +/* parsing, checking ans visualisation of Question in declaration/voting mode (UI input/output) |
| 435 | + */ |
| 436 | +class qp_Question extends qp_AbstractQuestion { |
| 437 | + |
| 438 | + # current user voting taken from POST data (if available) |
| 439 | + var $mProposalCategoryId = Array(); // user true/false answers to the question's proposal |
| 440 | + var $mProposalCategoryText = Array(); // user text answers to the question's proposal |
| 441 | + # previous user voting (if available) taken from DB |
| 442 | + var $mPrevProposalCategoryId = Array(); // user true/false answers to the question's proposal from DB |
| 443 | + var $mPrevProposalCategoryText = Array(); // user text answers to the question's proposal from DB |
| 444 | + |
| 445 | + # load some question fields from qp_QuestionData given |
| 446 | + # (usually qp_QuestionData is an array property of qp_PollStore instance) |
| 447 | + # @param $qdata - an instance of qp_QuestionData |
| 448 | + function loadAnswer( qp_QuestionData &$qdata ) { |
| 449 | + $this->alreadyVoted = $qdata->alreadyVoted; |
| 450 | + $this->mPrevProposalCategoryId = $qdata->ProposalCategoryId; |
| 451 | + $this->mPrevProposalCategoryText = $qdata->ProposalCategoryText; |
| 452 | + if ( isset( $qdata->Percents ) && is_array( $qdata->Percents ) ) { |
| 453 | + $this->Percents = $qdata->Percents; |
| 454 | + } else { |
| 455 | + # no percents - no stats |
| 456 | + $this->showResults = Array( 'type'=>0 ); |
| 457 | + } |
| 458 | + } |
| 459 | + |
| 460 | + # populates an instance of qp_Question with data from qp_QuestionData |
| 461 | + # @param the object of type qp_Question |
| 462 | + function getQuestionAnswer( qp_PollStore &$pollStore ) { |
| 463 | + if ( $pollStore->pid !== null ) { |
| 464 | + if ( $pollStore->questionExists( $this->mQuestionId ) ) { |
| 465 | + $qdata = $pollStore->Questions[ $this->mQuestionId ]; |
| 466 | + if ( $qdata->IsCompatible( $this ) ) { |
| 467 | + $this->loadAnswer( $qdata ); |
| 468 | + return true; |
| 469 | + } |
| 470 | + } |
| 471 | + } |
| 472 | + return false; |
| 473 | + } |
| 474 | + |
| 475 | + # checks, whether user had previousely selected the category of the proposal of this question |
| 476 | + # returns true/false for 'checkbox' and 'radio' inputTypes |
| 477 | + # text string/false for 'text' inputType |
| 478 | + function answerExists( $inputType, $proposalId, $catId ) { |
| 479 | + if ( $this->alreadyVoted ) { |
| 480 | + if ( array_key_exists( $proposalId, $this->mPrevProposalCategoryId ) ) { |
| 481 | + $id_key = array_search( $catId, $this->mPrevProposalCategoryId[ $proposalId ] ); |
| 482 | + if ( $id_key !== false ) { |
| 483 | + if ( $inputType == 'text' ) { |
| 484 | + if ( array_key_exists( $proposalId, $this->mPrevProposalCategoryText ) && |
| 485 | + array_key_exists( $id_key, $this->mPrevProposalCategoryText[ $proposalId ] ) ) { |
| 486 | + $prev_text_answer = $this->mPrevProposalCategoryText[ $proposalId ][ $id_key ]; |
| 487 | + if ( $prev_text_answer != '' ) { |
| 488 | + return $prev_text_answer; |
| 489 | + } |
| 490 | + } |
| 491 | + } else { |
| 492 | + return true; |
| 493 | + } |
| 494 | + } |
| 495 | + } |
| 496 | + } |
| 497 | + return false; |
| 498 | + } |
| 499 | + |
| 500 | + # store the proper (checked) Question |
| 501 | + # creates new qp_QuestionData in the given poll store |
| 502 | + # and places it into the poll store Questions[] collection |
| 503 | + # @param the object of type qp_PollStore |
| 504 | + function store( qp_PollStore &$pollStore ) { |
| 505 | + if ( $pollStore->pid !== null ) { |
| 506 | + $pollStore->Questions[ $this->mQuestionId ] = new qp_QuestionData( array( |
| 507 | + 'from'=>'postdata', |
| 508 | + 'type'=>$this->mType, |
| 509 | + 'common_question'=>$this->mCommonQuestion, |
| 510 | + 'categories'=>$this->mCategories, |
| 511 | + 'category_spans'=>$this->mCategorySpans, |
| 512 | + 'proposal_text'=>$this->mProposalText, |
| 513 | + 'proposal_category_id'=>$this->mProposalCategoryId, |
| 514 | + 'proposal_category_text'=>$this->mProposalCategoryText ) ); |
| 515 | + } |
| 516 | + } |
| 517 | + |
| 518 | + # parses question main header (common question and XML attributes) |
| 519 | + # initializes common question and question type/subtype |
| 520 | + # @param $input the question's header in QPoll syntax |
| 521 | + # |
| 522 | + # internally, the header is split into |
| 523 | + # main header (part inside curly braces) and |
| 524 | + # body header (categories and metacategories defitions) |
| 525 | + # |
| 526 | + function parseMainHeader( $header ) { |
| 527 | + # split common question and question attributes from the header |
| 528 | + @list( $common_question, $attr_str ) = preg_split( '`\n\|([^\|].*)\s*$`u', $header, -1, PREG_SPLIT_DELIM_CAPTURE ); |
| 529 | + if ( !isset( $attr_str ) ) { |
| 530 | + $this->setState( 'error', wfMsg( 'qp_error_in_question_header', qp_Setup::entities( $header ) ) ); |
| 531 | + return; |
| 532 | + } |
| 533 | + $this->mCommonQuestion = trim( $common_question ); |
| 534 | + $type = $this->parseAttributes( $attr_str ); |
| 535 | + # set question type property |
| 536 | + # select the question type and subtype corresponding to the header 'type' attribute |
| 537 | + switch ( $type ) { |
| 538 | + case 'unique()': |
| 539 | + $this->mSubType = 'unique'; |
| 540 | + $this->mType = 'singleChoice'; |
| 541 | + break; |
| 542 | + case '()': |
| 543 | + $this->mType = 'singleChoice'; |
| 544 | + break; |
| 545 | + case '[]': |
| 546 | + $this->mType = 'multipleChoice'; |
| 547 | + break; |
| 548 | + case 'mixed' : |
| 549 | + $this->mType = 'mixedChoice'; |
| 550 | + break; |
| 551 | + default : |
| 552 | + $this->setState( 'error', wfMsg( 'qp_error_invalid_question_type', qp_Setup::entities( $type ) ) ); |
| 553 | + } |
| 554 | + } |
| 555 | + |
| 556 | + # build categories and spans internal & visual representations according to |
| 557 | + # definition of categories and spans (AKA metacategories) in the question body |
| 558 | + # @param $input - the text of question body |
| 559 | + # |
| 560 | + # internally, the header is split into |
| 561 | + # main header (part inside curly braces) and |
| 562 | + # body header (categories and metacategories defitions) |
| 563 | + # |
| 564 | + function parseBodyHeader( $input ) { |
| 565 | + $this->raws = preg_split( '`\n`su', $input, -1, PREG_SPLIT_NO_EMPTY ); |
| 566 | + $categorySpans = false; |
| 567 | + if ( isset( $this->raws[1] ) ) { |
| 568 | + $categorySpans = preg_match( $this->mCategoryPattern, $this->raws[1]."\n", $matches ); |
| 569 | + } |
| 570 | + if ( !$categorySpans && isset( $this->raws[0] ) ) { |
| 571 | + preg_match( $this->mCategoryPattern, $this->raws[0]."\n", $matches ); |
| 572 | + } |
| 573 | + # parse the header - spans and categories |
| 574 | + $catString = isset( $matches[1] ) ? $matches[1] : ''; |
| 575 | + $catRow = $this->parseCategories( $catString ); |
| 576 | + if ( $categorySpans ) { |
| 577 | + $spansRow = $this->parseCategorySpans( $this->raws[0] ); |
| 578 | + # if there are multiple spans, "turn on" borders for span and category cells |
| 579 | + if ( count( $this->mCategorySpans ) > 1 ) { |
| 580 | + $this->categoriesStyle .= 'border:1px solid gray;'; |
| 581 | + } |
| 582 | + if ( $this->categoriesStyle != '' ) { |
| 583 | + qp_Renderer::applyAttrsToRow( $spansRow, array( 'style'=>$this->categoriesStyle ) ); |
| 584 | + } |
| 585 | + $this->addRow( $spansRow, array( 'class'=>'spans' ), 'th', array( 'count'=>$this->spanType, 'name'=>0 ) ); |
| 586 | + } |
| 587 | + # do not render single empty category at all (on user's request) |
| 588 | + if ( count( $this->mCategories ) == 1 && |
| 589 | + $this->mCategories[0]['name'] == ' ' ) { |
| 590 | + return; |
| 591 | + } |
| 592 | + # render category table row |
| 593 | + if ( $this->categoriesStyle != '' ) { |
| 594 | + qp_Renderer::applyAttrsToRow( $catRow, array( 'style'=>$this->categoriesStyle ) ); |
| 595 | + } |
| 596 | + $this->addRow( $catRow, array( 'class'=>'categories' ), 'th', array( 'name'=>0 ) ); |
| 597 | + } |
| 598 | + |
| 599 | + function singleChoiceParseBody() { |
| 600 | + $this->questionParseBody( "radio" ); |
| 601 | + return qp_Renderer::renderHTMLobject( $this->mRenderTable ); |
| 602 | + } |
| 603 | + |
| 604 | + function multipleChoiceParseBody() { |
| 605 | + $this->questionParseBody( "checkbox" ); |
| 606 | + return qp_Renderer::renderHTMLobject( $this->mRenderTable ); |
| 607 | + } |
| 608 | + |
| 609 | + function questionParseBody( $inputType ) { |
| 610 | + # Parameters used in some special cases. |
| 611 | + $proposalId = -1; |
| 612 | + foreach( $this->raws as $raw ) { |
| 613 | + if ( !preg_match( $this->mProposalPattern, $raw, $matches ) ) { |
| 614 | + continue; |
| 615 | + } |
| 616 | + # empty proposal text and row |
| 617 | + $text = null; |
| 618 | + $row = Array(); |
| 619 | + $proposalId++; |
| 620 | + $rawClass = 'proposal'; |
| 621 | + $text = array_pop( $matches ); |
| 622 | + $this->mProposalText[ $proposalId ] = trim( $text ); |
| 623 | + $spanState = (object) array( 'id'=>0, 'prevId'=>-1, 'wasChecked'=>true, 'isDrawing'=>false, 'cellsLeft'=>0, 'className'=>'sign' ); |
| 624 | + foreach ( $this->mCategories as $catId => $catDesc ) { |
| 625 | + $row[ $catId ] = Array(); |
| 626 | + $inp = Array( '__tag'=>'input' ); |
| 627 | + $spanState->className = 'sign'; |
| 628 | + # Determine the input's name and value. |
| 629 | + switch( $this->mType ) { |
| 630 | + case 'multipleChoice': |
| 631 | + $name = 'q' . $this->mQuestionId . 'p' . $proposalId . 's' . $catId; |
| 632 | + $value = 's' . $catId; |
| 633 | + break; |
| 634 | + case 'singleChoice': |
| 635 | + $name = 'q' . $this->mQuestionId . 'p' . $proposalId; |
| 636 | + $value = 's' . $catId; |
| 637 | + # category spans have sense only with single choice proposals |
| 638 | + $this->renderSpan( $name, $catDesc, $text, $rawClass, $spanState ); |
| 639 | + if ( $spanState->cellsLeft <= 1 ) { |
| 640 | + # end of new span |
| 641 | + if ( $this->mBeingCorrected && |
| 642 | + !$spanState->wasChecked && |
| 643 | + $this->mRequest->getVal($name) != $value ) { |
| 644 | + # the span (a part of proposal) was submitted but unanswered |
| 645 | + $text = $this->bodyErrorMessage( wfMsg( 'qp_error_unanswered_span' ), 'NA' ) . $text; |
| 646 | + # highlight current span to indicate an error |
| 647 | + for ( $i = $catId, $j = $this->mCategorySpans[ $spanState->id ]['count']; $j > 0; $i--, $j-- ) { |
| 648 | + QP_Renderer::addClass( $row[$i], 'error' ); |
| 649 | + } |
| 650 | + $rawClass = 'proposalerror'; |
| 651 | + } |
| 652 | + } |
| 653 | + break; |
| 654 | + } |
| 655 | + # Determine if the input had to be checked. |
| 656 | + if ( $this->mBeingCorrected && $this->mRequest->getVal( $name ) == $value ) { |
| 657 | + $inp[ 'checked' ] = 'checked'; |
| 658 | + } |
| 659 | + if ( $this->answerExists( $inputType, $proposalId, $catId ) !== false ) { |
| 660 | + $inp[ 'checked' ] = 'checked'; |
| 661 | + } |
| 662 | + if ( array_key_exists( 'checked', $inp ) ) { |
| 663 | + if ( $this->mSubType == 'unique' ) { |
| 664 | + if ( $this->mBeingCorrected && !$this->isUniqueProposalCategoryId( $proposalId, $catId ) ) { |
| 665 | + $text = $this->bodyErrorMessage( wfMsg( 'qp_error_non_unique_choice' ), 'NA' ) . $text; |
| 666 | + $rawClass = 'proposalerror'; |
| 667 | + unset( $inp[ 'checked' ] ); |
| 668 | + QP_Renderer::addClass( $row[ $catId ], 'error' ); |
| 669 | + } |
| 670 | + } else { |
| 671 | + $spanState->wasChecked = true; |
| 672 | + } |
| 673 | + } |
| 674 | + if ( array_key_exists( 'checked', $inp ) ) { |
| 675 | + # add category to the list of user answers for current proposal (row) |
| 676 | + $this->mProposalCategoryId[ $proposalId ][] = $catId; |
| 677 | + $this->mProposalCategoryText[ $proposalId ][] = ''; |
| 678 | + } |
| 679 | + QP_Renderer::addClass( $row[ $catId ], $spanState->className ); |
| 680 | + if ( $this->mSubType == 'unique' ) { |
| 681 | + # unique (question,category,proposal) "coordinate" for javascript |
| 682 | + $inp[ 'id' ] = 'uq' . $this->mQuestionId . 'c' . $catId . 'p' . $proposalId; |
| 683 | + # If type='unique()' question has more proposals than categories, such question is impossible to complete |
| 684 | + if ( count( $this->mProposalText ) > count( $this->mCategories ) ) { |
| 685 | + # if there was no previous errors, hightlight the whole row |
| 686 | + if ( $this->getState() == '' ) { |
| 687 | + foreach( $row as &$cell ) { |
| 688 | + QP_Renderer::addClass( $cell, 'error' ); |
| 689 | + } |
| 690 | + } |
| 691 | + $text = $this->bodyErrorMessage( wfMsg( 'qp_error_unique' ), 'error' ) . $text; |
| 692 | + $rawClass = 'proposalerror'; |
| 693 | + } |
| 694 | + } |
| 695 | + $inp[ 'class' ] = 'check'; |
| 696 | + $inp[ 'type' ] = $inputType; |
| 697 | + $inp[ 'name' ] = $name; |
| 698 | + $inp[ 'value' ] = $value; |
| 699 | + if ( $this->showResults['type'] != 0 ) { |
| 700 | + # there ars some stat in row (not necessarily all cells, because size of question table changes dynamically) |
| 701 | + $row[ $catId ][ 0 ] = $this->{'addShowResults' . $this->showResults['type']}( $inp, $proposalId, $catId ); |
| 702 | + } else { |
| 703 | + $row[ $catId ][ 0 ] = $inp; |
| 704 | + } |
| 705 | + } |
| 706 | + # If the proposal text is empty, the question has a syntax error. |
| 707 | + if( trim( $text ) == '' ) { |
| 708 | + $text = $this->bodyErrorMessage( wfMsg( 'qp_error_proposal_text_empty' ), 'error' ); |
| 709 | + foreach( $row as &$cell ) { |
| 710 | + QP_Renderer::addClass( $cell, 'error' ); |
| 711 | + } |
| 712 | + $rawClass = 'proposalerror'; |
| 713 | + } |
| 714 | + # If the proposal was submitted but unanswered |
| 715 | + if ( $this->mBeingCorrected && !array_key_exists( $proposalId, $this->mProposalCategoryId ) ) { |
| 716 | + # if there was no previous errors, hightlight the whole row |
| 717 | + if ( $this->getState() == '' ) { |
| 718 | + foreach( $row as &$cell ) { |
| 719 | + QP_Renderer::addClass( $cell, 'error' ); |
| 720 | + } |
| 721 | + } |
| 722 | + $text = $this->bodyErrorMessage( wfMsg( 'qp_error_no_answer' ), 'NA' ) . $text; |
| 723 | + $rawClass = 'proposalerror'; |
| 724 | + } |
| 725 | + if ( $text !== null ) { |
| 726 | + $text = array( '__tag'=>'td', '__end'=>"\n", 'class'=>'proposaltext', 'style'=>$this->proposalTextStyle, 0=>$this->parser->recursiveTagParse( $text, $this->ppframe ) ); |
| 727 | + if ( $this->proposalsFirst ) { |
| 728 | + # first element is proposaltext |
| 729 | + array_unshift( $row, $text ); |
| 730 | + } else { |
| 731 | + # last element is proposaltext |
| 732 | + $row[] = $text; |
| 733 | + } |
| 734 | + $this->addRow( $row, array( 'class'=>$rawClass ), 'td' ); |
| 735 | + } |
| 736 | + } |
| 737 | + } |
| 738 | + |
| 739 | + function mixedChoiceParseBody() { |
| 740 | + # Parameters used in some special cases. |
| 741 | + $this->mProposalPattern = '`^'; |
| 742 | + foreach ( $this->mCategories as $catDesc ) { |
| 743 | + $this->mProposalPattern .= '(\[\]|\(\)|<>)'; |
| 744 | + } |
| 745 | + $this->mProposalPattern .= '(.*)`u'; |
| 746 | + $proposalId = -1; |
| 747 | + foreach( $this->raws as $raw ) { |
| 748 | + # empty proposal text and row |
| 749 | + $text = null; |
| 750 | + $row = Array(); |
| 751 | + if ( preg_match( $this->mProposalPattern, $raw, $matches ) ) { |
| 752 | + $text = array_pop( $matches ); // current proposal text |
| 753 | + array_shift( $matches ); // remove "at whole" match |
| 754 | + $last_matches = $matches; |
| 755 | + } else { |
| 756 | + if ( $proposalId >= 0 ) { |
| 757 | + # shortened syntax: use the pattern from the last row where it's been defined |
| 758 | + $text = $raw; |
| 759 | + $matches = $last_matches; |
| 760 | + } |
| 761 | + } |
| 762 | + if ( $text === null ) { |
| 763 | + continue; |
| 764 | + } |
| 765 | + $proposalId++; |
| 766 | + $rawClass = 'proposal'; |
| 767 | + $this->mProposalText[ $proposalId ] = trim( $text ); |
| 768 | + # Determine a type ID, according to the questionType and the number of signes. |
| 769 | + foreach ( $this->mCategories as $catId => $catDesc ) { |
| 770 | + $typeId = $matches[ $catId ]; |
| 771 | + $row[ $catId ] = Array(); |
| 772 | + $inp = Array( '__tag'=>'input' ); |
| 773 | + # Determine the input's name and value. |
| 774 | + switch ( $typeId ) { |
| 775 | + case '<>': |
| 776 | + $name = 'q' . $this->mQuestionId . 'p' . $proposalId . 's' . $catId; |
| 777 | + $value = ''; |
| 778 | + $inputType = 'text'; |
| 779 | + break; |
| 780 | + case '[]': |
| 781 | + $name = 'q' . $this->mQuestionId . 'p' . $proposalId . 's' . $catId; |
| 782 | + $value = 's' . $catId; |
| 783 | + $inputType = 'checkbox'; |
| 784 | + break; |
| 785 | + case '()': |
| 786 | + $name = 'q' . $this->mQuestionId . 'p' . $proposalId . 's' . $catId; |
| 787 | + $value = 's' . $catId; |
| 788 | + $inputType = 'radio'; |
| 789 | + break; |
| 790 | + } |
| 791 | + # Determine if the input has to be checked. |
| 792 | + $input_checked = false; |
| 793 | + $text_answer = ''; |
| 794 | + if ( $this->mBeingCorrected && $this->mRequest->getVal( $name ) !== null ) { |
| 795 | + if ( $inputType == 'text' ) { |
| 796 | + $text_answer = trim( $this->mRequest->getText( $name ) ); |
| 797 | + if ( strlen( $text_answer ) > QP_MAX_TEXT_ANSWER_LENGTH ) { |
| 798 | + $text_answer = substr( $text_answer, 0, QP_MAX_TEXT_ANSWER_LENGTH ); |
| 799 | + } |
| 800 | + if ( $text_answer != '' ) { |
| 801 | + $input_checked = true; |
| 802 | + } |
| 803 | + } else { |
| 804 | + $inp[ 'checked' ] = 'checked'; |
| 805 | + $input_checked = true; |
| 806 | + } |
| 807 | + } |
| 808 | + if ( ( $prev_text_answer = $this->answerExists( $inputType, $proposalId, $catId ) ) !== false ) { |
| 809 | + $input_checked = true; |
| 810 | + if ( $inputType == 'text' ) { |
| 811 | + $text_answer = $prev_text_answer; |
| 812 | + } else { |
| 813 | + $inp[ 'checked' ] = 'checked'; |
| 814 | + } |
| 815 | + } |
| 816 | + if ( $input_checked === true ) { |
| 817 | + # add category to the list of user answers for current proposal (row) |
| 818 | + $this->mProposalCategoryId[ $proposalId ][] = $catId; |
| 819 | + $this->mProposalCategoryText[ $proposalId ][] = $text_answer; |
| 820 | + } |
| 821 | + $row[ $catId ][ 'class' ] = 'sign'; |
| 822 | + # unique (question,proposal,category) "coordinate" for javascript |
| 823 | + $inp[ 'id' ] = 'mx' . $this->mQuestionId . 'p' . $proposalId . 'c' . $catId; |
| 824 | + $inp[ 'class' ] = 'check'; |
| 825 | + $inp[ 'type' ] = $inputType; |
| 826 | + $inp[ 'name' ] = $name; |
| 827 | + if ( $inputType == 'text' ) { |
| 828 | + $inp[ 'value' ] = qp_Setup::specialchars( $text_answer ); |
| 829 | + if ( $this->textInputStyle != '' ) { |
| 830 | + $inp[ 'style' ] = $this->textInputStyle; |
| 831 | + } |
| 832 | + } else { |
| 833 | + $inp[ 'value' ] = $value; |
| 834 | + } |
| 835 | + if ( $this->showResults['type'] != 0 ) { |
| 836 | + # there ars some stat in row (not necessarily all cells, because size of question table changes dynamically) |
| 837 | + $row[ $catId ][ 0 ] = $this->{'addShowResults' . $this->showResults['type']}( $inp, $proposalId, $catId ); |
| 838 | + } else { |
| 839 | + $row[ $catId ][ 0 ] = $inp; |
| 840 | + } |
| 841 | + } |
| 842 | + try { |
| 843 | + # if there is only one category defined and it is not a textfield, |
| 844 | + # the question has a syntax error |
| 845 | + if ( count( $matches ) < 2 && $matches[0] != '<>' ) { |
| 846 | + $text = $this->bodyErrorMessage( wfMsg( 'qp_error_too_few_categories' ), 'error' ); |
| 847 | + throw new Exception( 'qp_error' ); |
| 848 | + } |
| 849 | + # If the proposal text is empty, the question has a syntax error. |
| 850 | + if( trim( $text ) == '' ) { |
| 851 | + $text = $this->bodyErrorMessage( wfMsg( "qp_error_proposal_text_empty" ), "error" ); |
| 852 | + throw new Exception( 'qp_error' ); |
| 853 | + } |
| 854 | + # If the proposal was submitted but unanswered |
| 855 | + if ( $this->mBeingCorrected && !array_key_exists( $proposalId, $this->mProposalCategoryId ) ) { |
| 856 | + $prev_state = $this->getState(); |
| 857 | + $text = $this->bodyErrorMessage( wfMsg( 'qp_error_no_answer' ), 'NA' ) . $text; |
| 858 | + # if there was no previous errors, hightlight the whole row |
| 859 | + if ( $prev_state == '' ) { |
| 860 | + throw new Exception( 'qp_error' ); |
| 861 | + } |
| 862 | + } |
| 863 | + } catch( Exception $e ) { |
| 864 | + if ( $e->getMessage() == 'qp_error' ) { |
| 865 | + foreach( $row as &$cell ) { |
| 866 | + QP_Renderer::addClass( $cell, 'error' ); |
| 867 | + } |
| 868 | + $rawClass = 'proposalerror'; |
| 869 | + } else { |
| 870 | + throw new MWException( $e->getMessage() ); |
| 871 | + } |
| 872 | + } |
| 873 | + $text = array( '__tag'=>'td', '__end'=>"\n", 'class'=>'proposaltext', 'style'=>$this->proposalTextStyle, 0=>$this->parser->recursiveTagParse( $text, $this->ppframe ) ); |
| 874 | + if ( $this->proposalsFirst ) { |
| 875 | + # first element is proposaltext |
| 876 | + array_unshift( $row, $text ); |
| 877 | + } else { |
| 878 | + # last element is proposaltext |
| 879 | + $row[] = $text; |
| 880 | + } |
| 881 | + $this->addRow( $row, array( 'class'=>$rawClass ), 'td' ); |
| 882 | + } |
| 883 | + return qp_Renderer::renderHTMLobject( $this->mRenderTable ); |
| 884 | + } |
| 885 | + |
| 886 | + /** |
| 887 | + * build internal & visual representation of question categories |
| 888 | + * |
| 889 | + * @param $input the raw source of categories |
| 890 | + */ |
| 891 | + function parseCategories( $input ) { |
| 892 | + $row = Array(); |
| 893 | + if ( $this->proposalsFirst ) { |
| 894 | + // add empty <th> at the begin of row to "compensate" proposal text |
| 895 | + $row[] = array( '__tag'=>'td', 0=>"", 'style'=>'border:none;', '__end'=>"\n" ); |
| 896 | + } |
| 897 | + # build "raw" categories array |
| 898 | + # split tokens |
| 899 | + $cat_split = preg_split( '`({{|}}|\[\[|\]\]|\|)`u', $input, -1, PREG_SPLIT_DELIM_CAPTURE ); |
| 900 | + $matching_braces = Array(); |
| 901 | + $curr_elem = ''; |
| 902 | + $categories = Array(); |
| 903 | + foreach( $cat_split as $part ) { |
| 904 | + switch ($part) { |
| 905 | + case '|' : |
| 906 | + if ( count( $matching_braces ) == 0 ) { |
| 907 | + # delimeters are working only when braces are completely closed |
| 908 | + $categories[] = $curr_elem; |
| 909 | + $curr_elem = ''; |
| 910 | + $part = ''; |
| 911 | + } |
| 912 | + break; |
| 913 | + case '[[' : |
| 914 | + case '{{' : |
| 915 | + if ( $part == '[[' ) { |
| 916 | + $last_brace = ']]'; |
| 917 | + } else { |
| 918 | + $last_brace = '}}'; |
| 919 | + } |
| 920 | + array_push( $matching_braces, $last_brace ); |
| 921 | + break; |
| 922 | + case ']]' : |
| 923 | + case '}}' : |
| 924 | + if ( count( $matching_braces ) > 0 ) { |
| 925 | + $last_brace = array_pop( $matching_braces ); |
| 926 | + if ( $last_brace != $part ) { |
| 927 | + array_push( $matching_braces, $last_brace ); |
| 928 | + } |
| 929 | + } |
| 930 | + break; |
| 931 | + } |
| 932 | + $curr_elem .= $part; |
| 933 | + } |
| 934 | + if ( $curr_elem != '' ) { |
| 935 | + $categories[] = $curr_elem; |
| 936 | + } |
| 937 | + $categories = array_map( 'trim', $categories ); |
| 938 | + # analyze previousely build "raw" categories array |
| 939 | + # Less than two categories is a syntax error. |
| 940 | + if ( $this->mType != 'mixedChoice' && count( $categories ) < 2 ) { |
| 941 | + $categories[0] .= $this->bodyErrorMessage( wfMsg( 'qp_error_too_few_categories' ), 'error' ); |
| 942 | + } |
| 943 | + foreach( $categories as $catkey => $category ) { |
| 944 | + # If a category name is empty, the question has a syntax error. |
| 945 | + if( $category == '' ) { |
| 946 | + $category = $this->bodyErrorMessage( wfMsg( 'qp_error_category_name_empty' ), 'error' ); |
| 947 | + } |
| 948 | + $this->mCategories[ $catkey ]["name"] = $category; |
| 949 | + $row[] = $this->parser->recursiveTagParse( $category, $this->ppframe ); |
| 950 | + } |
| 951 | + |
| 952 | + # cut unused categories rows which are presented in DB but were removed from article |
| 953 | + $this->mCategories = array_slice( $this->mCategories, 0, count( $categories ) ); |
| 954 | + if ( !$this->proposalsFirst ) { |
| 955 | + // add empty <th> at the end of row to "compensate" proposal text |
| 956 | + $row[] = array( '__tag'=>'td', 0=>"", 'style'=>'border:none;', '__end'=>"\n" ); |
| 957 | + } |
| 958 | + return $row; |
| 959 | + } |
| 960 | + |
| 961 | + /** |
| 962 | + * build internal & visual representation of question category spans |
| 963 | + * ( also known as metacategories or "category groups" ) |
| 964 | + * |
| 965 | + * @param $input the raw source of category spans |
| 966 | + */ |
| 967 | + # warning: parseCategorySpans() should be called after parseCategories() |
| 968 | + function parseCategorySpans( $input ) { |
| 969 | + $row = Array(); |
| 970 | + if ( $this->mType == "singleChoice" ) { |
| 971 | + # real category spans have sense only for radiobuttons |
| 972 | + # build "raw" spans array |
| 973 | + # split tokens |
| 974 | + $span_split = preg_split( '`({{|}}|\[\[|\]\]|\||\!)`u', $input, -1, PREG_SPLIT_DELIM_CAPTURE ); |
| 975 | + $matching_braces = Array(); |
| 976 | + $curr_elem = null; |
| 977 | + $spans = Array(); |
| 978 | + if ( isset( $span_split[0] ) && $span_split[0] == '' ) { |
| 979 | + array_shift( $span_split ); |
| 980 | + if ( isset( $span_split[0] ) && in_array( $span_split[0], array( '!', '|' ) ) ) { |
| 981 | + $delim = $span_split[0]; |
| 982 | + foreach( $span_split as $part ) { |
| 983 | + if ( $part == $delim ) { |
| 984 | + if ( count( $matching_braces ) == 0 ) { |
| 985 | + # delimeters are working only when braces are completely closed |
| 986 | + $spans[0][] = $part; |
| 987 | + if ( $curr_elem !== null ) { |
| 988 | + $spans[1][] = $curr_elem; |
| 989 | + } |
| 990 | + $curr_elem = ''; |
| 991 | + $part = ''; |
| 992 | + } |
| 993 | + } else { |
| 994 | + switch ( $part ) { |
| 995 | + case '[[' : |
| 996 | + case '{{' : |
| 997 | + if ( $part == '[[' ) { |
| 998 | + $last_brace = ']]'; |
| 999 | + } else { |
| 1000 | + $last_brace = '}}'; |
| 1001 | + } |
| 1002 | + array_push ( $matching_braces, $last_brace ); |
| 1003 | + break; |
| 1004 | + case ']]' : |
| 1005 | + case '}}' : |
| 1006 | + if ( count( $matching_braces ) > 0 ) { |
| 1007 | + $last_brace = array_pop( $matching_braces ); |
| 1008 | + if ( $last_brace != $part ) { |
| 1009 | + array_push( $matching_braces, $last_brace ); |
| 1010 | + } |
| 1011 | + } |
| 1012 | + break; |
| 1013 | + } |
| 1014 | + } |
| 1015 | + $curr_elem .= $part; |
| 1016 | + } |
| 1017 | + if ( $curr_elem !== null ) { |
| 1018 | + $spans[1][] = $curr_elem; |
| 1019 | + } else { |
| 1020 | + $curr_elem = ''; |
| 1021 | + } |
| 1022 | + } |
| 1023 | + } |
| 1024 | + # analyze previousely build "raw" spans array |
| 1025 | + # Less than one span is a syntax error. |
| 1026 | + if(!array_key_exists(0, $spans)) { |
| 1027 | + return $this->bodyErrorMessage( wfMsg( "qp_error_too_few_spans" ), "error" ); |
| 1028 | + } |
| 1029 | + # fill undefined spans with the last span value |
| 1030 | + $SpanCategDelta = count( $this->mCategories ) - count( $spans[0] ); |
| 1031 | + # temporary var $diff used to avoid warning in E_STRICT mode |
| 1032 | + $diff = array_diff( array_keys( $spans[1] ), array_keys( $spans[1], "", true ) ); |
| 1033 | + $lastDefinedSpanKey = array_pop( $diff ); |
| 1034 | + unset( $diff ); |
| 1035 | + if ($lastDefinedSpanKey !== null) { |
| 1036 | + if ( $SpanCategDelta > 0 ) { |
| 1037 | + # increase the length of last defined span value to match total lenth of categories |
| 1038 | + $lastSpanType = $spans[0][$lastDefinedSpanKey]; |
| 1039 | + $spans[0] = array_merge( array_slice( $spans[0], 0, $lastDefinedSpanKey ), |
| 1040 | + array_fill( 0, $SpanCategDelta, $lastSpanType ), |
| 1041 | + array_slice( $spans[0], $lastDefinedSpanKey ) ); |
| 1042 | + $spans[1] = array_merge( array_slice( $spans[1], 0, $lastDefinedSpanKey ), |
| 1043 | + array_fill( 0, $SpanCategDelta, "" ), |
| 1044 | + array_slice( $spans[1], $lastDefinedSpanKey ) ); |
| 1045 | + } elseif ( $SpanCategDelta < 0 ) { |
| 1046 | + # cut unused but defined extra spans |
| 1047 | + $spans[0] = array_slice( $spans[0], count( $this->mCategories ), -$SpanCategDelta ); |
| 1048 | + $spans[1] = array_slice( $spans[1], count( $this->mCategories ), -$SpanCategDelta ); |
| 1049 | + } |
| 1050 | + } else { |
| 1051 | + # no valid category spans are defined |
| 1052 | + return $this->bodyErrorMessage( wfMsg( 'qp_error_too_few_spans' ), 'error' ); |
| 1053 | + } |
| 1054 | + # populate mCategorySpans and row |
| 1055 | + if ( $this->proposalsFirst ) { |
| 1056 | + // add empty <th> at the begin of row to "compensate" proposal text |
| 1057 | + $row[] = array( '__tag'=>'td', 0=>"", 'style'=>'border:none;', '__end'=>"\n" ); |
| 1058 | + } |
| 1059 | + $colspanBase = ( $lastDefinedSpanKey == 0 ) ? 1 : 0; |
| 1060 | + $colspan = 1; |
| 1061 | + $categorySpanId = 0; |
| 1062 | + foreach($spans[0] as $spanKey => $spanType) { |
| 1063 | + $spanCategory = trim( $spans[1][$spanKey] ); |
| 1064 | + if ( $spanCategory=="" ) { |
| 1065 | + $colspan++; |
| 1066 | + } else { |
| 1067 | + $row[] = array( "count"=>$colspan + $colspanBase, 0=>$this->parser->recursiveTagParse( $spanCategory, $this->ppframe ) ); |
| 1068 | + if ( $spanType == "|") { // "!" is a comment header, not a real category span |
| 1069 | + $this->mCategorySpans[ $categorySpanId ]['name'] = $spanCategory; |
| 1070 | + $this->mCategorySpans[ $categorySpanId ]['count'] = $colspan; |
| 1071 | + for ( $i = $spanKey; |
| 1072 | + $i >=0 && array_key_exists( $i, $this->mCategories ) && !array_key_exists( 'spanId', $this->mCategories[ $i ] ); |
| 1073 | + $i-- ) { |
| 1074 | + $this->mCategories[$i]['spanId'] = $categorySpanId; |
| 1075 | + } |
| 1076 | + $categorySpanId++; |
| 1077 | + } |
| 1078 | + $colspan = 1; |
| 1079 | + } |
| 1080 | + } |
| 1081 | + if ( !$this->proposalsFirst ) { |
| 1082 | + // add empty <th> at the end of row to "compensate" proposal text |
| 1083 | + $row[] = array( '__tag'=>'td', 0=>"", 'style'=>'border:none;', '__end'=>"\n" ); |
| 1084 | + } |
| 1085 | + } |
| 1086 | + return $row; |
| 1087 | + } |
| 1088 | + |
| 1089 | + function isUniqueProposalCategoryId( $proposalId, $catId ) { |
| 1090 | + foreach( $this->mProposalCategoryId as $proposalCategoryId ) { |
| 1091 | + if ( in_array( $catId, $proposalCategoryId ) ) { |
| 1092 | + return false; |
| 1093 | + } |
| 1094 | + } |
| 1095 | + return true; |
| 1096 | + } |
| 1097 | + |
| 1098 | + /*** cell templates ***/ |
| 1099 | + |
| 1100 | + # cell templates for the selected showresults |
| 1101 | + var $cellTemplate = Array(); |
| 1102 | + var $cellTemplateParam = Array( 'inp'=>'', 'percents'=>'', 'bar1style'=>'', 'bar2style'=>'' ); |
| 1103 | + |
| 1104 | + # setup a template for showresults=1 |
| 1105 | + # showresults=1 cellTemplate has only one variant |
| 1106 | + function cellTemplate1() { |
| 1107 | + $this->cellTemplate = |
| 1108 | + array( |
| 1109 | + 0=>array( '__tag'=>'div', 0=>&$this->cellTemplateParam['inp'] ), |
| 1110 | + 1=>array( '__tag'=>'div', 'class'=>'stats', 0=>&$this->cellTemplateParam['percents'] ) |
| 1111 | + ); |
| 1112 | + if ( isset( $this->showResults['color'] ) ) { |
| 1113 | + $this->cellTemplate[1]['style'] = 'color:' . $this->showResults['color'] . ';'; |
| 1114 | + } |
| 1115 | + if ( isset( $this->showResults['background'] ) ) { |
| 1116 | + $this->cellTemplate[1]['style'] .= 'background:' . $this->showResults['background'] . ';'; |
| 1117 | + } |
| 1118 | + } |
| 1119 | + |
| 1120 | + # transform input according to showresults=1 (numerical percents) |
| 1121 | + # *** warning! parameters should be passed only by value, not by reference *** |
| 1122 | + function addShowResults1( $inp, $proposalId, $catId ) { |
| 1123 | + $this->cellTemplateParam['inp'] = $inp; |
| 1124 | + $this->cellTemplateParam['percents'] = ' '; |
| 1125 | + if ( ( $percents = $this->getPercents( $proposalId, $catId ) ) !== false ) { |
| 1126 | + # there is a stat in cell |
| 1127 | + $this->cellTemplateParam['percents'] = $percents . '%'; |
| 1128 | + # template has to be rendered immediately, because $this->cellTemplateParam[] are used as pointers and thus, |
| 1129 | + # will always be overwritten |
| 1130 | + return QP_Renderer::renderHTMLobject( $this->cellTemplate ); |
| 1131 | + } else { |
| 1132 | + return $inp; |
| 1133 | + } |
| 1134 | + } |
| 1135 | + |
| 1136 | + # setup a template for showresults=2 |
| 1137 | + function cellTemplate2() { |
| 1138 | + # statical styles |
| 1139 | + $percentstyle = ''; |
| 1140 | + if ( isset( $this->showResults['textcolor'] ) ) { |
| 1141 | + $percentstyle = 'color:' . $this->showResults['textcolor'] . ';'; |
| 1142 | + } |
| 1143 | + if ( isset( $this->showResults['textbackground'] ) ) { |
| 1144 | + $percentstyle .= 'background:' . $this->showResults['textbackground'] . ';'; |
| 1145 | + } |
| 1146 | + # html arrays used in templates below |
| 1147 | + $bar = array( '__tag'=>'div', 'class'=>'stats1', |
| 1148 | + 0=>array( '__tag'=>'div', 'class'=>'bar0', 0=>&$this->cellTemplateParam['inp'] ), |
| 1149 | + 1=>array( '__tag'=>'div', 'class'=>'bar1', 'style'=>&$this->cellTemplateParam['bar1style'], 0=>' ' ), |
| 1150 | + 2=>array( '__tag'=>'div', 'class'=>'bar2', 'style'=>&$this->cellTemplateParam['bar2style'], 0=>' ' ), |
| 1151 | + 3=>array( '__tag'=>'div', 'class'=>'bar0', 'style'=>$percentstyle, 0=>&$this->cellTemplateParam['percents'] ) |
| 1152 | + ); |
| 1153 | + $bar2 = array( '__tag'=>'div', 'class'=>'stats1', |
| 1154 | + 0=>array( '__tag'=>'div', 'class'=>'bar0', 0=>' ' ), |
| 1155 | + 1=>&$bar[1], |
| 1156 | + 2=>&$bar[2], |
| 1157 | + 3=>&$bar[3] |
| 1158 | + ); |
| 1159 | + # has two available templates ('bar','textinput') |
| 1160 | + $this->cellTemplate = array( |
| 1161 | + 'bar'=>$bar, |
| 1162 | + 'textinput'=>array( '__tag'=>'table', 'class'=>'stats', |
| 1163 | + 0=>array( '__tag'=>'tr', |
| 1164 | + 0=>array( '__tag'=>'td', 0=>&$this->cellTemplateParam['inp'] ), |
| 1165 | + ), |
| 1166 | + 1=>array( '__tag'=>'tr', |
| 1167 | + 0=>array( '__tag'=>'td', |
| 1168 | + 0=>$bar2 |
| 1169 | + ) |
| 1170 | + ) |
| 1171 | + ), |
| 1172 | + # the following entries are not real templates, but pre-calculated values of css attributes taken from showresults parameter |
| 1173 | + 'bar1showres'=>'', |
| 1174 | + 'bar2showres'=>'' |
| 1175 | + ); |
| 1176 | + # dynamical styles, width: in percents will be added during rendering in addShowResults |
| 1177 | + if ( isset( $this->showResults['color'] ) ) { |
| 1178 | + $this->cellTemplate['bar1showres'] .= 'background:' . $this->showResults['color'] . ';'; |
| 1179 | + } |
| 1180 | + if ( isset( $this->showResults['background'] ) ) { |
| 1181 | + $this->cellTemplate['bar2showres'] .= 'background:' . $this->showResults['background'] . ';'; |
| 1182 | + } |
| 1183 | + } |
| 1184 | + |
| 1185 | + # transform input according to showresults=2 (bars) |
| 1186 | + # *** warning! parameters should be passed only by value, not by reference *** |
| 1187 | + function addShowResults2( $inp, $proposalId, $catId ) { |
| 1188 | + $this->cellTemplateParam['inp'] = $inp; |
| 1189 | + $this->cellTemplateParam['percents'] = ' '; |
| 1190 | + if ( ( $percents = $this->getPercents( $proposalId, $catId ) ) !== false ) { |
| 1191 | + # there is a stat in cell |
| 1192 | + $this->cellTemplateParam['percents'] = $percents . '%'; |
| 1193 | + $this->cellTemplateParam['bar1style'] = 'width:' . $percents . 'px;' . $this->cellTemplate[ 'bar1showres' ]; |
| 1194 | + $this->cellTemplateParam['bar2style'] = 'width:' . (100 - $percents) . 'px;' . $this->cellTemplate[ 'bar2showres' ]; |
| 1195 | + if ( $inp['type'] == 'text' ) { |
| 1196 | + return qp_Renderer::renderHTMLobject( $this->cellTemplate['textinput'] ); |
| 1197 | + } else { |
| 1198 | + return qp_Renderer::renderHTMLobject( $this->cellTemplate['bar'] ); |
| 1199 | + } |
| 1200 | + } else { |
| 1201 | + return $inp; |
| 1202 | + } |
| 1203 | + } |
| 1204 | + |
| 1205 | + /*** end of cell templates ***/ |
| 1206 | + |
| 1207 | +} |
Property changes on: trunk/extensions/QPoll/qp_question.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 1208 | + native |
Index: trunk/extensions/QPoll/qpoll.src |
— | — | @@ -0,0 +1,62 @@ |
| 2 | +CREATE TABLE /*$wgDBprefix*/qp_poll_desc ( |
| 3 | + `pid` int unsigned NOT NULL auto_increment, |
| 4 | + `article_id` int unsigned NOT NULL, |
| 5 | + `poll_id` tinytext NOT NULL, |
| 6 | + `order_id` int unsigned NOT NULL, |
| 7 | + `dependance` mediumtext NOT NULL, |
| 8 | + PRIMARY KEY poll (pid), |
| 9 | + UNIQUE INDEX article_poll (article_id,poll_id(128)) |
| 10 | +) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
| 11 | + |
| 12 | +CREATE TABLE /*$wgDBprefix*/qp_question_desc ( |
| 13 | + `pid` int unsigned NOT NULL, |
| 14 | + `question_id` int unsigned NOT NULL, |
| 15 | + `type` tinytext NOT NULL, |
| 16 | + `common_question` mediumtext NOT NULL, |
| 17 | + PRIMARY KEY question (pid,question_id), |
| 18 | + INDEX poll (pid) |
| 19 | +) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
| 20 | + |
| 21 | +CREATE TABLE /*$wgDBprefix*/qp_question_categories ( |
| 22 | + `pid` int unsigned NOT NULL, |
| 23 | + `question_id` int unsigned NOT NULL, |
| 24 | + `cat_id` int unsigned NOT NULL, |
| 25 | + `cat_name` tinytext NOT NULL, |
| 26 | + PRIMARY KEY category (pid,question_id,cat_id), |
| 27 | + INDEX poll (pid) |
| 28 | +) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
| 29 | + |
| 30 | +CREATE TABLE /*$wgDBprefix*/qp_question_proposals ( |
| 31 | + `pid` int unsigned NOT NULL, |
| 32 | + `question_id` int unsigned NOT NULL, |
| 33 | + `proposal_id` int unsigned NOT NULL, |
| 34 | + `proposal_text` tinytext NOT NULL, |
| 35 | + PRIMARY KEY proposal (pid,question_id,proposal_id), |
| 36 | + INDEX poll (pid) |
| 37 | +) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
| 38 | + |
| 39 | +CREATE TABLE /*$wgDBprefix*/qp_question_answers ( |
| 40 | + `uid` int unsigned NOT NULL, |
| 41 | + `pid` int unsigned NOT NULL, |
| 42 | + `question_id` int unsigned NOT NULL, |
| 43 | + `proposal_id` int unsigned NOT NULL, |
| 44 | + `cat_id` int unsigned NOT NULL, |
| 45 | + `text_answer` mediumtext, |
| 46 | + PRIMARY KEY answer (uid,pid,question_id,proposal_id,cat_id), |
| 47 | + INDEX user_vote (uid,pid), |
| 48 | + INDEX poll_question (pid,question_id) |
| 49 | +) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
| 50 | + |
| 51 | +CREATE TABLE /*$wgDBprefix*/qp_users_polls ( |
| 52 | + `uid` int unsigned NOT NULL, |
| 53 | + `pid` int unsigned NOT NULL, |
| 54 | + PRIMARY KEY user_poll (uid,pid) |
| 55 | +) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
| 56 | + |
| 57 | +CREATE TABLE /*$wgDBprefix*/qp_users ( |
| 58 | + `uid` int unsigned NOT NULL auto_increment, |
| 59 | + `name` tinytext NOT NULL, |
| 60 | + PRIMARY KEY unique_name (uid,name(64)), |
| 61 | + INDEX user_id (uid), |
| 62 | + INDEX username (name(64)) |
| 63 | +) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
Property changes on: trunk/extensions/QPoll/qpoll.src |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 64 | + native |