Index: trunk/extensions/Maintenance/Maintenance_body.php |
— | — | @@ -9,7 +9,7 @@ |
10 | 10 | static $scripts = array( |
11 | 11 | 'changePassword', 'createAndPromote', 'deleteBatch', 'deleteRevision', |
12 | 12 | 'initEditCount', 'initStats', 'moveBatch', 'runJobs', 'showJobs', 'stats', |
13 | | - 'sql', 'eval', |
| 13 | + 'sql', 'eval', 'reassignEdits', |
14 | 14 | ); |
15 | 15 | |
16 | 16 | /** |
— | — | @@ -121,6 +121,13 @@ |
122 | 122 | $wgOut->addHTML('<textarea name="wpMove" rows="25" cols="80"></textarea><br /><br />'); |
123 | 123 | $wgOut->addHTML( Xml::inputLabel( wfMsg( 'maintenance-reason' ), 'wpReason', 'wpReason', '60', false, array( 'maxlength' => 200 ) ) . '<br /><br />' ); |
124 | 124 | break; |
| 125 | + case 'reassignEdits': |
| 126 | + $wgOut->addHTML( Xml::inputLabel( wfMsg( 'maintenance-re-from' ), 'wpFrom', 'wpFrom', '60' ) . '<br /><br />' ); |
| 127 | + $wgOut->addHTML( Xml::inputLabel( wfMsg( 'maintenance-re-to' ), 'wpTo', 'wpTo', '60' ) . '<br /><br />' ); |
| 128 | + $wgOut->addHTML( Xml::checkLabel( wfMsg( 'maintenance-re-force' ), 'wpForce', 'wpForce' ) . '<br /><br />' ); |
| 129 | + $wgOut->addHTML( Xml::checkLabel( wfMsg( 'maintenance-re-rc' ), 'wpRc', 'wpRc' ) . '<br /><br />' ); |
| 130 | + $wgOut->addHTML( Xml::checkLabel( wfMsg( 'maintenance-re-report' ), 'wpReport', 'wpReport' ) . '<br /><br />' ); |
| 131 | + break; |
125 | 132 | case 'runJobs': |
126 | 133 | //just hit the button to start this, no additional settings are needed :) |
127 | 134 | break; |
— | — | @@ -389,6 +396,68 @@ |
390 | 397 | } |
391 | 398 | $wgOut->addWikiMsg( 'maintenance-success', $type ); |
392 | 399 | break; |
| 400 | + case 'reassignEdits': |
| 401 | + $wpFrom = $wgRequest->getVal( 'wpFrom' ); |
| 402 | + $wpTo = $wgRequest->getVal( 'wpTo' ); |
| 403 | + if( User::isIP( $wpFrom ) ) { |
| 404 | + $from = new User(); |
| 405 | + $from->setId( 0 ); |
| 406 | + $from->setName( $wpFrom ); |
| 407 | + } else { |
| 408 | + $from = User::newFromName( $wpFrom ); |
| 409 | + } |
| 410 | + if( User::isIP( $wpTo ) ) { |
| 411 | + $to = new User(); |
| 412 | + $to->setId( 0 ); |
| 413 | + $to->setName( $wpTo ); |
| 414 | + } else { |
| 415 | + $to = User::newFromName( $wpTo ); |
| 416 | + } |
| 417 | + if( $to->getId() || $wgRequest->getCheck( 'wpForce' ) ) { |
| 418 | + $report = $wgRequest->getCheck( 'wpReport' ); |
| 419 | + $dbw = wfGetDB( DB_MASTER ); |
| 420 | + $dbw->immediateBegin(); |
| 421 | + $rcond = $from->getId() ? array( 'rev_user' => $from->getId() ) : array( 'rev_user_text' => $from->getName() ); |
| 422 | + $res = $dbw->select( 'revision', 'COUNT(*) AS count', $rcond, 'Maintenance::reassignEdits' ); |
| 423 | + $row = $dbw->fetchObject( $res ); |
| 424 | + $cur = $row->count; |
| 425 | + $wgOut->addWikiMsg( 'maintenance-re-ce', $cur ); |
| 426 | + $acond = $from->getId() ? array( 'ar_user' => $from->getId() ) : array( 'ar_user_text' => $from->getName() ); |
| 427 | + $res = $dbw->select( 'archive', 'COUNT(*) AS count', $acond, 'Maintenance::reassignEdits' ); |
| 428 | + $row = $dbw->fetchObject( $res ); |
| 429 | + $del = $row->count; |
| 430 | + $wgOut->addWikiMsg( 'maintenance-re-de', $del ); |
| 431 | + if( !$wgRequest->getCheck( 'wpRc' ) ) { |
| 432 | + $ccond = $from->getId() ? array( 'rc_user' => $from->getId() ) : array( 'rc_user_text' => $from->getName() ); |
| 433 | + $res = $dbw->select( 'recentchanges', 'COUNT(*) AS count', $ccond, 'Maintenance::reassignEdits' ); |
| 434 | + $row = $dbw->fetchObject( $res ); |
| 435 | + $rec = $row->count; |
| 436 | + $wgOut->addWikiMsg( 'maintenance-re-rce', $rec ); |
| 437 | + } else { |
| 438 | + $rec = 0; |
| 439 | + } |
| 440 | + $total = $cur + $del + $rec; |
| 441 | + $wgOut->addWikiMsg( 'maintenance-re-total', $total ); |
| 442 | + if( !$report ) { |
| 443 | + $rspec = array( 'rev_user' => $to->getId(), 'rev_user_text' => $to->getName() ); |
| 444 | + $res = $dbw->update( 'revision', $rspec, $rcond, 'Maintenance::reassignEdits' ); |
| 445 | + $aspec = array( 'ar_user' => $to->getId(), 'ar_user_text' => $to->getName() ); |
| 446 | + $res = $dbw->update( 'archive', $aspec, $acond, 'Maintenance::reassignEdits' ); |
| 447 | + if( !$wgRequest->getCheck( 'wpRc' ) ) { |
| 448 | + $cspec = array( 'rc_user' => $to->getId(), 'rc_user_text' => $to->getName() ); |
| 449 | + $res = $dbw->update( 'recentchanges', $cspec, $ccond, 'Maintenance::reassignEdits' ); |
| 450 | + } |
| 451 | + } |
| 452 | + $dbw->immediateCommit(); |
| 453 | + if( $report ) { |
| 454 | + $wgOut->addWikiMsg( 'maintenance-re-rr', wfMsg( 'maintenance-re-report' ) ); |
| 455 | + } |
| 456 | + } else { |
| 457 | + $ton = $to->getName(); |
| 458 | + $wgOut->addWikiMsg( 'maintenance-re-nf', $ton ); |
| 459 | + } |
| 460 | + $wgOut->addWikiMsg( 'maintenance-success', $type ); |
| 461 | + break; |
393 | 462 | case 'runJobs': |
394 | 463 | $maxJobs = 10000; |
395 | 464 | $dbw = wfGetDB( DB_MASTER ); |
— | — | @@ -533,4 +602,6 @@ |
534 | 603 | list( $host, $lag ) = $lb->getMaxLag(); |
535 | 604 | } |
536 | 605 | } |
537 | | -} |
\ No newline at end of file |
| 606 | +} |
| 607 | + |
| 608 | +// Helper classes |
Index: trunk/extensions/Maintenance/Maintenance.i18n.php |
— | — | @@ -12,11 +12,15 @@ |
13 | 13 | * @author Ryan Schmidt |
14 | 14 | */ |
15 | 15 | $messages['en'] = array( |
| 16 | + // special page text |
16 | 17 | 'maintenance' => 'Run maintenance scripts', |
| 18 | + // description |
17 | 19 | 'maintenance-desc' => '[[Special:Maintenance|Wiki interface]] for various maintenance scripts', |
| 20 | + // main form |
18 | 21 | 'maintenance-backlink' => 'Back to script selection', |
19 | 22 | 'maintenance-header' => 'Please select a script below to execute. |
20 | 23 | Descriptions are next to each script', |
| 24 | + // script descriptions |
21 | 25 | 'maintenance-changePassword-desc' => "Change a user's password", |
22 | 26 | 'maintenance-createAndPromote-desc' => 'Create a user and promote to sysop status', |
23 | 27 | 'maintenance-deleteBatch-desc' => 'Mass-delete pages', |
— | — | @@ -25,45 +29,71 @@ |
26 | 30 | 'maintenance-initEditCount-desc' => 'Recalculate the edit counts of users', |
27 | 31 | 'maintenance-initStats-desc' => 'Recalculate site statistics', |
28 | 32 | 'maintenance-moveBatch-desc' => 'Mass-move pages', |
| 33 | + 'maintenance-reassignEdits-desc' => 'Reassign edits from one user to another', |
29 | 34 | 'maintenance-runJobs-desc' => 'Run jobs in the job queue', |
30 | 35 | 'maintenance-showJobs-desc' => 'Show a list of jobs pending in the job queue', |
31 | 36 | 'maintenance-sql-desc' => 'Execute an SQL query', |
32 | 37 | 'maintenance-stats-desc' => 'Show Memcached statistics', |
| 38 | + // changePassword |
33 | 39 | 'maintenance-changePassword' => "Use this form to change a user's password", |
| 40 | + // createAndPromote |
34 | 41 | 'maintenance-createAndPromote' => 'Use this form to create a new user and promote it to sysop. |
35 | 42 | Check the bureaucrat box if you wish to promote to bureaucrat as well', |
| 43 | + // deleteBatch |
36 | 44 | 'maintenance-deleteBatch' => 'Use this form to mass-delete pages. |
37 | 45 | Put only one page per line', |
| 46 | + // deleteRevision |
38 | 47 | 'maintenance-deleteRevision' => 'Use this form to mass-delete revisions. |
39 | 48 | Put only one revision number per line', |
| 49 | + // initEditCount |
40 | 50 | 'maintenance-initEditCount' => '', |
| 51 | + // initStats |
41 | 52 | 'maintenance-initStats' => 'Use this form to recalculate site statistics, specifiying if you want to recalculate page views as well', |
| 53 | + // moveBatch |
42 | 54 | 'maintenance-moveBatch' => 'Use this form to mass-move pages. |
43 | 55 | Each line should specify a source page and destination page separated by a pipe', |
| 56 | + // runJobs |
44 | 57 | 'maintenance-runJobs' => '', |
| 58 | + // showJobs |
45 | 59 | 'maintenance-showJobs' => '', |
| 60 | + // stats |
46 | 61 | 'maintenance-stats' => '', |
| 62 | + // invalid type |
47 | 63 | 'maintenance-invalidtype' => 'Invalid type!', |
| 64 | + // changePassword + createAndPromote |
48 | 65 | 'maintenance-name' => 'Username', |
49 | 66 | 'maintenance-password' => 'Password', |
| 67 | + // createAndPromote |
50 | 68 | 'maintenance-bureaucrat' => 'Promote user to bureaucrat status', |
| 69 | + // deleteBatch, moveBatch, etc. |
51 | 70 | 'maintenance-reason' => 'Reason', |
| 71 | + // initStats |
52 | 72 | 'maintenance-update' => 'Use UPDATE when updating a table? Unchecked uses DELETE/INSERT instead.', |
53 | 73 | 'maintenance-noviews' => 'Check this to prevent updating the number of pageviews', |
| 74 | + // all scripts |
54 | 75 | 'maintenance-confirm' => 'Confirm', |
| 76 | + // createAndPromote, perhaps others |
55 | 77 | 'maintenance-invalidname' => 'Invalid username!', |
| 78 | + // all scripts |
56 | 79 | 'maintenance-success' => '$1 ran successfully!', |
| 80 | + // createAndPromote |
57 | 81 | 'maintenance-userexists' => 'User already exists!', |
| 82 | + // deleteBatch, moveBatch, perhaps others |
58 | 83 | 'maintenance-invalidtitle' => 'Invalid title "$1"!', |
| 84 | + // deleteBatch, moveBatch, perhaps others |
59 | 85 | 'maintenance-titlenoexist' => 'Title specified ("$1") does not exist!', |
| 86 | + // unsure |
60 | 87 | 'maintenance-failed' => 'FAILED', |
61 | 88 | 'maintenance-deleted' => 'DELETED', |
| 89 | + // deleteRevisions |
62 | 90 | 'maintenance-revdelete' => 'Deleting revisions $1 from wiki $2', |
63 | 91 | 'maintenance-revnotfound' => 'Revision $1 not found!', |
| 92 | + // sql |
64 | 93 | 'maintenance-sql' => 'Use this form to execute a SQL query on the database.', |
65 | 94 | 'maintenance-sql-aff' => 'Affected rows: $1', |
66 | 95 | 'maintenance-sql-res' => '$1 {{PLURAL:$1|row|rows}} returned: |
67 | 96 | $2', |
| 97 | + // stats |
68 | 98 | 'maintenance-stats-edits' => 'Number of edits: $1', |
69 | 99 | 'maintenance-stats-articles' => 'Number of pages in the main namespace: $1', |
70 | 100 | 'maintenance-stats-pages' => 'Number of pages: $1', |
— | — | @@ -72,10 +102,13 @@ |
73 | 103 | 'maintenance-stats-images' => 'Number of files: $1', |
74 | 104 | 'maintenance-stats-views' => 'Number of pageviews: $1', |
75 | 105 | 'maintenance-stats-update' => 'Updating database...', |
| 106 | + // moveBatch |
76 | 107 | 'maintenance-move' => 'Moving $1 to $2...', |
77 | 108 | 'maintenance-movefail' => 'Error encountered while moving: $1. |
78 | 109 | Aborting move', |
| 110 | + // unsure |
79 | 111 | 'maintenance-error' => 'Error: $1', |
| 112 | + // stats |
80 | 113 | 'maintenance-memc-fake' => 'You are running FakeMemCachedClient. No statistics can be provided', |
81 | 114 | 'maintenance-memc-requests' => 'Requests', |
82 | 115 | 'maintenance-memc-withsession' => 'with session:', |
— | — | @@ -92,7 +125,22 @@ |
93 | 126 | 'maintenance-memc-updates' => 'updates:', |
94 | 127 | 'maintenance-memc-uncacheable' => 'uncacheable:', |
95 | 128 | 'maintenance-memc-diffcache' => 'Diff Cache', |
| 129 | + // eval |
96 | 130 | 'maintenance-eval' => 'Use this form to evaluate PHP code in the MediaWiki environment.', |
| 131 | + // reassignEdits |
| 132 | + 'maintenance-reassignEdits' => 'Use this form to reassign edits from one user to another.', |
| 133 | + 'maintenance-re-from' => 'Name of the user to assign edits from', |
| 134 | + 'maintenance-re-to' => 'Name of the user to assign edits to', |
| 135 | + 'maintenance-re-force' => 'Reassign even if the target user doesn\'t exist', |
| 136 | + 'maintenance-re-rc' => 'Don\'t update the recent changes table', |
| 137 | + 'maintenance-re-report' => 'Print out details of what would be changed, but don\'t update it', |
| 138 | + 'maintenance-re-nf' => 'User $1 not found', |
| 139 | + 'maintenance-re-rr' => 'Run the script again without "$1" to update.', |
| 140 | + 'maintenance-re-ce' => 'Current edits: $1', |
| 141 | + 'maintenance-re-de' => 'Deleted edits: $1', |
| 142 | + 'maintenance-re-rce' => 'RecentChanges entries: $1', |
| 143 | + 'maintenance-re-total' => 'Total entries to change: $1', |
| 144 | + 'maintenance-re-re' => 'Reassigning edits... done', |
97 | 145 | ); |
98 | 146 | |
99 | 147 | /** Message documentation (Message documentation) |
Index: trunk/extensions/AmazonPlus/AmazonPlus.php |
— | — | @@ -47,7 +47,7 @@ |
48 | 48 | 'name' => 'AmazonPlus', |
49 | 49 | 'description' => 'A highly customizable extension to display Amazon information', |
50 | 50 | 'descriptionmsg' => 'amazonplus-desc', |
51 | | - 'version' => '0.2', |
| 51 | + 'version' => '0.3', |
52 | 52 | 'url' => 'http://www.mediawiki.org/wiki/Extension:AmazonPlus', |
53 | 53 | 'author' => 'Ryan Schmidt', |
54 | 54 | ); |
— | — | @@ -85,7 +85,7 @@ |
86 | 86 | function efAmazonPlusJavascript( &$out, $sk ) { |
87 | 87 | global $wgScriptPath; |
88 | 88 | $src = $wgScriptPath . '/extensions/AmazonPlus/AmazonPlus.js'; |
89 | | - $out->addScript( '<script type="text/javascript" src="' . $src . '"></script>' ); |
| 89 | + $out->addScript( '<script type="text/javascript" src="' . $src . '"></script>' . "\n" ); |
90 | 90 | return true; |
91 | 91 | } |
92 | 92 | |
— | — | @@ -113,7 +113,8 @@ |
114 | 114 | $ret = $am->getResult(); |
115 | 115 | $temp = $parser->mOptions->setAllowExternalImages( true ); |
116 | 116 | $ret = $parser->recursiveTagParse( $ret ); |
117 | | - $ret = str_replace( '%' . $am->getToken() . '%', $am->priceSelect(), $ret ); |
| 117 | + $ret = str_replace( '%' . $am->getToken( 'priceSelect' ) . '%', $am->priceSelect(), $ret ); |
| 118 | + $ret = str_replace( '%' . $am->getToken( 'shortReview' ) . '%', $am->shortReview(), $ret ); |
118 | 119 | $parser->mOptions->setAllowExternalImages( $temp ); |
119 | 120 | wfRestoreWarnings(); |
120 | 121 | return $ret; |
— | — | @@ -121,13 +122,13 @@ |
122 | 123 | |
123 | 124 | # Class for holding/parsing information from the Amazon REST interface |
124 | 125 | class AmazonPlus { |
125 | | - var $locale, $request, $response, $xml, $input, $error, $valid, $token, $title; |
| 126 | + var $locale, $request, $response, $xml, $input, $error, $valid, $token, $title, $shortReview; |
126 | 127 | |
127 | 128 | function __construct( $title, $args, $input ) { |
128 | 129 | global $wgAmazonPlusAWS, $wgAmazonPlusAssociates; |
129 | 130 | $this->valid = array( 'us', 'gb', 'ca', 'de', 'fr', 'jp' ); |
130 | 131 | $this->currencies = array(); |
131 | | - $this->token = rand(); |
| 132 | + $this->token = array( 'priceSelect' => rand() . '1', 'shortReview' => rand() . '2' ); |
132 | 133 | if ( isset( $args['locale'] ) ) { |
133 | 134 | $this->locale = ( $this->validLocale( $args['locale'] ) ) ? $args['locale'] : 'us'; |
134 | 135 | } else { |
— | — | @@ -157,7 +158,7 @@ |
158 | 159 | |
159 | 160 | function setValue( $key, $value ) { $this->request[$key] = $value; } |
160 | 161 | function getValue( $key ) { return $this->request[$key]; } |
161 | | - function getToken() { return $this->token; } |
| 162 | + function getToken( $key ) { return $this->token[$key]; } |
162 | 163 | function getLocale() { return $this->locale; } |
163 | 164 | |
164 | 165 | function getId( $title, $args ) { |
— | — | @@ -230,12 +231,13 @@ |
231 | 232 | 'swatchimage' => $imageset->SwatchImage->URL, |
232 | 233 | 'thumbnail' => $imageset->ThumbnailImage->URL, |
233 | 234 | /* REVIEWS AND RATINGS */ |
234 | | - 'review' => $editorials->Content, |
| 235 | + 'editorialreview' => $editorials->Content, |
| 236 | + 'shortreview' => $this->shortReview( $editorials->Content ), |
235 | 237 | 'reviewlink' => $links['AllCustomerReviews'], |
236 | | - 'source' => $editorials->Source, |
| 238 | + 'editorialsource' => $editorials->Source, |
237 | 239 | 'rating' => $reviews->AverageRating, |
238 | 240 | 'stars' => $this->starsImage( $reviews->AverageRating ), |
239 | | - 'total' => $reviews->TotalReviews, |
| 241 | + 'totalreviews' => $reviews->TotalReviews, |
240 | 242 | /* PRICES */ |
241 | 243 | 'price' => $this->formatPrice( $item, AMAZONPLUS_ALL ), |
242 | 244 | 'price-amazon' => $this->formatPrice( $item, AMAZONPLUS_AMAZON ), |
— | — | @@ -265,7 +267,7 @@ |
266 | 268 | 'price-de-used' => $this->getPrice( 'de', $item->ASIN, AMAZONPLUS_USED ), |
267 | 269 | 'price-jp-used' => $this->getPrice( 'jp', $item->ASIN, AMAZONPLUS_USED ), |
268 | 270 | 'price-fr-used' => $this->getPrice( 'fr', $item->ASIN, AMAZONPLUS_USED ), |
269 | | - 'compare' => '%' . $this->token . '%', |
| 271 | + 'compare' => '%' . $this->token['priceSelect'] . '%', |
270 | 272 | 'offers' => $links['AllOffers'], |
271 | 273 | /* DETAILS */ |
272 | 274 | 'url' => $item->DetailPageURL, |
— | — | @@ -311,6 +313,38 @@ |
312 | 314 | $pieces = explode( '-', $date ); |
313 | 315 | return $pieces[$segment]; |
314 | 316 | } |
| 317 | + |
| 318 | + function shortReview( $rev ) { |
| 319 | + // return the first 3 paragraphs and have a more/less link afterwards |
| 320 | + if( !$this->shortReview ) { |
| 321 | + $rev = str_replace( '<br>', '<br />', $rev ); |
| 322 | + $paras = explode( '<br />', $rev ); |
| 323 | + switch( count( $paras ) ) { |
| 324 | + case 1: |
| 325 | + $this->shortReview = $rev; |
| 326 | + case 2: |
| 327 | + $this->shortReview = $rev; |
| 328 | + case 3: |
| 329 | + $this->shortReview = $rev; |
| 330 | + default: |
| 331 | + $head = implode( '<br />', array( $paras[0], $paras[1], $paras[2] ) ); |
| 332 | + $html = '<div class="shortReviewFrame" id="shortReviewFrame' . ++$this->src . '">'; |
| 333 | + $html .= '<div class="shortReviewHead">' . $head . '</div>'; |
| 334 | + $html .= '<div class="shortReviewBody" style="display: none">'; |
| 335 | + for( $i = 3; $i < count( $paras ); $i++ ) { |
| 336 | + $html .= '<br />' . $paras[$i]; |
| 337 | + } |
| 338 | + $more = wfMsg( 'amazonplus-more' ); |
| 339 | + $less = wfMsg( 'amazonplus-less' ); |
| 340 | + $internal = "'{$more}', '{$less}', '{$this->src}'"; |
| 341 | + $id = 'shortReviewLink' . $this->src; |
| 342 | + $html .= '</div> [<a href="#" id="' . $id . '" onclick="javascript:toggleReview(' . $internal . ');">' . $more . '</a>]</div>'; |
| 343 | + $this->shortReview = $html; |
| 344 | + } |
| 345 | + return '%' . $this->token['shortReview'] . '%'; |
| 346 | + } |
| 347 | + return $this->shortReview; |
| 348 | + } |
315 | 349 | |
316 | 350 | function getPrice( $loc, $asin, $type ) { |
317 | 351 | # if it isn't in the input, then don't do the query to save time |
Index: trunk/extensions/AmazonPlus/AmazonPlus.js |
— | — | @@ -1,3 +1,21 @@ |
2 | 2 | function convertPrices() { |
3 | | - return; |
| 3 | + return; //not yet implemented |
4 | 4 | } |
| 5 | + |
| 6 | +function toggleReview(more, less, id) { |
| 7 | + var e = document.getElementById( 'shortReviewFrame' + id ); |
| 8 | + if( !e ) return; |
| 9 | + var a = document.getElementById( 'shortReviewLink' + id ); |
| 10 | + if( !a ) return; |
| 11 | + var b = getElementsByClassName( e, 'div', 'shortReviewBody' ); |
| 12 | + if( !b || !b[0] ) return; |
| 13 | + b = b[0]; |
| 14 | + d = b.style.display; |
| 15 | + if( d == 'block' ) { |
| 16 | + b.style.display = 'none'; |
| 17 | + a.innerHTML = more; |
| 18 | + } else if( d == 'none' ) { |
| 19 | + b.style.display = 'block'; |
| 20 | + a.innerHTML = less; |
| 21 | + } |
| 22 | +} |
\ No newline at end of file |
Index: trunk/extensions/AmazonPlus/AmazonPlus.i18n.php |
— | — | @@ -8,6 +8,9 @@ |
9 | 9 | |
10 | 10 | $messages = array(); |
11 | 11 | |
| 12 | +/** English (English) |
| 13 | + * @author Skizzerz |
| 14 | + */ |
12 | 15 | $messages['en'] = array( |
13 | 16 | 'amazonplus-desc' => 'A highly customizable extension to display Amazon information', |
14 | 17 | 'amazonplus-nores' => 'Error: No results found!', |
— | — | @@ -31,13 +34,31 @@ |
32 | 35 | 'amazonplus-cp-gbp' => 'GBP', |
33 | 36 | 'amazonplus-cp-eur' => 'EUR', |
34 | 37 | 'amazonplus-cp-jpy' => 'JPY', |
| 38 | + 'amazonplus-more' => 'more', |
| 39 | + 'amazonplus-less' => 'less', |
35 | 40 | ); |
36 | 41 | |
37 | 42 | /** Message documentation (Message documentation) |
| 43 | + * @author Skizzerz |
38 | 44 | * @author Purodha |
39 | 45 | */ |
40 | 46 | $messages['qqq'] = array( |
41 | | - 'amazonplus-desc' => 'A short description of this extension. Shown in [[Special:Version]]. Do not translate links.', |
| 47 | + 'amazonplus-desc' => 'Short description of this extension, shown on [[Special:Version]]. Do not translate or change links.', |
| 48 | + 'amazonplus-nores' => 'Error message, automatically wrapped in a span tag with class="error."', |
| 49 | + 'amazonplus-noidres' => 'Error message, automatically wrapped in a span tag with class="error."', |
| 50 | + 'amazonplus-fgcerr' => 'Error message, automatically wrapped in a span tag with class="error."', |
| 51 | + 'amazonplus-slserr' => 'Error message, automatically wrapped in a span tag with class="error."', |
| 52 | + 'amazonplus-used' => 'Definition of "used" in this message is "not new."', |
| 53 | + 'amazonplus-german' => 'Name of the German language, or an empty string if translating to German.', |
| 54 | + 'amazonplus-french' => 'Name of the French language, or an empty string if translating to French.', |
| 55 | + 'amazonplus-japanese' => 'Name of the Japanese language, or an empty string if translating to Japanese.', |
| 56 | + 'amazonplus-english' => 'Name of the English language, or an empty string if translating to English.', |
| 57 | + 'amazonplus-status' => ';$1:A combination of status messages seperated with [[MediaWiki:Amazonplus-status-sep/en|amazonplus-status-sep]]', |
| 58 | + 'amazonplus-status-sep' => 'Seperator used in [[MediaWiki:Amazonplus-status/en|amazonplus-status]] to divide the listing of terms', |
| 59 | + 'amazonplus-currency' => ';$1:Formatted price without symbol (e.g. 16.41) |
| 60 | +;$2:Currency code (e.g. USD) |
| 61 | +;$3:Currency symbol (e.g. $) |
| 62 | +;$4:Status message', |
42 | 63 | ); |
43 | 64 | |
44 | 65 | /** Arabic (العربية) |
Index: trunk/extensions/JSKit/JSKit.i18n.php |
— | — | @@ -0,0 +1,20 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Internationalisation file for extension AbsenteeLandlord. |
| 5 | + * |
| 6 | + * @addtogroup Extensions |
| 7 | +*/ |
| 8 | + |
| 9 | +/** English (English) |
| 10 | + * @author Skizzerz |
| 11 | + */ |
| 12 | +$messages['en'] = array( |
| 13 | + 'jskit-desc' => 'Integrates js-kit tools onto a wiki page', |
| 14 | +); |
| 15 | + |
| 16 | +/** Message documentation (Message documentation) |
| 17 | + * @author Skizzerz |
| 18 | + */ |
| 19 | +$messages['qqq'] = array( |
| 20 | + 'jskit-desc' => 'Short description of this extension, shown on [[Special:Version]]. Do not translate or change links.', |
| 21 | +); |
\ No newline at end of file |
Property changes on: trunk/extensions/JSKit/JSKit.i18n.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 22 | + native |
Index: trunk/extensions/JSKit/JSKit.php |
— | — | @@ -0,0 +1,223 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +/** |
| 5 | + * JSKit extension for MediaWiki -- integrates js-kit tools onto a wiki page |
| 6 | + * Documentation is available at http://www.mediawiki.org/wiki/Extension:JSKit |
| 7 | + * |
| 8 | + * Copyright (c) 2008 Ryan Schmidt (Skizzerz) |
| 9 | + * |
| 10 | + * This program is free software; you can redistribute it and/or modify |
| 11 | + * it under the terms of the GNU General Public License as published by |
| 12 | + * the Free Software Foundation; either version 2 of the License, or |
| 13 | + * (at your option) any later version. |
| 14 | + * |
| 15 | + * This program is distributed in the hope that it will be useful, |
| 16 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 17 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 18 | + * GNU General Public License for more details. |
| 19 | + * |
| 20 | + * You should have received a copy of the GNU General Public License along |
| 21 | + * with this program; if not, write to the Free Software Foundation, Inc., |
| 22 | + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 23 | + * http://www.gnu.org/copyleft/gpl.html |
| 24 | + */ |
| 25 | + |
| 26 | +if(!defined('MEDIAWIKI')) { |
| 27 | + echo 'Not an entry point'; |
| 28 | + die(1); |
| 29 | +} |
| 30 | + |
| 31 | +$wgExtensionCredits['other'][] = array( |
| 32 | + 'name' => 'JSKit', |
| 33 | + 'description' => 'Integrates js-kit tools onto a wiki page', |
| 34 | + 'descriptionmsg' => 'jskit-desc', |
| 35 | + 'version' => '0.1', |
| 36 | + 'author' => 'Ryan Schmidt', |
| 37 | +); |
| 38 | + |
| 39 | +$wgHooks['OutputPageBeforeHTML'][] = 'efJSKit'; |
| 40 | +if ( defined( 'MW_SUPPORTS_PARSERFIRSTCALLINIT' ) ) { |
| 41 | + $wgHooks['ParserFirstCallInit'][] = 'efJSKitSetup'; |
| 42 | +} else { |
| 43 | + $wgExtensionFunctions[] = 'efJSKitSetup'; |
| 44 | +} |
| 45 | + |
| 46 | +$wgExtensionMessagesFiles['JSKit'] = dirname(__FILE__) . '/JSKit.i18n.php'; |
| 47 | + |
| 48 | +$wgJSKitTypes = array( |
| 49 | + 'navigator' => true, // Enables the js-kit Navigator on pages -- see http://js-kit.com/navigator/ for more information |
| 50 | + 'ratings' => true, // Enables the js-kit Ratings on pages -- see http://js-kit.com/ratings/ for more information |
| 51 | + 'polls' => true, // Enables the js-kit Polls on pages -- see http://js-kit.com/polls/ for more information |
| 52 | + 'comments' => true, // Enables the js-kit Comments on pages -- see http://js-kit.com/comments/ for more information |
| 53 | + 'reviews' => true, // Enables the js-kit Reviews on pages -- see http://js-kit.com/reviews/ for more information |
| 54 | +); |
| 55 | + |
| 56 | +$wgJSKitNamespaces = array( NS_MAIN => true ); // Namespaces on which we want to be able to use the js-kit services |
| 57 | + |
| 58 | +$wgJSKitAlways = ''; // Should we always display something at the bottom of the page (in the namespaces above)? |
| 59 | + |
| 60 | +# Sets up the tag functions |
| 61 | +function efJSKitSetup() { |
| 62 | + global $wgParser, $wgJSKitTypes; |
| 63 | + if( $wgJSKitTypes['navigator'] ) { |
| 64 | + $wgParser->setHook( 'top', 'efJSKitTop' ); |
| 65 | + } |
| 66 | + if( $wgJSKitTypes['ratings'] ) { |
| 67 | + $wgParser->setHook( 'rating', 'efJSKitRating' ); |
| 68 | + } |
| 69 | + if( $wgJSKitTypes['polls'] ) { |
| 70 | + $wgParser->setHook( 'poll', 'efJSKitPoll' ); |
| 71 | + } |
| 72 | + if( $wgJSKitTypes['comments'] ) { |
| 73 | + $wgParser->setHook( 'comment', 'efJSKitComment' ); |
| 74 | + } |
| 75 | + if( $wgJSKitTypes['reviews'] ) { |
| 76 | + $wgParser->setHook( 'review', 'efJSKitReview' ); |
| 77 | + } |
| 78 | + wfLoadExtensionMessages( 'JSKit' ); |
| 79 | + return true; |
| 80 | +} |
| 81 | + |
| 82 | +# Wrapper to get the Navigator service |
| 83 | +function efJSKitTop( $input, $args, $parser ) { |
| 84 | + return efJSKitRender( $input, $args, $parser, 'top' ); |
| 85 | +} |
| 86 | + |
| 87 | +#Wrapper to get the Rating service |
| 88 | +function efJSKitRating( $input, $args, $parser ) { |
| 89 | + return efJSKitRender( $input, $args, $parser, 'rating' ); |
| 90 | +} |
| 91 | + |
| 92 | +# Wrapper to get the Poll service |
| 93 | +function efJSKitPoll( $input, $args, $parser ) { |
| 94 | + return efJSKitRender( $input, $args, $parser, 'poll' ); |
| 95 | +} |
| 96 | + |
| 97 | +# Wrapper to get the Comment service |
| 98 | +function efJSKitComment( $input, $args, $parser ) { |
| 99 | + return efJSKitRender( $input, $args, $parser, 'comment' ); |
| 100 | +} |
| 101 | + |
| 102 | +# Wrapper to get the Review service |
| 103 | +function efJSKitReview( $input, $args, $parser ) { |
| 104 | + return efJSKitRender( $input, $args, $parser, 'review' ); |
| 105 | +} |
| 106 | + |
| 107 | +# Main execution function for the tags |
| 108 | +function efJSKitRender( $input, $args, $parser, $type ) { |
| 109 | + $jsclass2 = false; |
| 110 | + switch( $type ) { |
| 111 | + case 'top': |
| 112 | + $jsclass = 'js-kit-top'; |
| 113 | + break; |
| 114 | + case 'rating': |
| 115 | + $jsclass = 'js-kit-rating'; |
| 116 | + break; |
| 117 | + case 'poll': |
| 118 | + $jsclass = 'js-kit-poll'; |
| 119 | + break; |
| 120 | + case 'comment': |
| 121 | + $jsclass = 'js-kit-comments'; |
| 122 | + break; |
| 123 | + case 'review': |
| 124 | + $jsclass = 'js-kit-rating'; |
| 125 | + $jsclass2 = 'js-kit-comments'; |
| 126 | + break; |
| 127 | + default: |
| 128 | + return ''; |
| 129 | + } |
| 130 | + $args['class'] = isset( $args['class'] ) ? $args['class'] : false; |
| 131 | + $args['style'] = isset( $args['style'] ) ? $args['style'] : false; |
| 132 | + $args['id'] = isset( $args['id'] ) ? $args['id'] : false; |
| 133 | + $class = $args['class'] ? 'class="' . $jsclass . ' ' . $args['class'] . '"' : 'class="' . $jsclass . '"'; |
| 134 | + $style = $args['style'] ? 'style="' . $args['style'] . '"' : ''; |
| 135 | + $id = $args['id'] ? 'id="' . $args['id'] . '"' : ''; |
| 136 | + $tag = "<div $id $class $style "; |
| 137 | + $parts = explode( "\n", $input ); |
| 138 | + foreach( $parts as $part ) { |
| 139 | + $pieces = explode( '=', $part, 2 ); |
| 140 | + if( count( $pieces ) != 2 ) |
| 141 | + continue; |
| 142 | + $tag .= $pieces[0] . '="'. $pieces[1] . '" '; |
| 143 | + } |
| 144 | + if( $type == 'rating' || $type == 'comment' ) { |
| 145 | + $tag .= 'standalone="yes" '; // if this is a rating/comment, force it standalone so it doesn't try to be a review |
| 146 | + } |
| 147 | + $tag .= '></div>'; |
| 148 | + if( $jsclass2 ) { |
| 149 | + // needs 2 tags, like in reviews |
| 150 | + $args['class2'] = isset( $args['class2'] ) ? $args['class2'] : false; |
| 151 | + $args['style2'] = isset( $args['style2'] ) ? $args['style2'] : false; |
| 152 | + $args['id2'] = isset( $args['id2'] ) ? $args['id2'] : false; |
| 153 | + $class2 = $args['class2'] ? 'class="' . $jsclass2 . ' ' . $args['class2'] . '"' : 'class="' . $jsclass2 . '"'; |
| 154 | + $style2 = $args['style2'] ? 'style="' . $args['style2'] . '"' : ''; |
| 155 | + $id2 = $args['id2'] ? 'id="' . $args['id2'] . '"' : ''; |
| 156 | + $tag2 = "<div $id2 $class2 $style2 "; |
| 157 | + // $parts is already defined above |
| 158 | + foreach( $parts as $part ) { |
| 159 | + $pieces = explode( '=', $part, 2 ); |
| 160 | + if( count( $pieces ) != 2 ) |
| 161 | + continue; |
| 162 | + $tag2 .= $pieces[0] . '="'. $pieces[1] . '" '; |
| 163 | + } |
| 164 | + $tag2 .= '></div>'; |
| 165 | + $tag .= $tag2; |
| 166 | + } |
| 167 | + return $tag . '__JSKIT-TYPE-' . $type . '__'; |
| 168 | +} |
| 169 | + |
| 170 | +# Appends the javascript |
| 171 | +function efJSKit(&$out, &$text) { |
| 172 | + global $wgJSKitNamespaces, $wgJSKitAlways, $wgTitle; |
| 173 | + $ns = $wgTitle->getNamespace(); |
| 174 | + if( !$wgTitle->getArticleId() ) { |
| 175 | + // special page or wrong namespace, so don't do anything |
| 176 | + return true; |
| 177 | + } |
| 178 | + if( strpos( $text, '__NOJSKIT__' ) !== false ) { |
| 179 | + // "magic word" to disable js-kit on a per-page basis |
| 180 | + $text = str_replace( '__NOJSKIT__', '', $text ); |
| 181 | + return true; |
| 182 | + } |
| 183 | + $always = ( strpos( $text, '__JSKIT-DISABLE-ALWAYS__' ) === false ); |
| 184 | + $wgJSKitAlways = preg_match( '/^(comment|review|rating)$/', $wgJSKitAlways ) ? $wgJSKitAlways : ''; |
| 185 | + if( strpos( $text, '__JSKIT__' ) === false ) { |
| 186 | + if( !array_key_exists($ns, $wgJSKitNamespaces) || !$wgJSKitNamespaces[$ns] ) { |
| 187 | + // not a namespace where JSKit is normally enabled |
| 188 | + return true; |
| 189 | + } elseif( $always ) { |
| 190 | + $text .= efJSKitRender( '', '', false, $wgJSKitAlways ); |
| 191 | + } |
| 192 | + } else { |
| 193 | + // "magic word" to enable js-kit on a per-page basis |
| 194 | + $text = str_replace( '__JSKIT__', '', $text ); |
| 195 | + if( $always ) { |
| 196 | + $text .= efJSKitRender( '', '', false, $wgJSKitAlways ); |
| 197 | + } |
| 198 | + } |
| 199 | + $text = str_replace( '__JSKIT-DISABLE-ALWAYS__', '', $text ); |
| 200 | + |
| 201 | + $sb = '<script type="text/javascript" src="http://js-kit.com/'; |
| 202 | + $se = '.js"></script>' . "\n"; |
| 203 | + if( strpos( $text, '__JSKIT-TYPE-top__' ) !== false ) { |
| 204 | + $text = str_replace( '__JSKIT-TYPE-top__', '', $text ); |
| 205 | + $text .= $sb . 'top' . $se; |
| 206 | + } |
| 207 | + if( strpos( $text, '__JSKIT-TYPE-rating__' ) !== false ) { |
| 208 | + $text = str_replace( '__JSKIT-TYPE-rating__', '', $text ); |
| 209 | + $text .= $sb . 'ratings' . $se; |
| 210 | + } |
| 211 | + if( strpos( $text, '__JSKIT-TYPE-poll__' ) !== false ) { |
| 212 | + $text = str_replace( '__JSKIT-TYPE-poll__', '', $text ); |
| 213 | + $text .= $sb . 'polls' . $se; |
| 214 | + } |
| 215 | + if( strpos( $text, '__JSKIT-TYPE-comment__' ) !== false ) { |
| 216 | + $text = str_replace( '__JSKIT-TYPE-comment__', '', $text ); |
| 217 | + $text .= $sb . 'comments' . $se; |
| 218 | + } |
| 219 | + if( strpos( $text, '__JSKIT-TYPE-review__' ) !== false ) { |
| 220 | + $text = str_replace( '__JSKIT-TYPE-review__', '', $text ); |
| 221 | + $text .= $sb . 'reviews' . $se; |
| 222 | + } |
| 223 | + return true; |
| 224 | +} |
\ No newline at end of file |
Property changes on: trunk/extensions/JSKit/JSKit.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 225 | + native |