r47264 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r47263‎ | r47264 | r47265 >
Date:14:45, 14 February 2009
Author:ialex
Status:ok
Tags:
Comment:
svn:eol-style native
Modified paths:
  • /trunk/extensions/ClientSide/ClientSide.php (modified) (history)
  • /trunk/extensions/CommunityVoice/CLI/Initialize.php (modified) (history)
  • /trunk/extensions/CommunityVoice/Modules/Ratings.php (modified) (history)
  • /trunk/extensions/DeleteQueue/Views/DeleteQueueView.php (modified) (history)
  • /trunk/extensions/DeleteQueue/Views/DeleteQueueView.template.php (modified) (history)
  • /trunk/extensions/DeleteQueue/Views/DeleteQueueViewCase.php (modified) (history)
  • /trunk/extensions/DeleteQueue/Views/DeleteQueueViewNominate.php (modified) (history)
  • /trunk/extensions/DeleteQueue/Views/DeleteQueueViewVote.php (modified) (history)
  • /trunk/extensions/DeleteQueue/deletequeue.css (modified) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/libAddMedia/searchLibs/mediaWikiSearch.js (modified) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/libAddMedia/searchLibs/metavidSearch.js (modified) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/libAddMedia/searchLibs/solrArchiveSearch.js (modified) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/libAddMedia/seqRemoteSearchDriver.js (modified) (history)
  • /trunk/extensions/ParserFunctions/exprTests.txt (modified) (history)
  • /trunk/extensions/ParserFunctions/testExpr.php (modified) (history)

Diff [purge]

Property changes on: trunk/extensions/CommunityVoice/CLI/Initialize.php
___________________________________________________________________
Name: svn:eol-style
11 + native
Index: trunk/extensions/CommunityVoice/Modules/Ratings.php
@@ -1,489 +1,489 @@
2 -<?php
3 -
4 -abstract class CommunityVoiceRatings {
5 -
6 - /* Private Static Functions */
7 -
8 - private static function getScaleFraction( $rating, $star ) {
9 - if ( floor( $rating ) > $star ) {
10 - return 6;
11 - } else if ( floor( $rating ) < $star ) {
12 - return 0;
13 - } else {
14 - return round( ( 6 / 10 ) * ( ( $rating - floor( $rating ) ) * 10 ) );
15 - }
16 - }
17 -
18 - private static function getArticlesUsing( $category, $title ) {
19 - $dbr = wfGetDB( DB_SLAVE );
20 - $result = $dbr->select(
21 - 'cv_ratings_usage',
22 - 'usg_article',
23 - array(
24 - 'usg_category' => $category,
25 - 'usg_title' => $title,
26 - )
27 - );
28 - $articles = array();
29 - while ( $row = $result->fetchRow() ) {
30 - $articles[] = (string)$row['usg_article'];
31 - }
32 - return $articles;
33 - }
34 -
35 - private static function getCategories() {
36 - $dbr = wfGetDB( DB_SLAVE );
37 - $result = $dbr->select(
38 - 'cv_ratings_votes',
39 - 'DISTINCT vot_category'
40 - );
41 - $categories = array();
42 - while ( $row = $result->fetchRow() ) {
43 - $categories[] = (string)$row['vot_category'];
44 - }
45 - return $categories;
46 - }
47 -
48 - private static function getTitles( $category ) {
49 - $dbr = wfGetDB( DB_SLAVE );
50 - $result = $dbr->select(
51 - 'cv_ratings_votes',
52 - 'DISTINCT vot_title',
53 - array( 'vot_category' => $category )
54 - );
55 - $titles = array();
56 - while ( $row = $result->fetchRow() ) {
57 - $titles[] = (string)$row['vot_title'];
58 - }
59 - return $titles;
60 - }
61 -
62 - private static function getTotalVotes( $category, $title ) {
63 - $dbr = wfGetDB( DB_SLAVE );
64 - return (integer)$dbr->selectField(
65 - 'cv_ratings_votes',
66 - 'COUNT(*)',
67 - array(
68 - 'vot_category' => $category,
69 - 'vot_title' => $title,
70 - )
71 - );
72 - }
73 -
74 - private static function getUserVoted( $category, $title ) {
75 - global $wgUser;
76 - $dbr = wfGetDB( DB_SLAVE );
77 - return (bool)$dbr->selectField(
78 - 'cv_ratings_votes',
79 - 'COUNT(*)',
80 - array(
81 - 'vot_category' => $category,
82 - 'vot_title' => $title,
83 - 'vot_user' => $wgUser->getId(),
84 - )
85 - );
86 - }
87 -
88 - private static function getAverageRating( $category, $title ) {
89 - $dbr = wfGetDB( DB_SLAVE );
90 - return (float)$dbr->selectField(
91 - 'cv_ratings_votes',
92 - 'AVG(vot_rating)',
93 - array(
94 - 'vot_category' => $category,
95 - 'vot_title' => $title,
96 - )
97 - );
98 - }
99 -
100 - private static function addVote( $category, $title, $rating ) {
101 - global $wgUser;
102 - // Checks if...
103 - if (
104 - // User is logged in
105 - $wgUser->isLoggedIn() &&
106 - // User has not yet voted
107 - !self::getUserVoted( $category, $title )
108 - ) {
109 - // Get database connection
110 - $dbw = wfGetDB( DB_MASTER );
111 - // Insert new vote for user
112 - $dbw->insert(
113 - 'cv_ratings_votes',
114 - array(
115 - 'vot_category' => $category,
116 - 'vot_title' => $title,
117 - 'vot_user' => $wgUser->getId(),
118 - 'vot_rating' => $rating,
119 - )
120 - );
121 - $dbw->commit();
122 - return true;
123 - }
124 - return false;
125 - }
126 -
127 - /* Static Functions */
128 -
129 - public static function register() {
130 - global $wgParser, $wgAjaxExportList, $wgHooks;
131 - // Register the hook with the parser
132 - $wgParser->setHook( 'ratings:scale', array( __CLASS__, 'renderScale' ) );
133 - // Register ajax response hook
134 - $wgAjaxExportList[] = __CLASS__ . '::handleScaleVoteCall';
135 - // Register article save hook
136 - $wgHooks['ArticleSave'][] = __CLASS__ . '::updateArticleUsage';
137 -
138 - }
139 -
140 - public static function updateArticleUsage( $article, $user, $text, $summary, $minor, $watch, $sectionanchor, $flags ) {
141 - $usedRatings = array();
142 - // Extract all ratings:scale tags
143 - preg_match_all(
144 - "/<ratings:scale[^>]*[\\/]*>/i", $text, $matches, PREG_PATTERN_ORDER
145 - );
146 - // Loop over each match
147 - foreach ( $matches[0] as $match ) {
148 - $rating = array();
149 - foreach ( array( 'category', 'title' ) as $attribute ) {
150 - // Extract value of attribute
151 - preg_match(
152 - "/{$attribute}=['\"]*(?<value>[^'\"]*)['\"]*/i",
153 - $match,
154 - $values
155 - );
156 - if ( isset( $values['value'] ) ) {
157 - $rating[$attribute] = $values['value'];
158 - }
159 - }
160 - if ( isset( $rating['category'], $rating['title'] ) ) {
161 - $usedRatings[] = $rating;
162 - }
163 - }
164 - // Gets name of article
165 - $articleDbKey = $article->getTitle()->getPrefixedDBkey();
166 - // Get database connection
167 - $dbw = wfGetDB( DB_MASTER );
168 - // Remove all usage for this article
169 - $dbw->delete(
170 - 'cv_ratings_usage',
171 - array( 'usg_article' => $articleDbKey )
172 - );
173 - // Loop over each rating
174 - foreach ( $usedRatings as $rating ) {
175 - // Add usage for rating for this article
176 - $dbw->insert(
177 - 'cv_ratings_usage',
178 - array(
179 - 'usg_category' => $rating['category'],
180 - 'usg_title' => $rating['title'],
181 - 'usg_article' => $articleDbKey,
182 - )
183 - );
184 - }
185 - return true;
186 - }
187 -
188 - public static function renderScale( $input, $args, $parser ) {
189 - global $wgUser, $wgTitle;
190 - global $egCommunityVoiceResourcesPath;
191 - // Validate and sanitize incoming arguments
192 - $errors = array();
193 - $error = false;
194 - foreach ( array( 'category', 'title' ) as $argument ) {
195 - if ( isset( $args[$argument] ) ) {
196 - $args[$argument] = htmlspecialchars( $args[$argument] );
197 - } else {
198 - $error = true;
199 - if ( $parser->getOptions()->getIsPreview() ) {
200 - $errors[] = CommunityVoice::getMessage(
201 - 'ratings', 'error-missing-argument', $argument
202 - );
203 - }
204 - }
205 - }
206 - // Checks if an error ocurred
207 - if ( $error ) {
208 - // Checks if there are any error messages to return
209 - if ( count( $errors ) ) {
210 - return Html::div(
211 - array( 'class' => 'error' ), implode( ' ', $errors )
212 - );
213 - }
214 - // Continues without rendering
215 - return true;
216 - }
217 - // Collects data
218 - $totalVotes = self::getTotalVotes( $args['category'], $args['title'] );
219 - $rating = self::getAverageRating( $args['category'], $args['title'] );
220 - $userVoted = self::getUserVoted( $args['category'], $args['title'] );
221 - // Builds sanitized HTML id with prepended module naming
222 - $id = Html::toId(
223 - 'cv_ratings_scale_' . $args['category'] . '_' . $args['title']
224 - );
225 - // Gets stats message
226 - $stats = CommunityVoice::getMessage(
227 - 'ratings', 'scale-stats', array( round( $rating, 1 ), $totalVotes )
228 - );
229 - // Begins rating scale
230 - $htmlOut = Html::open(
231 - 'div',
232 - array( 'class' => 'communityvoice-ratings-scale', 'id' => $id )
233 - );
234 - // Checks for input
235 - if ( $input != '' ) {
236 - // Adds content of tag as parsed wiki-text
237 - $htmlOut .= $parser->recursiveTagParse( $input );
238 - }
239 - // Checks if the user has not voted yet and is logged in
240 - if ( !$userVoted && $wgUser->isLoggedIn() ) {
241 -
242 - /* Ajax Interaction */
243 -
244 - // Adds scale script
245 - $htmlOut .= Html::script(
246 - Js::callFunction(
247 - 'communityVoice.ratings.scales.add',
248 - Js::buildInstance(
249 - 'CommunityVoiceRatingsScale',
250 - array(
251 - Js::toScalar( $id ),
252 - Js::toScalar( $args['category'] ),
253 - Js::toScalar( $args['title'] ),
254 - Js::toScalar( $rating ),
255 - Js::toObject(
256 - array(
257 - 'stats' => $stats,
258 - 'status' => array(
259 - 'null' => '&nbsp;',
260 - 'sending' => CommunityVoice::getMessage(
261 - 'ratings', 'scale-status-sending'
262 - ),
263 - 'error' => CommunityVoice::getMessage(
264 - 'ratings', 'scale-status-error'
265 - ),
266 - 'thanks' => CommunityVoice::getMessage(
267 - 'ratings', 'scale-status-thanks'
268 - ),
269 - )
270 - )
271 - ),
272 - Js::toScalar( $wgTitle->getPrefixedText() )
273 - )
274 - )
275 - )
276 - );
277 -
278 - /* HTML Form Interaction */
279 -
280 - // Begins non-javascript fallback
281 - $htmlOut .= Html::open( 'noscript' );
282 - // Begins form
283 - $specialPageTitle = Title::newFromText( 'Special:CommunityVoice' );
284 - $htmlOut .= Html::open(
285 - 'form',
286 - array(
287 - 'action' => $specialPageTitle->getFullUrl(),
288 - 'method' => 'post',
289 - )
290 - );
291 - // Builds list of hidden fields
292 - $hiddenFields = array(
293 - 'token' => $wgUser->editToken(),
294 - 'module' => 'Ratings',
295 - 'action' => 'ScaleVoteSubmission',
296 - 'scale[article]' => $wgTitle->getPrefixedText(),
297 - 'scale[category]' => $args['category'],
298 - 'scale[title]' => $args['title'],
299 - );
300 - // Loops over each field
301 - foreach ( $hiddenFields as $name => $value ) {
302 - // Adds hidden field
303 - $htmlOut .= Html::input(
304 - array(
305 - 'type' => 'hidden', 'name' => $name, 'value' => $value
306 - )
307 - );
308 - }
309 - // Loops 5 times (once per star)
310 - for ( $i = 0; $i < 5; $i++ ) {
311 - // Adds star as image input
312 - $htmlOut .= Html::input(
313 - array(
314 - 'type' => 'image',
315 - 'name' => 'scale[rating_' . $i . ']',
316 - 'src' => sprintf(
317 - '%s/Icons/star-%d.png',
318 - $egCommunityVoiceResourcesPath,
319 - self::getScaleFraction( $rating, $i )
320 - ),
321 - 'border' => 0,
322 - 'alt' => '',
323 - 'class' => 'star',
324 - 'align' => 'absmiddle',
325 - )
326 - );
327 - }
328 - // Adds stats message
329 - $htmlOut .= Html::tag( 'span', array( 'class' => 'stats' ), $stats );
330 - // Ends form
331 - $htmlOut .= Html::close( 'form' );
332 - // Ends non-javascript fallback
333 - $htmlOut .= Html::close( 'noscript' );
334 - } else {
335 -
336 - /* No Interaction */
337 -
338 - // Loops 5 times (once per star)
339 - for ( $i = 0; $i < 5; $i++ ) {
340 - // Adds star as image
341 - $htmlOut .= Html::tag(
342 - 'img',
343 - array(
344 - 'src' => sprintf(
345 - '%s/Icons/star-%d.png',
346 - $egCommunityVoiceResourcesPath,
347 - self::getScaleFraction( $rating, $i )
348 - ),
349 - 'border' => 0,
350 - 'alt' => '',
351 - 'class' => 'star',
352 - 'align' => 'absmiddle',
353 - )
354 - );
355 - }
356 - // Adds stats message
357 - $htmlOut .= Html::tag( 'span', array( 'class' => 'stats' ), $stats );
358 - }
359 - // Ends scale
360 - $htmlOut .= Xml::closeElement( 'div' );
361 - // Returns output
362 - return $htmlOut;
363 - }
364 -
365 - /* Processing Functions */
366 -
367 - /**
368 - * Hanlder for ratings scale vote via ajax call
369 - */
370 - public static function handleScaleVoteCall( $category, $title, $rating, $article ) {
371 - global $wgUser;
372 - // Adds vote and checks for success
373 - if ( self::addVote( $category, $title, $rating ) ) {
374 - // Gets new rating data
375 - $rating = self::getAverageRating( $category, $title );
376 - // Builds result
377 - $result = array(
378 - 'rating' => $rating,
379 - 'stats' => CommunityVoice::getMessage(
380 - 'ratings',
381 - 'scale-stats',
382 - array(
383 - round( $rating, 1 ),
384 - self::getTotalVotes( $category, $title )
385 - )
386 - ),
387 - );
388 - // Gets articles that use this rating
389 - $articles = self::getArticlesUsing( $category, $title );
390 - // Loops over each article
391 - foreach ( $articles as $article ) {
392 - // Invalidates the cache of the article
393 - CommunityVoice::touchArticle( $article );
394 - }
395 - // Ensure database commits take place (since this is an ajax call)
396 - $dbw = wfGetDB( DB_MASTER );
397 - $dbw->commit();
398 - // Returns result
399 - return Js::toObject( $result );
400 - }
401 - // Returns error information
402 - return Js::toObject( array( 'rating' => - 1, 'stats' => null ) );
403 - }
404 -
405 - /**
406 - * Hanlder for ratings scale vote via HTML form submission
407 - */
408 - public static function handleScaleVoteSubmission() {
409 - global $wgOut, $wgRequest;
410 - // Gets scale data
411 - $scale = $wgRequest->getArray( 'scale' );
412 - // Checks if an article was given
413 - if ( isset( $scale['article'], $scale['title'], $scale['category'] ) ) {
414 - // Looks for rating value
415 - foreach ( $scale as $key => $value ) {
416 - // Breaks key into parts
417 - $parts = explode( '_', $key );
418 - // Checks if...
419 - if (
420 - // There's at least 2 parts
421 - ( count( $parts ) > 1 ) &&
422 - // The first part is 'rating'
423 - ( $parts[0] == 'rating' ) &&
424 - // The second part is a number
425 - ( is_numeric( $parts[1] ) )
426 - ) {
427 - // Uses number as rating
428 - $rating = $parts[1];
429 - // Finishes loop
430 - break;
431 - }
432 - }
433 - // Checks if a rating was found
434 - if ( isset( $rating ) ) {
435 - // Adds vote and checks for success
436 - if (
437 - self::addVote(
438 - $scale['category'], $scale['title'], $rating
439 - )
440 - ) {
441 - // Gets articles that use this rating
442 - $articles = self::getArticlesUsing(
443 - $scale['category'], $scale['title']
444 - );
445 - // Loops over each article
446 - foreach ( $articles as $article ) {
447 - // Invalidates the cache of the article
448 - CommunityVoice::touchArticle( $article );
449 - }
450 - // Redirects user back to article
451 - $wgOut->redirect(
452 - Title::newFromText( $scale['article'] )->getFullUrl()
453 - );
454 - } else {
455 - throw new MWException( 'Voting failed!' );
456 - }
457 - } else {
458 - throw new MWException( 'No rating parameter!' );
459 - }
460 - } else {
461 - throw new MWException( 'Missing parameters!' );
462 - }
463 - }
464 -
465 - /* UI Functions */
466 -
467 - /**
468 - * Outputs a summary UI for the module
469 - */
470 - public static function showSummary() {
471 - global $wgOut;
472 - //
473 - $wgOut->addWikiText( '==== Categories ====' );
474 - $xmlCategories = Html::open( 'ul' );
475 - foreach ( self::getCategories() as $category ) {
476 - $xmlCategories .= Html::tag( 'li', $category );
477 - }
478 - $xmlCategories .= Html::close( 'ul' );
479 - $wgOut->addHtml( $xmlCategories );
480 - }
481 -
482 - /**
483 - * Outputs main UI for module
484 - */
485 - public static function showMain( $path ) {
486 - global $wgOut;
487 - //
488 - $wgOut->addWikiText( '==== Detailed Information ====' );
489 - }
490 -}
 2+<?php
 3+
 4+abstract class CommunityVoiceRatings {
 5+
 6+ /* Private Static Functions */
 7+
 8+ private static function getScaleFraction( $rating, $star ) {
 9+ if ( floor( $rating ) > $star ) {
 10+ return 6;
 11+ } else if ( floor( $rating ) < $star ) {
 12+ return 0;
 13+ } else {
 14+ return round( ( 6 / 10 ) * ( ( $rating - floor( $rating ) ) * 10 ) );
 15+ }
 16+ }
 17+
 18+ private static function getArticlesUsing( $category, $title ) {
 19+ $dbr = wfGetDB( DB_SLAVE );
 20+ $result = $dbr->select(
 21+ 'cv_ratings_usage',
 22+ 'usg_article',
 23+ array(
 24+ 'usg_category' => $category,
 25+ 'usg_title' => $title,
 26+ )
 27+ );
 28+ $articles = array();
 29+ while ( $row = $result->fetchRow() ) {
 30+ $articles[] = (string)$row['usg_article'];
 31+ }
 32+ return $articles;
 33+ }
 34+
 35+ private static function getCategories() {
 36+ $dbr = wfGetDB( DB_SLAVE );
 37+ $result = $dbr->select(
 38+ 'cv_ratings_votes',
 39+ 'DISTINCT vot_category'
 40+ );
 41+ $categories = array();
 42+ while ( $row = $result->fetchRow() ) {
 43+ $categories[] = (string)$row['vot_category'];
 44+ }
 45+ return $categories;
 46+ }
 47+
 48+ private static function getTitles( $category ) {
 49+ $dbr = wfGetDB( DB_SLAVE );
 50+ $result = $dbr->select(
 51+ 'cv_ratings_votes',
 52+ 'DISTINCT vot_title',
 53+ array( 'vot_category' => $category )
 54+ );
 55+ $titles = array();
 56+ while ( $row = $result->fetchRow() ) {
 57+ $titles[] = (string)$row['vot_title'];
 58+ }
 59+ return $titles;
 60+ }
 61+
 62+ private static function getTotalVotes( $category, $title ) {
 63+ $dbr = wfGetDB( DB_SLAVE );
 64+ return (integer)$dbr->selectField(
 65+ 'cv_ratings_votes',
 66+ 'COUNT(*)',
 67+ array(
 68+ 'vot_category' => $category,
 69+ 'vot_title' => $title,
 70+ )
 71+ );
 72+ }
 73+
 74+ private static function getUserVoted( $category, $title ) {
 75+ global $wgUser;
 76+ $dbr = wfGetDB( DB_SLAVE );
 77+ return (bool)$dbr->selectField(
 78+ 'cv_ratings_votes',
 79+ 'COUNT(*)',
 80+ array(
 81+ 'vot_category' => $category,
 82+ 'vot_title' => $title,
 83+ 'vot_user' => $wgUser->getId(),
 84+ )
 85+ );
 86+ }
 87+
 88+ private static function getAverageRating( $category, $title ) {
 89+ $dbr = wfGetDB( DB_SLAVE );
 90+ return (float)$dbr->selectField(
 91+ 'cv_ratings_votes',
 92+ 'AVG(vot_rating)',
 93+ array(
 94+ 'vot_category' => $category,
 95+ 'vot_title' => $title,
 96+ )
 97+ );
 98+ }
 99+
 100+ private static function addVote( $category, $title, $rating ) {
 101+ global $wgUser;
 102+ // Checks if...
 103+ if (
 104+ // User is logged in
 105+ $wgUser->isLoggedIn() &&
 106+ // User has not yet voted
 107+ !self::getUserVoted( $category, $title )
 108+ ) {
 109+ // Get database connection
 110+ $dbw = wfGetDB( DB_MASTER );
 111+ // Insert new vote for user
 112+ $dbw->insert(
 113+ 'cv_ratings_votes',
 114+ array(
 115+ 'vot_category' => $category,
 116+ 'vot_title' => $title,
 117+ 'vot_user' => $wgUser->getId(),
 118+ 'vot_rating' => $rating,
 119+ )
 120+ );
 121+ $dbw->commit();
 122+ return true;
 123+ }
 124+ return false;
 125+ }
 126+
 127+ /* Static Functions */
 128+
 129+ public static function register() {
 130+ global $wgParser, $wgAjaxExportList, $wgHooks;
 131+ // Register the hook with the parser
 132+ $wgParser->setHook( 'ratings:scale', array( __CLASS__, 'renderScale' ) );
 133+ // Register ajax response hook
 134+ $wgAjaxExportList[] = __CLASS__ . '::handleScaleVoteCall';
 135+ // Register article save hook
 136+ $wgHooks['ArticleSave'][] = __CLASS__ . '::updateArticleUsage';
 137+
 138+ }
 139+
 140+ public static function updateArticleUsage( $article, $user, $text, $summary, $minor, $watch, $sectionanchor, $flags ) {
 141+ $usedRatings = array();
 142+ // Extract all ratings:scale tags
 143+ preg_match_all(
 144+ "/<ratings:scale[^>]*[\\/]*>/i", $text, $matches, PREG_PATTERN_ORDER
 145+ );
 146+ // Loop over each match
 147+ foreach ( $matches[0] as $match ) {
 148+ $rating = array();
 149+ foreach ( array( 'category', 'title' ) as $attribute ) {
 150+ // Extract value of attribute
 151+ preg_match(
 152+ "/{$attribute}=['\"]*(?<value>[^'\"]*)['\"]*/i",
 153+ $match,
 154+ $values
 155+ );
 156+ if ( isset( $values['value'] ) ) {
 157+ $rating[$attribute] = $values['value'];
 158+ }
 159+ }
 160+ if ( isset( $rating['category'], $rating['title'] ) ) {
 161+ $usedRatings[] = $rating;
 162+ }
 163+ }
 164+ // Gets name of article
 165+ $articleDbKey = $article->getTitle()->getPrefixedDBkey();
 166+ // Get database connection
 167+ $dbw = wfGetDB( DB_MASTER );
 168+ // Remove all usage for this article
 169+ $dbw->delete(
 170+ 'cv_ratings_usage',
 171+ array( 'usg_article' => $articleDbKey )
 172+ );
 173+ // Loop over each rating
 174+ foreach ( $usedRatings as $rating ) {
 175+ // Add usage for rating for this article
 176+ $dbw->insert(
 177+ 'cv_ratings_usage',
 178+ array(
 179+ 'usg_category' => $rating['category'],
 180+ 'usg_title' => $rating['title'],
 181+ 'usg_article' => $articleDbKey,
 182+ )
 183+ );
 184+ }
 185+ return true;
 186+ }
 187+
 188+ public static function renderScale( $input, $args, $parser ) {
 189+ global $wgUser, $wgTitle;
 190+ global $egCommunityVoiceResourcesPath;
 191+ // Validate and sanitize incoming arguments
 192+ $errors = array();
 193+ $error = false;
 194+ foreach ( array( 'category', 'title' ) as $argument ) {
 195+ if ( isset( $args[$argument] ) ) {
 196+ $args[$argument] = htmlspecialchars( $args[$argument] );
 197+ } else {
 198+ $error = true;
 199+ if ( $parser->getOptions()->getIsPreview() ) {
 200+ $errors[] = CommunityVoice::getMessage(
 201+ 'ratings', 'error-missing-argument', $argument
 202+ );
 203+ }
 204+ }
 205+ }
 206+ // Checks if an error ocurred
 207+ if ( $error ) {
 208+ // Checks if there are any error messages to return
 209+ if ( count( $errors ) ) {
 210+ return Html::div(
 211+ array( 'class' => 'error' ), implode( ' ', $errors )
 212+ );
 213+ }
 214+ // Continues without rendering
 215+ return true;
 216+ }
 217+ // Collects data
 218+ $totalVotes = self::getTotalVotes( $args['category'], $args['title'] );
 219+ $rating = self::getAverageRating( $args['category'], $args['title'] );
 220+ $userVoted = self::getUserVoted( $args['category'], $args['title'] );
 221+ // Builds sanitized HTML id with prepended module naming
 222+ $id = Html::toId(
 223+ 'cv_ratings_scale_' . $args['category'] . '_' . $args['title']
 224+ );
 225+ // Gets stats message
 226+ $stats = CommunityVoice::getMessage(
 227+ 'ratings', 'scale-stats', array( round( $rating, 1 ), $totalVotes )
 228+ );
 229+ // Begins rating scale
 230+ $htmlOut = Html::open(
 231+ 'div',
 232+ array( 'class' => 'communityvoice-ratings-scale', 'id' => $id )
 233+ );
 234+ // Checks for input
 235+ if ( $input != '' ) {
 236+ // Adds content of tag as parsed wiki-text
 237+ $htmlOut .= $parser->recursiveTagParse( $input );
 238+ }
 239+ // Checks if the user has not voted yet and is logged in
 240+ if ( !$userVoted && $wgUser->isLoggedIn() ) {
 241+
 242+ /* Ajax Interaction */
 243+
 244+ // Adds scale script
 245+ $htmlOut .= Html::script(
 246+ Js::callFunction(
 247+ 'communityVoice.ratings.scales.add',
 248+ Js::buildInstance(
 249+ 'CommunityVoiceRatingsScale',
 250+ array(
 251+ Js::toScalar( $id ),
 252+ Js::toScalar( $args['category'] ),
 253+ Js::toScalar( $args['title'] ),
 254+ Js::toScalar( $rating ),
 255+ Js::toObject(
 256+ array(
 257+ 'stats' => $stats,
 258+ 'status' => array(
 259+ 'null' => '&nbsp;',
 260+ 'sending' => CommunityVoice::getMessage(
 261+ 'ratings', 'scale-status-sending'
 262+ ),
 263+ 'error' => CommunityVoice::getMessage(
 264+ 'ratings', 'scale-status-error'
 265+ ),
 266+ 'thanks' => CommunityVoice::getMessage(
 267+ 'ratings', 'scale-status-thanks'
 268+ ),
 269+ )
 270+ )
 271+ ),
 272+ Js::toScalar( $wgTitle->getPrefixedText() )
 273+ )
 274+ )
 275+ )
 276+ );
 277+
 278+ /* HTML Form Interaction */
 279+
 280+ // Begins non-javascript fallback
 281+ $htmlOut .= Html::open( 'noscript' );
 282+ // Begins form
 283+ $specialPageTitle = Title::newFromText( 'Special:CommunityVoice' );
 284+ $htmlOut .= Html::open(
 285+ 'form',
 286+ array(
 287+ 'action' => $specialPageTitle->getFullUrl(),
 288+ 'method' => 'post',
 289+ )
 290+ );
 291+ // Builds list of hidden fields
 292+ $hiddenFields = array(
 293+ 'token' => $wgUser->editToken(),
 294+ 'module' => 'Ratings',
 295+ 'action' => 'ScaleVoteSubmission',
 296+ 'scale[article]' => $wgTitle->getPrefixedText(),
 297+ 'scale[category]' => $args['category'],
 298+ 'scale[title]' => $args['title'],
 299+ );
 300+ // Loops over each field
 301+ foreach ( $hiddenFields as $name => $value ) {
 302+ // Adds hidden field
 303+ $htmlOut .= Html::input(
 304+ array(
 305+ 'type' => 'hidden', 'name' => $name, 'value' => $value
 306+ )
 307+ );
 308+ }
 309+ // Loops 5 times (once per star)
 310+ for ( $i = 0; $i < 5; $i++ ) {
 311+ // Adds star as image input
 312+ $htmlOut .= Html::input(
 313+ array(
 314+ 'type' => 'image',
 315+ 'name' => 'scale[rating_' . $i . ']',
 316+ 'src' => sprintf(
 317+ '%s/Icons/star-%d.png',
 318+ $egCommunityVoiceResourcesPath,
 319+ self::getScaleFraction( $rating, $i )
 320+ ),
 321+ 'border' => 0,
 322+ 'alt' => '',
 323+ 'class' => 'star',
 324+ 'align' => 'absmiddle',
 325+ )
 326+ );
 327+ }
 328+ // Adds stats message
 329+ $htmlOut .= Html::tag( 'span', array( 'class' => 'stats' ), $stats );
 330+ // Ends form
 331+ $htmlOut .= Html::close( 'form' );
 332+ // Ends non-javascript fallback
 333+ $htmlOut .= Html::close( 'noscript' );
 334+ } else {
 335+
 336+ /* No Interaction */
 337+
 338+ // Loops 5 times (once per star)
 339+ for ( $i = 0; $i < 5; $i++ ) {
 340+ // Adds star as image
 341+ $htmlOut .= Html::tag(
 342+ 'img',
 343+ array(
 344+ 'src' => sprintf(
 345+ '%s/Icons/star-%d.png',
 346+ $egCommunityVoiceResourcesPath,
 347+ self::getScaleFraction( $rating, $i )
 348+ ),
 349+ 'border' => 0,
 350+ 'alt' => '',
 351+ 'class' => 'star',
 352+ 'align' => 'absmiddle',
 353+ )
 354+ );
 355+ }
 356+ // Adds stats message
 357+ $htmlOut .= Html::tag( 'span', array( 'class' => 'stats' ), $stats );
 358+ }
 359+ // Ends scale
 360+ $htmlOut .= Xml::closeElement( 'div' );
 361+ // Returns output
 362+ return $htmlOut;
 363+ }
 364+
 365+ /* Processing Functions */
 366+
 367+ /**
 368+ * Hanlder for ratings scale vote via ajax call
 369+ */
 370+ public static function handleScaleVoteCall( $category, $title, $rating, $article ) {
 371+ global $wgUser;
 372+ // Adds vote and checks for success
 373+ if ( self::addVote( $category, $title, $rating ) ) {
 374+ // Gets new rating data
 375+ $rating = self::getAverageRating( $category, $title );
 376+ // Builds result
 377+ $result = array(
 378+ 'rating' => $rating,
 379+ 'stats' => CommunityVoice::getMessage(
 380+ 'ratings',
 381+ 'scale-stats',
 382+ array(
 383+ round( $rating, 1 ),
 384+ self::getTotalVotes( $category, $title )
 385+ )
 386+ ),
 387+ );
 388+ // Gets articles that use this rating
 389+ $articles = self::getArticlesUsing( $category, $title );
 390+ // Loops over each article
 391+ foreach ( $articles as $article ) {
 392+ // Invalidates the cache of the article
 393+ CommunityVoice::touchArticle( $article );
 394+ }
 395+ // Ensure database commits take place (since this is an ajax call)
 396+ $dbw = wfGetDB( DB_MASTER );
 397+ $dbw->commit();
 398+ // Returns result
 399+ return Js::toObject( $result );
 400+ }
 401+ // Returns error information
 402+ return Js::toObject( array( 'rating' => - 1, 'stats' => null ) );
 403+ }
 404+
 405+ /**
 406+ * Hanlder for ratings scale vote via HTML form submission
 407+ */
 408+ public static function handleScaleVoteSubmission() {
 409+ global $wgOut, $wgRequest;
 410+ // Gets scale data
 411+ $scale = $wgRequest->getArray( 'scale' );
 412+ // Checks if an article was given
 413+ if ( isset( $scale['article'], $scale['title'], $scale['category'] ) ) {
 414+ // Looks for rating value
 415+ foreach ( $scale as $key => $value ) {
 416+ // Breaks key into parts
 417+ $parts = explode( '_', $key );
 418+ // Checks if...
 419+ if (
 420+ // There's at least 2 parts
 421+ ( count( $parts ) > 1 ) &&
 422+ // The first part is 'rating'
 423+ ( $parts[0] == 'rating' ) &&
 424+ // The second part is a number
 425+ ( is_numeric( $parts[1] ) )
 426+ ) {
 427+ // Uses number as rating
 428+ $rating = $parts[1];
 429+ // Finishes loop
 430+ break;
 431+ }
 432+ }
 433+ // Checks if a rating was found
 434+ if ( isset( $rating ) ) {
 435+ // Adds vote and checks for success
 436+ if (
 437+ self::addVote(
 438+ $scale['category'], $scale['title'], $rating
 439+ )
 440+ ) {
 441+ // Gets articles that use this rating
 442+ $articles = self::getArticlesUsing(
 443+ $scale['category'], $scale['title']
 444+ );
 445+ // Loops over each article
 446+ foreach ( $articles as $article ) {
 447+ // Invalidates the cache of the article
 448+ CommunityVoice::touchArticle( $article );
 449+ }
 450+ // Redirects user back to article
 451+ $wgOut->redirect(
 452+ Title::newFromText( $scale['article'] )->getFullUrl()
 453+ );
 454+ } else {
 455+ throw new MWException( 'Voting failed!' );
 456+ }
 457+ } else {
 458+ throw new MWException( 'No rating parameter!' );
 459+ }
 460+ } else {
 461+ throw new MWException( 'Missing parameters!' );
 462+ }
 463+ }
 464+
 465+ /* UI Functions */
 466+
 467+ /**
 468+ * Outputs a summary UI for the module
 469+ */
 470+ public static function showSummary() {
 471+ global $wgOut;
 472+ //
 473+ $wgOut->addWikiText( '==== Categories ====' );
 474+ $xmlCategories = Html::open( 'ul' );
 475+ foreach ( self::getCategories() as $category ) {
 476+ $xmlCategories .= Html::tag( 'li', $category );
 477+ }
 478+ $xmlCategories .= Html::close( 'ul' );
 479+ $wgOut->addHtml( $xmlCategories );
 480+ }
 481+
 482+ /**
 483+ * Outputs main UI for module
 484+ */
 485+ public static function showMain( $path ) {
 486+ global $wgOut;
 487+ //
 488+ $wgOut->addWikiText( '==== Detailed Information ====' );
 489+ }
 490+}
Property changes on: trunk/extensions/CommunityVoice/Modules/Ratings.php
___________________________________________________________________
Name: svn:eol-style
491491 + native
Property changes on: trunk/extensions/ParserFunctions/exprTests.txt
___________________________________________________________________
Name: svn:eol-style
492492 + native
Property changes on: trunk/extensions/ParserFunctions/testExpr.php
___________________________________________________________________
Name: svn:eol-style
493493 + native
Property changes on: trunk/extensions/MetavidWiki/skins/mv_embed/libAddMedia/searchLibs/solrArchiveSearch.js
___________________________________________________________________
Name: svn:eol-style
494494 + native
Property changes on: trunk/extensions/MetavidWiki/skins/mv_embed/libAddMedia/searchLibs/mediaWikiSearch.js
___________________________________________________________________
Name: svn:eol-style
495495 + native
Property changes on: trunk/extensions/MetavidWiki/skins/mv_embed/libAddMedia/searchLibs/metavidSearch.js
___________________________________________________________________
Name: svn:eol-style
496496 + native
Property changes on: trunk/extensions/MetavidWiki/skins/mv_embed/libAddMedia/seqRemoteSearchDriver.js
___________________________________________________________________
Name: svn:eol-style
497497 + native
Property changes on: trunk/extensions/ClientSide/ClientSide.php
___________________________________________________________________
Name: svn:eol-style
498498 + native
Property changes on: trunk/extensions/DeleteQueue/Views/DeleteQueueView.template.php
___________________________________________________________________
Name: svn:eol-style
499499 + native
Property changes on: trunk/extensions/DeleteQueue/Views/DeleteQueueViewNominate.php
___________________________________________________________________
Name: svn:eol-style
500500 + native
Property changes on: trunk/extensions/DeleteQueue/Views/DeleteQueueViewCase.php
___________________________________________________________________
Name: svn:eol-style
501501 + native
Property changes on: trunk/extensions/DeleteQueue/Views/DeleteQueueViewVote.php
___________________________________________________________________
Name: svn:eol-style
502502 + native
Property changes on: trunk/extensions/DeleteQueue/Views/DeleteQueueView.php
___________________________________________________________________
Name: svn:eol-style
503503 + native
Property changes on: trunk/extensions/DeleteQueue/deletequeue.css
___________________________________________________________________
Name: svn:eol-style
504504 + native

Status & tagging log