Index: trunk/extensions/CommunityVoice/CommunityVoice.php |
— | — | @@ -37,48 +37,26 @@ |
38 | 38 | 'name' => 'CommunityVoice', |
39 | 39 | 'author' => 'Trevor Parscal', |
40 | 40 | 'url' => 'http://www.mediawiki.org/wiki/Extension:CommunityVoice', |
41 | | - 'descriptionmsg' => 'communityvoice-desc', |
| 41 | + 'description-msg' => 'communityvoice-desc', |
42 | 42 | 'version' => '0.1.0', |
43 | 43 | ); |
44 | | - |
45 | 44 | // Shortcut to this extension directory |
46 | 45 | $dir = dirname( __FILE__ ) . '/'; |
47 | | - |
48 | 46 | // Internationalization |
49 | 47 | $wgExtensionMessagesFiles['CommunityVoice'] = $dir . 'CommunityVoice.i18n.php'; |
50 | | -$wgExtensionAliasesFiles['CommunityVoice'] = $dir . 'CommunityVoice.alias.php'; |
51 | | - |
52 | 48 | // Class Autoloading |
53 | 49 | $wgAutoloadClasses['CommunityVoice'] = $dir . 'CommunityVoice.php'; |
54 | 50 | $wgAutoloadClasses['CommunityVoicePage'] = $dir . 'CommunityVoice.page.php'; |
55 | 51 | $wgAutoloadClasses['CommunityVoiceRatings'] = $dir . 'Modules/Ratings.php'; |
56 | | - |
57 | | -// Special Pages |
| 52 | +// Spacial Pages |
58 | 53 | $wgSpecialPages['CommunityVoice'] = 'CommunityVoicePage'; |
59 | | -$wgSpecialPageGroups['CommunityVoice'] = 'wiki'; |
60 | | - |
61 | 54 | // Setup Hooks |
62 | 55 | $wgExtensionFunctions[] = 'CommunityVoice::registerModules'; |
63 | 56 | $wgHooks['AjaxAddScript'][] = 'CommunityVoice::addScripts'; |
64 | 57 | $wgHooks['BeforePageDisplay'][] = 'CommunityVoice::addStyles'; |
65 | | -$wgHooks['LoadExtensionSchemaUpdates'][] = 'efCheckSchema'; |
66 | 58 | |
67 | | -function efCheckSchema() { |
68 | | - // Get a connection |
69 | | - $db = wfGetDB( DB_MASTER ); |
70 | | - // Create table if it doesn't exist |
71 | | - if ( !$db->tableExists( 'cv_ratings_votes' ) ) { |
72 | | - $db->sourceFile( dirname( __FILE__ ) . '/CommunityVoice.sql' ); |
73 | | - } |
74 | | - if ( !$db->tableExists( 'cv_ratings_usage' ) ) { |
75 | | - $db->sourceFile( dirname( __FILE__ ) . '/CommunityVoice.sql' ); |
76 | | - } |
77 | | - // Continue |
78 | | - return true; |
79 | | -} |
80 | | - |
81 | 59 | /* Classes */ |
82 | | -// FIXME: classes should be put in their own files |
| 60 | + |
83 | 61 | abstract class CommunityVoice { |
84 | 62 | |
85 | 63 | /* Static Members */ |
— | — | @@ -94,7 +72,12 @@ |
95 | 73 | return array_keys( self::$modules ); |
96 | 74 | } |
97 | 75 | |
98 | | - public static function callModuleAction( $module, $type, $action = '' ) { |
| 76 | + public static function callModuleAction( |
| 77 | + $module, |
| 78 | + $type, |
| 79 | + $action = '', |
| 80 | + $path = '' |
| 81 | + ) { |
99 | 82 | // Checks for class |
100 | 83 | if ( isset( self::$modules[$module] ) ) { |
101 | 84 | if ( class_exists( self::$modules[$module]['class'] ) ) { |
— | — | @@ -105,7 +88,7 @@ |
106 | 89 | // Checks callability |
107 | 90 | if ( is_callable( $function ) ) { |
108 | 91 | // Calls function on class |
109 | | - return call_user_func( $function ); |
| 92 | + return call_user_func( $function, $path ); |
110 | 93 | } else { |
111 | 94 | // Throws unfound/uncallable function exception |
112 | 95 | throw new MWException( |
— | — | @@ -130,13 +113,17 @@ |
131 | 114 | */ |
132 | 115 | public static function registerModules() { |
133 | 116 | // Loops over each module |
134 | | - foreach ( self::getModules() as $module ) { |
| 117 | + foreach( self::getModules() as $module ) { |
135 | 118 | self::callModuleAction( $module, 'register' ); |
136 | 119 | } |
137 | 120 | return true; |
138 | 121 | } |
139 | 122 | |
140 | | - public static function getMessage( $module, $message, $parameter = null ) { |
| 123 | + public static function getMessage( |
| 124 | + $module, |
| 125 | + $message, |
| 126 | + $parameter = null |
| 127 | + ) { |
141 | 128 | // Checks if extension messages have been loaded already |
142 | 129 | if ( !self::$messagesLoaded ) { |
143 | 130 | // Loads extension messages |
— | — | @@ -147,20 +134,14 @@ |
148 | 135 | return wfMsg( 'communityvoice-' . $module . '-' . $message, $parameter ); |
149 | 136 | } |
150 | 137 | |
151 | | - public static function touchArticle( $article ) { |
152 | | - // Gets the title of the article which included the scale |
153 | | - $articleTitle = Title::newFromText( $article ); |
154 | | - // Invalidates the cache of the article |
155 | | - $articleTitle->invalidateCache(); |
156 | | - } |
157 | | - |
158 | 138 | /** |
159 | 139 | * Adds scripts to document |
160 | 140 | */ |
161 | | - public static function addScripts( $out ) { |
| 141 | + public static function addScripts( |
| 142 | + $out |
| 143 | + ) { |
162 | 144 | global $wgJsMimeType; |
163 | 145 | global $egCommunityVoiceResourcesPath; |
164 | | - |
165 | 146 | $out->addInlineScript( |
166 | 147 | sprintf( |
167 | 148 | "var egCommunityVoiceResourcesPath = '%s';\n" , |
— | — | @@ -198,4 +179,4 @@ |
199 | 180 | ); |
200 | 181 | return true; |
201 | 182 | } |
202 | | -} |
| 183 | +} |
\ No newline at end of file |
Index: trunk/extensions/CommunityVoice/CommunityVoice.sql |
— | — | @@ -2,8 +2,6 @@ |
3 | 3 | -- SQL for CommunityVoice Extension |
4 | 4 | -- |
5 | 5 | -- Table for ratings |
6 | | - |
7 | 6 | DROP TABLE IF EXISTS /*$wgDBprefix*/cv_ratings_votes; |
8 | 7 | CREATE TABLE /*$wgDBPrefix*/cv_ratings_votes ( |
9 | 8 | -- Category of item being rated |
— | — | @@ -18,19 +16,4 @@ |
19 | 17 | INDEX vot_category_title ( vot_category, vot_title ), |
20 | 18 | INDEX vot_category_title_user ( vot_category, vot_title, vot_user ), |
21 | 19 | INDEX vot_category_title_rating ( vot_category, vot_title, vot_rating ) |
22 | | -) /*$wgDBTableOptions*/; |
23 | | -DROP TABLE IF EXISTS /*$wgDBprefix*/cv_ratings_usage; |
24 | | -CREATE TABLE /*$wgDBPrefix*/cv_ratings_usage ( |
25 | | - -- Category of item being rated |
26 | | - usg_category VARBINARY(255) NOT NULL default '', |
27 | | - -- Title of item being rated |
28 | | - usg_title VARBINARY(255) NOT NULL default '', |
29 | | - -- Title of article which includes the rating |
30 | | - usg_article VARBINARY(255) NOT NULL default '', |
31 | | - -- |
32 | | - INDEX rat_category_title ( usg_category, usg_title ), |
33 | | - INDEX rat_category_title_article ( usg_category, usg_title, usg_article ) |
34 | | -) /*$wgDBTableOptions*/; |
| 20 | +) /*$wgDBTableOptions*/; |
\ No newline at end of file |
Index: trunk/extensions/CommunityVoice/Modules/Ratings.php |
— | — | @@ -4,7 +4,10 @@ |
5 | 5 | |
6 | 6 | /* Private Static Functions */ |
7 | 7 | |
8 | | - private static function getScaleFraction( $rating, $star ) { |
| 8 | + private static function getScaleFraction( |
| 9 | + $rating, |
| 10 | + $star |
| 11 | + ) { |
9 | 12 | if ( floor( $rating ) > $star ) { |
10 | 13 | return 6; |
11 | 14 | } else if ( floor( $rating ) < $star ) { |
— | — | @@ -14,23 +17,6 @@ |
15 | 18 | } |
16 | 19 | } |
17 | 20 | |
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 | 21 | private static function getCategories() { |
36 | 22 | $dbr = wfGetDB( DB_SLAVE ); |
37 | 23 | $result = $dbr->select( |
— | — | @@ -44,7 +30,9 @@ |
45 | 31 | return $categories; |
46 | 32 | } |
47 | 33 | |
48 | | - private static function getTitles( $category ) { |
| 34 | + private static function getTitles( |
| 35 | + $category |
| 36 | + ) { |
49 | 37 | $dbr = wfGetDB( DB_SLAVE ); |
50 | 38 | $result = $dbr->select( |
51 | 39 | 'cv_ratings_votes', |
— | — | @@ -58,7 +46,10 @@ |
59 | 47 | return $titles; |
60 | 48 | } |
61 | 49 | |
62 | | - private static function getTotalVotes( $category, $title ) { |
| 50 | + private static function getTotalVotes( |
| 51 | + $category, |
| 52 | + $title |
| 53 | + ) { |
63 | 54 | $dbr = wfGetDB( DB_SLAVE ); |
64 | 55 | return (integer)$dbr->selectField( |
65 | 56 | 'cv_ratings_votes', |
— | — | @@ -70,7 +61,10 @@ |
71 | 62 | ); |
72 | 63 | } |
73 | 64 | |
74 | | - private static function getUserVoted( $category, $title ) { |
| 65 | + private static function getUserVoted( |
| 66 | + $category, |
| 67 | + $title |
| 68 | + ) { |
75 | 69 | global $wgUser; |
76 | 70 | $dbr = wfGetDB( DB_SLAVE ); |
77 | 71 | return (bool)$dbr->selectField( |
— | — | @@ -84,7 +78,10 @@ |
85 | 79 | ); |
86 | 80 | } |
87 | 81 | |
88 | | - private static function getAverageRating( $category, $title ) { |
| 82 | + private static function getAverageRating( |
| 83 | + $category, |
| 84 | + $title |
| 85 | + ) { |
89 | 86 | $dbr = wfGetDB( DB_SLAVE ); |
90 | 87 | return (float)$dbr->selectField( |
91 | 88 | 'cv_ratings_votes', |
— | — | @@ -96,7 +93,11 @@ |
97 | 94 | ); |
98 | 95 | } |
99 | 96 | |
100 | | - private static function addVote( $category, $title, $rating ) { |
| 97 | + private static function addVote( |
| 98 | + $category, |
| 99 | + $title, |
| 100 | + $rating |
| 101 | + ) { |
101 | 102 | global $wgUser; |
102 | 103 | // Checks if... |
103 | 104 | if ( |
— | — | @@ -131,62 +132,18 @@ |
132 | 133 | $wgParser->setHook( 'ratings:scale', array( __CLASS__, 'renderScale' ) ); |
133 | 134 | // Register ajax response hook |
134 | 135 | $wgAjaxExportList[] = __CLASS__ . '::handleScaleVoteCall'; |
135 | | - // Register article save hook |
136 | | - $wgHooks['ArticleSave'][] = __CLASS__ . '::updateArticleUsage'; |
137 | 136 | |
138 | 137 | } |
139 | 138 | |
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 ) { |
| 139 | + public static function renderScale( |
| 140 | + $input, |
| 141 | + $args, |
| 142 | + $parser |
| 143 | + ) { |
189 | 144 | global $wgUser, $wgTitle; |
190 | 145 | global $egCommunityVoiceResourcesPath; |
| 146 | + // Disable caching |
| 147 | + $parser->disableCache(); |
191 | 148 | // Validate and sanitize incoming arguments |
192 | 149 | $errors = array(); |
193 | 150 | $error = false; |
— | — | @@ -195,11 +152,9 @@ |
196 | 153 | $args[$argument] = htmlspecialchars( $args[$argument] ); |
197 | 154 | } else { |
198 | 155 | $error = true; |
199 | | - if ( $parser->getOptions()->getIsPreview() ) { |
200 | | - $errors[] = CommunityVoice::getMessage( |
201 | | - 'ratings', 'error-missing-argument', $argument |
202 | | - ); |
203 | | - } |
| 156 | + $errors[] = CommunityVoice::getMessage( |
| 157 | + 'ratings', 'error-missing-argument', $argument |
| 158 | + ); |
204 | 159 | } |
205 | 160 | } |
206 | 161 | // Checks if an error ocurred |
— | — | @@ -235,8 +190,13 @@ |
236 | 191 | // Adds content of tag as parsed wiki-text |
237 | 192 | $htmlOut .= $parser->recursiveTagParse( $input ); |
238 | 193 | } |
239 | | - // Checks if the user has not voted yet and is logged in |
240 | | - if ( !$userVoted && $wgUser->isLoggedIn() ) { |
| 194 | + // Checks if... |
| 195 | + if ( |
| 196 | + // User has not voted yet |
| 197 | + !$userVoted && |
| 198 | + // User is logged in |
| 199 | + $wgUser->isLoggedIn() |
| 200 | + ) { |
241 | 201 | |
242 | 202 | /* Ajax Interaction */ |
243 | 203 | |
— | — | @@ -311,7 +271,7 @@ |
312 | 272 | $htmlOut .= Html::input( |
313 | 273 | array( |
314 | 274 | 'type' => 'image', |
315 | | - 'name' => 'scale[rating_' . $i . ']', |
| 275 | + 'name' => 'scale[rating_' . ( $i + 1 ) . ']', |
316 | 276 | 'src' => sprintf( |
317 | 277 | '%s/Icons/star-%d.png', |
318 | 278 | $egCommunityVoiceResourcesPath, |
— | — | @@ -366,7 +326,12 @@ |
367 | 327 | /** |
368 | 328 | * Hanlder for ratings scale vote via ajax call |
369 | 329 | */ |
370 | | - public static function handleScaleVoteCall( $category, $title, $rating, $article ) { |
| 330 | + public static function handleScaleVoteCall( |
| 331 | + $category, |
| 332 | + $title, |
| 333 | + $rating, |
| 334 | + $article |
| 335 | + ) { |
371 | 336 | global $wgUser; |
372 | 337 | // Adds vote and checks for success |
373 | 338 | if ( self::addVote( $category, $title, $rating ) ) { |
— | — | @@ -384,13 +349,6 @@ |
385 | 350 | ) |
386 | 351 | ), |
387 | 352 | ); |
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 | 353 | // Ensure database commits take place (since this is an ajax call) |
396 | 354 | $dbw = wfGetDB( DB_MASTER ); |
397 | 355 | $dbw->commit(); |
— | — | @@ -437,15 +395,6 @@ |
438 | 396 | $scale['category'], $scale['title'], $rating |
439 | 397 | ) |
440 | 398 | ) { |
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 | 399 | // Redirects user back to article |
451 | 400 | $wgOut->redirect( |
452 | 401 | Title::newFromText( $scale['article'] )->getFullUrl() |
— | — | @@ -466,13 +415,15 @@ |
467 | 416 | /** |
468 | 417 | * Outputs a summary UI for the module |
469 | 418 | */ |
470 | | - public static function showSummary() { |
| 419 | + public static function showSummary( |
| 420 | + $path |
| 421 | + ) { |
471 | 422 | global $wgOut; |
472 | 423 | // |
473 | 424 | $wgOut->addWikiText( '==== Categories ====' ); |
474 | 425 | $xmlCategories = Html::open( 'ul' ); |
475 | 426 | foreach ( self::getCategories() as $category ) { |
476 | | - $xmlCategories .= Html::tag( 'li', $category ); |
| 427 | + $xmlCategories .= Html::tag( 'li', array(), $category ); |
477 | 428 | } |
478 | 429 | $xmlCategories .= Html::close( 'ul' ); |
479 | 430 | $wgOut->addHtml( $xmlCategories ); |
— | — | @@ -481,7 +432,9 @@ |
482 | 433 | /** |
483 | 434 | * Outputs main UI for module |
484 | 435 | */ |
485 | | - public static function showMain( $path ) { |
| 436 | + public static function showMain( |
| 437 | + $path |
| 438 | + ) { |
486 | 439 | global $wgOut; |
487 | 440 | // |
488 | 441 | $wgOut->addWikiText( '==== Detailed Information ====' ); |
Index: trunk/extensions/CommunityVoice/CommunityVoice.page.php |
— | — | @@ -61,10 +61,10 @@ |
62 | 62 | // Breaks sub into path steps |
63 | 63 | $path = explode( '/', $sub ); |
64 | 64 | // Checks if a specific module was given |
65 | | - if ( count( $path ) > 0 ) { |
| 65 | + if ( count( $path ) >= 1 && $path[0] != '' ) { |
66 | 66 | // Calls specific action on module |
67 | 67 | CommunityVoice::callModuleAction( |
68 | | - $path[0], 'show', count( $path ) >= 2 ? $path[1] : 'Main' |
| 68 | + $path[0], 'show', count( $path ) >= 2 ? $path[1] : 'Main', $path |
69 | 69 | ); |
70 | 70 | // Finishes page |
71 | 71 | return true; |
— | — | @@ -73,10 +73,10 @@ |
74 | 74 | foreach ( CommunityVoice::getModules() as $module ) { |
75 | 75 | // Adds heading |
76 | 76 | $wgOut->addWikiText( |
77 | | - '== ' . wfMsg( 'communityvoice-' . $module ) . ' ==' |
| 77 | + '== ' . wfMsg( 'communityvoice-' . strtolower( $module ) ) . ' ==' |
78 | 78 | ); |
79 | 79 | // Calls summary action on module |
80 | | - self::callModuleAction( $module, 'show', 'Summary' ); |
| 80 | + CommunityVoice::callModuleAction( $module, 'show', 'Summary', $path ); |
81 | 81 | } |
82 | 82 | // Finishes page |
83 | 83 | return true; |