Index: trunk/extensions/Contest/Contest.i18n.php |
— | — | @@ -20,6 +20,9 @@ |
21 | 21 | $messages['en'] = array( |
22 | 22 | 'contest-desc' => 'Contest extension that allows users to participate in admin defined contest challenges. Via a judging interface, judges can discuss and vote on submissions.', |
23 | 23 | |
| 24 | + // Misc |
| 25 | + 'contest-toplink' => 'My contests', |
| 26 | + |
24 | 27 | // Rights |
25 | 28 | 'right-contestadmin' => 'Manage contests', |
26 | 29 | 'right-contestparticipant' => 'Participate in contests', |
— | — | @@ -38,6 +41,10 @@ |
39 | 42 | 'group-contestjudge-member' => 'contest judge', |
40 | 43 | 'grouppage-contestjudge' => 'Project:Contest_judges', |
41 | 44 | |
| 45 | + // Preferences |
| 46 | + 'prefs-contest' => 'Contests', |
| 47 | + 'contest-prefs-showtoplink' => 'Show a link to [[Special:MyContests|My Contests]] in the top menue.', |
| 48 | + |
42 | 49 | // Contest statuses |
43 | 50 | 'contest-status-draft' => 'Draft (disabled)', |
44 | 51 | 'contest-status-active' => 'Active (enabled)', |
— | — | @@ -50,6 +57,7 @@ |
51 | 58 | 'special-contestsubmission' => 'Contest submission', |
52 | 59 | 'special-contestwelcome' => 'Contest', |
53 | 60 | 'special-editcontest' => 'Edit contest', |
| 61 | + 'special-mycontests' => 'Contests', |
54 | 62 | |
55 | 63 | // Navigation links |
56 | 64 | 'contest-nav-contests' => 'Contests list', |
— | — | @@ -182,9 +190,14 @@ |
183 | 191 | 'contest-email-reminder-title' => 'Only $1 {{PLURAL:$1|day|days}} until the end of the challenge!', |
184 | 192 | |
185 | 193 | // Special:MyContests |
| 194 | + 'contest-mycontests-toplink' => 'My contests', |
186 | 195 | 'contest-mycontests-no-contests' => 'You are not participating in any contest.', |
187 | 196 | 'contest-mycontests-active-header' => 'Running contests', |
188 | 197 | 'contest-mycontests-finished-header' => 'Passed contests', |
| 198 | + 'contest-mycontests-active-text' => 'These are the contests you are currently participating in.', |
| 199 | + 'contest-mycontests-finished-text' => 'These are the passed contests you have participated in.', |
| 200 | + 'contest-mycontests-header-contest' => 'Contest', |
| 201 | + 'contest-mycontests-header-challenge' => 'Challenge', |
189 | 202 | ); |
190 | 203 | |
191 | 204 | /** Message documentation (Message documentation) |
— | — | @@ -240,4 +253,10 @@ |
241 | 254 | // Emails |
242 | 255 | 'contest-email-signup-title' => 'Title for signup emails', |
243 | 256 | 'contest-email-reminder-title' => 'Title for reminder emails', |
| 257 | + |
| 258 | + // Special:MyContests |
| 259 | + 'contest-mycontests-toplink' => 'Text for link in the top menue (ie where watchlist and preferences are linked)', |
| 260 | + 'contest-mycontests-no-contests' => 'Message indicating there are no contests for the user, displayed instead of a list.', |
| 261 | + 'contest-mycontests-active-header' => 'Page header (h2)', |
| 262 | + 'contest-mycontests-finished-header' => 'Page header (h2)', |
244 | 263 | ); |
Index: trunk/extensions/Contest/Contest.hooks.php |
— | — | @@ -81,8 +81,8 @@ |
82 | 82 | $contestants = $dbr->select( |
83 | 83 | array( 'contest_contestants', 'contests' ), |
84 | 84 | array( 'contestant_id' ), |
85 | | - array( 'contest_status' => Contest::STATUS_ACTIVE ), |
86 | | - '', |
| 85 | + array( 'contest_status' => Contest::STATUS_ACTIVE, 'contestant_user_id' => $user->getId() ), |
| 86 | + __METHOD__, |
87 | 87 | array(), |
88 | 88 | array( 'contests' => array( 'INNER JOIN', array( 'contest_id=contestant_contest_id' ) ) ) |
89 | 89 | ); |
— | — | @@ -103,4 +103,62 @@ |
104 | 104 | return true; |
105 | 105 | } |
106 | 106 | |
| 107 | + /** |
| 108 | + * Called after the personal URLs have been set up, before they are shown. |
| 109 | + * @see https://www.mediawiki.org/wiki/Manual:Hooks/PersonalUrls |
| 110 | + * |
| 111 | + * @since 0.1 |
| 112 | + * |
| 113 | + * @param array $personal_urls |
| 114 | + * @param Title $title |
| 115 | + * |
| 116 | + * @return true |
| 117 | + */ |
| 118 | + public static function onPersonalUrls( array &$personal_urls, Title &$title ) { |
| 119 | + if ( ContestSettings::get( 'enableTopLink' ) ) { |
| 120 | + global $wgUser; |
| 121 | + |
| 122 | + // Find the watchlist item and replace it by the my contests link and itself. |
| 123 | + if ( $wgUser->isLoggedIn() && $wgUser->getOption( 'contest_showtoplink' ) ) { |
| 124 | + $keys = array_keys( $personal_urls ); |
| 125 | + $watchListLocation = array_search( 'watchlist', $keys ); |
| 126 | + $watchListItem = $personal_urls[$keys[$watchListLocation]]; |
| 127 | + |
| 128 | + $url = SpecialPage::getTitleFor( 'MyContests' )->getLinkUrl(); |
| 129 | + $myContests = array( |
| 130 | + 'text' => wfMsg( 'contest-toplink' ), |
| 131 | + 'href' => $url, |
| 132 | + 'active' => ( $url == $title->getLinkUrl() ) |
| 133 | + ); |
| 134 | + |
| 135 | + array_splice( $personal_urls, $watchListLocation, 1, array( $myContests, $watchListItem ) ); |
| 136 | + } |
| 137 | + } |
| 138 | + |
| 139 | + return true; |
| 140 | + } |
| 141 | + |
| 142 | + /** |
| 143 | + * Adds the preferences of Contest to the list of available ones. |
| 144 | + * @see https://www.mediawiki.org/wiki/Manual:Hooks/GetPreferences |
| 145 | + * |
| 146 | + * @since 0.1 |
| 147 | + * |
| 148 | + * @param User $user |
| 149 | + * @param array $preferences |
| 150 | + * |
| 151 | + * @return true |
| 152 | + */ |
| 153 | + public static function onGetPreferences( User $user, array &$preferences ) { |
| 154 | + if ( ContestSettings::get( 'enableTopLink' ) ) { |
| 155 | + $preferences['contest_showtoplink'] = array( |
| 156 | + 'type' => 'toggle', |
| 157 | + 'label-message' => 'contest-prefs-showtoplink', |
| 158 | + 'section' => 'contest', |
| 159 | + ); |
| 160 | + } |
| 161 | + |
| 162 | + return true; |
| 163 | + } |
| 164 | + |
107 | 165 | } |
Index: trunk/extensions/Contest/Contest.alias.php |
— | — | @@ -20,8 +20,7 @@ |
21 | 21 | 'Contestant' => array( 'Contestant' ), |
22 | 22 | 'Contests' => array( 'Contests' ), |
23 | 23 | 'ContestSignup' => array( 'ContestSignup' ), |
24 | | - 'ContestSubmission' => array( 'ContestSubmission' ), |
25 | 24 | 'ContestWelcome' => array( 'ContestWelcome' ), |
26 | 25 | 'EditContest' => array( 'EditContest' ), |
27 | | - 'MyContests' => array( 'MyContests' ), |
| 26 | + 'MyContests' => array( 'MyContests', 'ContestSubmission', 'My contests' ), |
28 | 27 | ); |
Index: trunk/extensions/Contest/Contest.settings.php |
— | — | @@ -28,7 +28,8 @@ |
29 | 29 | */ |
30 | 30 | protected static function getDefaultSettings() { |
31 | 31 | return array( |
32 | | - 'votevalues' => range( 0, 5 ) |
| 32 | + 'votevalues' => range( 0, 5 ), |
| 33 | + 'enableTopLink' => true, |
33 | 34 | ); |
34 | 35 | } |
35 | 36 | |
Index: trunk/extensions/Contest/Contest.php |
— | — | @@ -70,7 +70,6 @@ |
71 | 71 | $wgAutoloadClasses['SpecialContestPage'] = dirname( __FILE__ ) . '/specials/SpecialContestPage.php'; |
72 | 72 | $wgAutoloadClasses['SpecialContests'] = dirname( __FILE__ ) . '/specials/SpecialContests.php'; |
73 | 73 | $wgAutoloadClasses['SpecialContestSignup'] = dirname( __FILE__ ) . '/specials/SpecialContestSignup.php'; |
74 | | -$wgAutoloadClasses['SpecialContestSubmission'] = dirname( __FILE__ ) . '/specials/SpecialContestSubmission.php'; |
75 | 74 | $wgAutoloadClasses['SpecialContestWelcome'] = dirname( __FILE__ ) . '/specials/SpecialContestWelcome.php'; |
76 | 75 | $wgAutoloadClasses['SpecialEditContest'] = dirname( __FILE__ ) . '/specials/SpecialEditContest.php'; |
77 | 76 | $wgAutoloadClasses['SpecialMyContests'] = dirname( __FILE__ ) . '/specials/SpecialMyContests.php'; |
— | — | @@ -80,7 +79,6 @@ |
81 | 80 | $wgSpecialPages['Contestant'] = 'SpecialContestant'; |
82 | 81 | $wgSpecialPages['Contests'] = 'SpecialContests'; |
83 | 82 | $wgSpecialPages['ContestSignup'] = 'SpecialContestSignup'; |
84 | | -$wgSpecialPages['ContestSubmission'] = 'SpecialContestSubmission'; |
85 | 83 | $wgSpecialPages['ContestWelcome'] = 'SpecialContestWelcome'; |
86 | 84 | $wgSpecialPages['EditContest'] = 'SpecialEditContest'; |
87 | 85 | $wgSpecialPages['MyContests'] = 'SpecialMyContests'; |
— | — | @@ -89,7 +87,6 @@ |
90 | 88 | $wgSpecialPageGroups['Contestant'] = 'other'; |
91 | 89 | $wgSpecialPageGroups['Contests'] = 'other'; |
92 | 90 | $wgSpecialPageGroups['ContestSignup'] = 'other'; |
93 | | -$wgSpecialPageGroups['ContestSubmission'] = 'other'; |
94 | 91 | $wgSpecialPageGroups['ContestWelcome'] = 'other'; |
95 | 92 | $wgSpecialPageGroups['EditContest'] = 'other'; |
96 | 93 | $wgSpecialPageGroups['MyContests'] = 'other'; |
— | — | @@ -105,6 +102,8 @@ |
106 | 103 | $wgHooks['LoadExtensionSchemaUpdates'][] = 'ContestHooks::onSchemaUpdate'; |
107 | 104 | $wgHooks['UnitTestsList'][] = 'ContestHooks::registerUnitTests'; |
108 | 105 | $wgHooks['UserSetEmail'][] = 'ContestHooks::onUserSetEmail'; |
| 106 | +$wgHooks['PersonalUrls'][] = 'ContestHooks::onPersonalUrls'; |
| 107 | +$wgHooks['GetPreferences'][] = 'ContestHooks::onGetPreferences'; |
109 | 108 | |
110 | 109 | // Rights |
111 | 110 | |
Index: trunk/extensions/Contest/includes/ContestDBObject.php |
— | — | @@ -643,7 +643,7 @@ |
644 | 644 | $this->getDBTable(), |
645 | 645 | $fields, |
646 | 646 | count( $conditions ) == 0 ? '' : $conditions, |
647 | | - '', |
| 647 | + __METHOD__, |
648 | 648 | $options |
649 | 649 | ); |
650 | 650 | } |
Index: trunk/extensions/Contest/includes/ContestContestant.php |
— | — | @@ -458,16 +458,29 @@ |
459 | 459 | $success = parent::insertIntoDB(); |
460 | 460 | |
461 | 461 | if ( $success ) { |
462 | | - $this->getContest( array( 'id' ) )->addToSubmissionCount( 1 ); |
463 | | - $this->sendSignupEmail(); |
464 | | - |
465 | | - wfRunHooks( 'ContestAfterContestantInsert', array( &$this ) ); |
| 462 | + $this->onUserSignup(); |
466 | 463 | } |
467 | 464 | |
468 | 465 | return $success; |
469 | 466 | } |
470 | 467 | |
471 | 468 | /** |
| 469 | + * Handles successfull user signup for a contest. |
| 470 | + * |
| 471 | + * @since 0.1 |
| 472 | + */ |
| 473 | + protected function onUserSignup() { |
| 474 | + $this->getContest( array( 'id' ) )->addToSubmissionCount( 1 ); |
| 475 | + |
| 476 | + $this->getUser()->setOption( 'contest_showtoplink', true ); |
| 477 | + $this->getUser()->saveSettings(); // TODO: can't we just save this single option instead of everything? |
| 478 | + |
| 479 | + $this->sendSignupEmail(); |
| 480 | + |
| 481 | + wfRunHooks( 'ContestAfterContestantInsert', array( &$this ) ); |
| 482 | + } |
| 483 | + |
| 484 | + /** |
472 | 485 | * Send the signup email. |
473 | 486 | * |
474 | 487 | * @since 0.1 |