Index: trunk/phase3/RELEASE-NOTES |
— | — | @@ -72,6 +72,8 @@ |
73 | 73 | (maintenance/fixDoubleRedirects.php) |
74 | 74 | * (bug 23315) New body classes to allow easier styling of special pages |
75 | 75 | * (bug 27159) Make email confirmation code expiration time configurable |
| 76 | +* CSS/JS for each user group is imported from MediaWiki:Sysop.js, |
| 77 | + MediaWiki:Autoconfirmed.css, etc. |
76 | 78 | |
77 | 79 | === Bug fixes in 1.18 === |
78 | 80 | * (bug 23119) WikiError class and subclasses are now marked as deprecated |
Index: trunk/phase3/resources/Resources.php |
— | — | @@ -8,6 +8,7 @@ |
9 | 9 | 'startup' => array( 'class' => 'ResourceLoaderStartUpModule' ), |
10 | 10 | 'user' => array( 'class' => 'ResourceLoaderUserModule' ), |
11 | 11 | 'user.options' => array( 'class' => 'ResourceLoaderUserOptionsModule' ), |
| 12 | + 'user.groups' => array( 'class' => 'ResourceLoaderUserGroupsModule' ), |
12 | 13 | |
13 | 14 | /* Skins */ |
14 | 15 | |
Index: trunk/phase3/includes/resourceloader/ResourceLoaderUserGroupsModule.php |
— | — | @@ -0,0 +1,61 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * This program is free software; you can redistribute it and/or modify |
| 5 | + * it under the terms of the GNU General Public License as published by |
| 6 | + * the Free Software Foundation; either version 2 of the License, or |
| 7 | + * (at your option) any later version. |
| 8 | + * |
| 9 | + * This program is distributed in the hope that it will be useful, |
| 10 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | + * GNU General Public License for more details. |
| 13 | + * |
| 14 | + * You should have received a copy of the GNU General Public License along |
| 15 | + * with this program; if not, write to the Free Software Foundation, Inc., |
| 16 | + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 17 | + * http://www.gnu.org/copyleft/gpl.html |
| 18 | + * |
| 19 | + * @file |
| 20 | + * @author Trevor Parscal |
| 21 | + * @author Roan Kattouw |
| 22 | + */ |
| 23 | + |
| 24 | +/** |
| 25 | + * Module for user customizations |
| 26 | + */ |
| 27 | +class ResourceLoaderUserGroupsModule extends ResourceLoaderWikiModule { |
| 28 | + |
| 29 | + /* Protected Methods */ |
| 30 | + protected $origin = self::ORIGIN_USER_SITEWIDE; |
| 31 | + |
| 32 | + protected function getPages( ResourceLoaderContext $context ) { |
| 33 | + if ( $context->getUser() ) { |
| 34 | + $user = User::newFromName( $context->getUser() ); |
| 35 | + if( $user instanceof User ){ |
| 36 | + $pages = array(); |
| 37 | + foreach( $user->getEffectiveGroups() as $group ){ |
| 38 | + if( in_array( $group, array( '*', 'user' ) ) ){ |
| 39 | + continue; |
| 40 | + } |
| 41 | + $g = ucfirst( $group ); |
| 42 | + $pages["MediaWiki:$g.js"] = array( 'type' => 'script' ); |
| 43 | + $pages["MediaWiki:$g.css"] = array( 'type' => 'style' ); |
| 44 | + } |
| 45 | + return $pages; |
| 46 | + } |
| 47 | + } |
| 48 | + return array(); |
| 49 | + } |
| 50 | + |
| 51 | + /* Methods */ |
| 52 | + |
| 53 | + public function getGroup() { |
| 54 | + return 'user'; |
| 55 | + } |
| 56 | + |
| 57 | + public function getFlip( $context ) { |
| 58 | + global $wgContLang; |
| 59 | + |
| 60 | + return $wgContLang->getDir() !== $context->getDirection(); |
| 61 | + } |
| 62 | +} |
Property changes on: trunk/phase3/includes/resourceloader/ResourceLoaderUserGroupsModule.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 63 | + native |
Index: trunk/phase3/includes/AutoLoader.php |
— | — | @@ -152,6 +152,7 @@ |
153 | 153 | 'LinksUpdate' => 'includes/LinksUpdate.php', |
154 | 154 | 'LocalisationCache' => 'includes/LocalisationCache.php', |
155 | 155 | 'LocalisationCache_BulkLoad' => 'includes/LocalisationCache.php', |
| 156 | + 'Login' => 'includes/Login.php', |
156 | 157 | 'LogPage' => 'includes/LogPage.php', |
157 | 158 | 'LogPager' => 'includes/LogEventsList.php', |
158 | 159 | 'LogEventsList' => 'includes/LogEventsList.php', |
— | — | @@ -211,6 +212,7 @@ |
212 | 213 | 'ResourceLoaderFileModule' => 'includes/resourceloader/ResourceLoaderFileModule.php', |
213 | 214 | 'ResourceLoaderSiteModule' => 'includes/resourceloader/ResourceLoaderSiteModule.php', |
214 | 215 | 'ResourceLoaderUserModule' => 'includes/resourceloader/ResourceLoaderUserModule.php', |
| 216 | + 'ResourceLoaderUserGroupsModule' => 'includes/resourceloader/ResourceLoaderUserGroupsModule.php', |
215 | 217 | 'ResourceLoaderUserOptionsModule' => 'includes/resourceloader/ResourceLoaderUserOptionsModule.php', |
216 | 218 | 'ResourceLoaderStartUpModule' => 'includes/resourceloader/ResourceLoaderStartUpModule.php', |
217 | 219 | 'ReverseChronologicalPager' => 'includes/Pager.php', |
— | — | @@ -579,6 +581,7 @@ |
580 | 582 | 'AncientPagesPage' => 'includes/specials/SpecialAncientpages.php', |
581 | 583 | 'BrokenRedirectsPage' => 'includes/specials/SpecialBrokenRedirects.php', |
582 | 584 | 'ContribsPager' => 'includes/specials/SpecialContributions.php', |
| 585 | + 'SpecialCreateAccount' => 'includes/specials/SpecialCreateAccount.php', |
583 | 586 | 'DBLockForm' => 'includes/specials/SpecialLockdb.php', |
584 | 587 | 'DBUnlockForm' => 'includes/specials/SpecialUnlockdb.php', |
585 | 588 | 'DeadendPagesPage' => 'includes/specials/SpecialDeadendpages.php', |
— | — | @@ -678,6 +681,7 @@ |
679 | 682 | 'UnwatchedpagesPage' => 'includes/specials/SpecialUnwatchedpages.php', |
680 | 683 | 'UploadForm' => 'includes/specials/SpecialUpload.php', |
681 | 684 | 'UploadSourceField' => 'includes/specials/SpecialUpload.php', |
| 685 | + 'SpecialUserlogin' => 'includes/specials/SpecialUserlogin.php', |
682 | 686 | 'UserrightsPage' => 'includes/specials/SpecialUserrights.php', |
683 | 687 | 'UsersPager' => 'includes/specials/SpecialListusers.php', |
684 | 688 | 'WantedCategoriesPage' => 'includes/specials/SpecialWantedcategories.php', |
Index: trunk/phase3/includes/specials/SpecialResetpass.php |
— | — | @@ -27,14 +27,69 @@ |
28 | 28 | * @ingroup SpecialPage |
29 | 29 | */ |
30 | 30 | class SpecialResetpass extends SpecialPage { |
| 31 | + |
| 32 | + public $mFormFields = array( |
| 33 | + 'NameInfo' => array( |
| 34 | + 'type' => 'info', |
| 35 | + 'label-message' => 'yourname', |
| 36 | + 'default' => '', |
| 37 | + ), |
| 38 | + 'Name' => array( |
| 39 | + 'type' => 'hidden', |
| 40 | + 'name' => 'wpName', |
| 41 | + 'default' => null, |
| 42 | + ), |
| 43 | + 'OldPassword' => array( |
| 44 | + 'type' => 'password', |
| 45 | + 'label-message' => 'oldpassword', |
| 46 | + 'size' => '20', |
| 47 | + 'id' => 'wpPassword', |
| 48 | + 'required' => '', |
| 49 | + ), |
| 50 | + 'NewPassword' => array( |
| 51 | + 'type' => 'password', |
| 52 | + 'label-message' => 'newpassword', |
| 53 | + 'size' => '20', |
| 54 | + 'id' => 'wpNewPassword', |
| 55 | + 'required' => '', |
| 56 | + ), |
| 57 | + 'Retype' => array( |
| 58 | + 'type' => 'password', |
| 59 | + 'label-message' => 'retypenew', |
| 60 | + 'size' => '20', |
| 61 | + 'id' => 'wpRetype', |
| 62 | + 'required' => '', |
| 63 | + ), |
| 64 | + 'Remember' => array( |
| 65 | + 'type' => 'check', |
| 66 | + 'id' => 'wpRemember', |
| 67 | + ), |
| 68 | + ); |
| 69 | + |
| 70 | + protected $mUsername; |
| 71 | + protected $mLogin; |
| 72 | + |
31 | 73 | public function __construct() { |
| 74 | + global $wgRequest, $wgUser, $wgLang, $wgCookieExpiration; |
| 75 | + |
32 | 76 | parent::__construct( 'Resetpass' ); |
| 77 | + $this->mFormFields['Retype']['validation-callback'] = array( 'SpecialCreateAccount', 'formValidateRetype' ); |
| 78 | + |
| 79 | + $this->mUsername = $wgRequest->getVal( 'wpName', $wgUser->getName() ); |
| 80 | + $this->mReturnTo = $wgRequest->getVal( 'returnto' ); |
| 81 | + $this->mReturnToQuery = $wgRequest->getVal( 'returntoquery' ); |
| 82 | + |
| 83 | + $this->mFormFields['Remember']['label'] = wfMsgExt( |
| 84 | + 'remembermypassword', |
| 85 | + 'parseinline', |
| 86 | + $wgLang->formatNum( ceil( $wgCookieExpiration / 86400 ) ) |
| 87 | + ); |
33 | 88 | } |
34 | 89 | |
35 | 90 | /** |
36 | 91 | * Main execution point |
37 | 92 | */ |
38 | | - function execute( $par ) { |
| 93 | + public function execute( $par ) { |
39 | 94 | global $wgUser, $wgAuth, $wgOut, $wgRequest; |
40 | 95 | |
41 | 96 | if ( wfReadOnly() ) { |
— | — | @@ -42,196 +97,134 @@ |
43 | 98 | return; |
44 | 99 | } |
45 | 100 | |
46 | | - $this->mUserName = $wgRequest->getVal( 'wpName' ); |
47 | | - $this->mOldpass = $wgRequest->getVal( 'wpPassword' ); |
48 | | - $this->mNewpass = $wgRequest->getVal( 'wpNewPassword' ); |
49 | | - $this->mRetype = $wgRequest->getVal( 'wpRetype' ); |
50 | | - $this->mDomain = $wgRequest->getVal( 'wpDomain' ); |
51 | | - |
52 | 101 | $this->setHeaders(); |
53 | 102 | $this->outputHeader(); |
54 | 103 | $wgOut->disallowUserJs(); |
55 | 104 | |
56 | | - if( !$wgRequest->wasPosted() && !$wgUser->isLoggedIn() ) { |
57 | | - $this->error( wfMsg( 'resetpass-no-info' ) ); |
58 | | - return; |
| 105 | + if( wfReadOnly() ){ |
| 106 | + $wgOut->readOnlyPage(); |
| 107 | + return false; |
59 | 108 | } |
| 109 | + if( !$wgAuth->allowPasswordChange() ) { |
| 110 | + $wgOut->showErrorPage( 'errorpagetitle', 'resetpass_forbidden' ); |
| 111 | + return false; |
| 112 | + } |
60 | 113 | |
61 | | - if( $wgRequest->wasPosted() && $wgRequest->getBool( 'wpCancel' ) ) { |
62 | | - $this->doReturnTo(); |
63 | | - return; |
| 114 | + if( !$wgRequest->wasPosted() && !$wgUser->isLoggedIn() ) { |
| 115 | + $wgOut->showErrorPage( 'errorpagetitle', 'resetpass-no-info' ); |
| 116 | + return false; |
64 | 117 | } |
65 | 118 | |
66 | | - if( $wgRequest->wasPosted() && $wgUser->matchEditToken( $wgRequest->getVal( 'token' ) ) ) { |
67 | | - try { |
68 | | - $wgAuth->setDomain( $this->mDomain ); |
69 | | - if( !$wgAuth->allowPasswordChange() ) { |
70 | | - $this->error( wfMsg( 'resetpass_forbidden' ) ); |
71 | | - return; |
72 | | - } |
| 119 | + $this->getForm()->show(); |
73 | 120 | |
74 | | - $this->attemptReset( $this->mNewpass, $this->mRetype ); |
75 | | - $wgOut->addWikiMsg( 'resetpass_success' ); |
76 | | - if( !$wgUser->isLoggedIn() ) { |
77 | | - LoginForm::setLoginToken(); |
78 | | - $token = LoginForm::getLoginToken(); |
79 | | - $data = array( |
80 | | - 'action' => 'submitlogin', |
81 | | - 'wpName' => $this->mUserName, |
82 | | - 'wpDomain' => $this->mDomain, |
83 | | - 'wpLoginToken' => $token, |
84 | | - 'wpPassword' => $this->mNewpass, |
85 | | - 'returnto' => $wgRequest->getVal( 'returnto' ), |
86 | | - ); |
87 | | - if( $wgRequest->getCheck( 'wpRemember' ) ) { |
88 | | - $data['wpRemember'] = 1; |
89 | | - } |
90 | | - $login = new LoginForm( new FauxRequest( $data, true ) ); |
91 | | - $login->execute( null ); |
92 | | - } |
93 | | - $this->doReturnTo(); |
94 | | - } catch( PasswordError $e ) { |
95 | | - $this->error( $e->getMessage() ); |
| 121 | + } |
| 122 | + |
| 123 | + public function formSubmitCallback( $data ){ |
| 124 | + $data['Password'] = $data['OldPassword']; |
| 125 | + $this->mLogin = new Login( $data ); |
| 126 | + $result = $this->attemptReset( $data ); |
| 127 | + |
| 128 | + if( $result === true ){ |
| 129 | + # Log the user in if they're not already (ie we're |
| 130 | + # coming from the e-mail-password-reset route |
| 131 | + global $wgUser; |
| 132 | + if( !$wgUser->isLoggedIn() ) { |
| 133 | + $this->mLogin->attemptLogin( $data['NewPassword'] ); |
| 134 | + # Redirect out to the appropriate target. |
| 135 | + SpecialUserlogin::successfulLogin( |
| 136 | + 'resetpass_success', |
| 137 | + $this->mReturnTo, |
| 138 | + $this->mReturnToQuery, |
| 139 | + $this->mLogin->mLoginResult |
| 140 | + ); |
| 141 | + } else { |
| 142 | + # Redirect out to the appropriate target. |
| 143 | + SpecialUserlogin::successfulLogin( |
| 144 | + 'resetpass_success', |
| 145 | + $this->mReturnTo, |
| 146 | + $this->mReturnToQuery |
| 147 | + ); |
96 | 148 | } |
| 149 | + return true; |
| 150 | + } else { |
| 151 | + return $result; |
97 | 152 | } |
98 | | - $this->showForm(); |
99 | 153 | } |
100 | | - |
101 | | - function doReturnTo() { |
102 | | - global $wgRequest, $wgOut; |
103 | | - $titleObj = Title::newFromText( $wgRequest->getVal( 'returnto' ) ); |
104 | | - if ( !$titleObj instanceof Title ) { |
105 | | - $titleObj = Title::newMainPage(); |
106 | | - } |
107 | | - $wgOut->redirect( $titleObj->getFullURL() ); |
108 | | - } |
109 | 154 | |
110 | | - function error( $msg ) { |
111 | | - global $wgOut; |
112 | | - $wgOut->addHTML( Xml::element('p', array( 'class' => 'error' ), $msg ) ); |
113 | | - } |
| 155 | + public function getForm( $reset=false ) { |
| 156 | + global $wgOut, $wgUser, $wgRequest; |
114 | 157 | |
115 | | - function showForm() { |
116 | | - global $wgOut, $wgUser, $wgRequest, $wgLivePasswordStrengthChecks; |
117 | | - |
118 | | - if ( $wgLivePasswordStrengthChecks ) { |
119 | | - $wgOut->addPasswordSecurity( 'wpNewPassword', 'wpRetype' ); |
120 | | - } |
121 | | - $self = $this->getTitle(); |
122 | | - if ( !$this->mUserName ) { |
123 | | - $this->mUserName = $wgUser->getName(); |
124 | | - } |
125 | | - $rememberMe = ''; |
126 | | - if ( !$wgUser->isLoggedIn() ) { |
127 | | - global $wgCookieExpiration, $wgLang; |
128 | | - $rememberMe = '<tr>' . |
129 | | - '<td></td>' . |
130 | | - '<td class="mw-input">' . |
131 | | - Xml::checkLabel( |
132 | | - wfMsgExt( 'remembermypassword', 'parsemag', $wgLang->formatNum( ceil( $wgCookieExpiration / ( 3600 * 24 ) ) ) ), |
133 | | - 'wpRemember', 'wpRemember', |
134 | | - $wgRequest->getCheck( 'wpRemember' ) ) . |
135 | | - '</td>' . |
136 | | - '</tr>'; |
| 158 | + if( $reset || $wgRequest->getCheck( 'reset' ) ){ |
| 159 | + # Request is coming from Special:UserLogin after it |
| 160 | + # authenticated someone with a temporary password. |
| 161 | + $this->mFormFields['OldPassword']['label-message'] = 'resetpass-temp-password'; |
137 | 162 | $submitMsg = 'resetpass_submit'; |
138 | | - $oldpassMsg = 'resetpass-temp-password'; |
| 163 | + $this->mFormFields['OldPassword']['default'] = $wgRequest->getText( 'wpPassword' ); |
| 164 | + #perpetuate |
| 165 | + $this->mFormFields['reset'] = array( |
| 166 | + 'type' => 'hidden', |
| 167 | + 'default' => '1', |
| 168 | + ); |
139 | 169 | } else { |
140 | | - $oldpassMsg = 'oldpassword'; |
| 170 | + unset( $this->mFormFields['Remember'] ); |
141 | 171 | $submitMsg = 'resetpass-submit-loggedin'; |
142 | 172 | } |
143 | | - $wgOut->addHTML( |
144 | | - Xml::fieldset( wfMsg( 'resetpass_header' ) ) . |
145 | | - Xml::openElement( 'form', |
146 | | - array( |
147 | | - 'method' => 'post', |
148 | | - 'action' => $self->getLocalUrl(), |
149 | | - 'id' => 'mw-resetpass-form' ) ) . "\n" . |
150 | | - Html::hidden( 'token', $wgUser->editToken() ) . "\n" . |
151 | | - Html::hidden( 'wpName', $this->mUserName ) . "\n" . |
152 | | - Html::hidden( 'wpDomain', $this->mDomain ) . "\n" . |
153 | | - Html::hidden( 'returnto', $wgRequest->getVal( 'returnto' ) ) . "\n" . |
154 | | - wfMsgExt( 'resetpass_text', array( 'parse' ) ) . "\n" . |
155 | | - Xml::openElement( 'table', array( 'id' => 'mw-resetpass-table' ) ) . "\n" . |
156 | | - $this->pretty( array( |
157 | | - array( 'wpName', 'username', 'text', $this->mUserName, '' ), |
158 | | - array( 'wpPassword', $oldpassMsg, 'password', $this->mOldpass, '' ), |
159 | | - array( 'wpNewPassword', 'newpassword', 'password', null, '<div id="password-strength"></div>' ), |
160 | | - array( 'wpRetype', 'retypenew', 'password', null, '<div id="password-retype"></div>' ), |
161 | | - ) ) . "\n" . |
162 | | - $rememberMe . |
163 | | - "<tr>\n" . |
164 | | - "<td></td>\n" . |
165 | | - '<td class="mw-input">' . |
166 | | - Xml::submitButton( wfMsg( $submitMsg ) ) . |
167 | | - Xml::submitButton( wfMsg( 'resetpass-submit-cancel' ), array( 'name' => 'wpCancel' ) ) . |
168 | | - "</td>\n" . |
169 | | - "</tr>\n" . |
170 | | - Xml::closeElement( 'table' ) . |
171 | | - Xml::closeElement( 'form' ) . |
172 | | - Xml::closeElement( 'fieldset' ) . "\n" |
173 | | - ); |
174 | | - } |
175 | 173 | |
176 | | - function pretty( $fields ) { |
177 | | - $out = ''; |
178 | | - foreach ( $fields as $list ) { |
179 | | - list( $name, $label, $type, $value, $extra ) = $list; |
180 | | - if( $type == 'text' ) { |
181 | | - $field = htmlspecialchars( $value ); |
182 | | - } else { |
183 | | - $attribs = array( 'id' => $name ); |
184 | | - if ( $name == 'wpNewPassword' || $name == 'wpRetype' ) { |
185 | | - $attribs = array_merge( $attribs, |
186 | | - User::passwordChangeInputAttribs() ); |
187 | | - } |
188 | | - if ( $name == 'wpPassword' ) { |
189 | | - $attribs[] = 'autofocus'; |
190 | | - } |
191 | | - $field = Html::input( $name, $value, $type, $attribs ); |
192 | | - } |
193 | | - $out .= "<tr>\n"; |
194 | | - $out .= "\t<td class='mw-label'>"; |
195 | | - if ( $type != 'text' ) |
196 | | - $out .= Xml::label( wfMsg( $label ), $name ); |
197 | | - else |
198 | | - $out .= wfMsgHtml( $label ); |
199 | | - $out .= "</td>\n"; |
200 | | - $out .= "\t<td class='mw-input'>$field</td>\n"; |
201 | | - $out .= "\t<td>$extra</td>\n"; |
202 | | - $out .= "</tr>"; |
203 | | - } |
204 | | - return $out; |
| 174 | + $this->mFormFields['Name']['default'] = |
| 175 | + $this->mFormFields['NameInfo']['default'] = $this->mUsername; |
| 176 | + |
| 177 | + $form = new HTMLForm( $this->mFormFields, '' ); |
| 178 | + $form->suppressReset(); |
| 179 | + $form->setSubmitText( wfMsg( $submitMsg ) ); |
| 180 | + $form->setTitle( $this->getTitle() ); |
| 181 | + $form->addHiddenField( 'returnto', $this->mReturnTo ); |
| 182 | + $form->setWrapperLegend( wfMsg( 'resetpass_header' ) ); |
| 183 | + |
| 184 | + $form->setSubmitCallback( array( $this, 'formSubmitCallback' ) ); |
| 185 | + $form->loadData(); |
| 186 | + |
| 187 | + return $form; |
205 | 188 | } |
206 | 189 | |
207 | 190 | /** |
208 | | - * @throws PasswordError when cannot set the new password because requirements not met. |
| 191 | + * Try to reset the user's password |
209 | 192 | */ |
210 | | - protected function attemptReset( $newpass, $retype ) { |
211 | | - $user = User::newFromName( $this->mUserName ); |
212 | | - if( !$user || $user->isAnon() ) { |
213 | | - throw new PasswordError( 'no such user' ); |
| 193 | + protected function attemptReset( $data ) { |
| 194 | + |
| 195 | + if( !$data['Name'] |
| 196 | + || !$data['OldPassword'] |
| 197 | + || !$data['NewPassword'] |
| 198 | + || !$data['Retype'] ) |
| 199 | + { |
| 200 | + return false; |
214 | 201 | } |
215 | | - |
216 | | - if( $newpass !== $retype ) { |
217 | | - wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'badretype' ) ); |
218 | | - throw new PasswordError( wfMsg( 'badretype' ) ); |
| 202 | + |
| 203 | + $user = $this->mLogin->getUser(); |
| 204 | + if( !( $user instanceof User ) ){ |
| 205 | + return wfMsgExt( 'nosuchuser', 'parse' ); |
219 | 206 | } |
220 | 207 | |
221 | | - if( !$user->checkTemporaryPassword($this->mOldpass) && !$user->checkPassword($this->mOldpass) ) { |
222 | | - wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'wrongpassword' ) ); |
223 | | - throw new PasswordError( wfMsg( 'resetpass-wrong-oldpass' ) ); |
| 208 | + if( $data['NewPassword'] !== $data['Retype'] ) { |
| 209 | + wfRunHooks( 'PrefsPasswordAudit', array( $user, $data['NewPassword'], 'badretype' ) ); |
| 210 | + return wfMsgExt( 'badretype', 'parse' ); |
224 | 211 | } |
225 | | - |
| 212 | + |
| 213 | + if( !$user->checkPassword( $data['OldPassword'] ) && !$user->checkTemporaryPassword( $data['OldPassword'] ) ) |
| 214 | + { |
| 215 | + wfRunHooks( 'PrefsPasswordAudit', array( $user, $data['NewPassword'], 'wrongpassword' ) ); |
| 216 | + return wfMsgExt( 'resetpass-wrong-oldpass', 'parse' ); |
| 217 | + } |
| 218 | + |
226 | 219 | try { |
227 | | - $user->setPassword( $this->mNewpass ); |
228 | | - wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'success' ) ); |
229 | | - $this->mNewpass = $this->mOldpass = $this->mRetypePass = ''; |
| 220 | + $user->setPassword( $data['NewPassword'] ); |
| 221 | + wfRunHooks( 'PrefsPasswordAudit', array( $user, $data['NewPassword'], 'success' ) ); |
230 | 222 | } catch( PasswordError $e ) { |
231 | | - wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'error' ) ); |
232 | | - throw new PasswordError( $e->getMessage() ); |
| 223 | + wfRunHooks( 'PrefsPasswordAudit', array( $user, $data['NewPassword'], 'error' ) ); |
| 224 | + return $e->getMessage(); |
233 | 225 | } |
234 | | - |
| 226 | + |
235 | 227 | $user->setCookies(); |
236 | 228 | $user->saveSettings(); |
| 229 | + return true; |
237 | 230 | } |
238 | 231 | } |
Index: trunk/phase3/includes/Skin.php |
— | — | @@ -546,7 +546,7 @@ |
547 | 547 | * @private |
548 | 548 | */ |
549 | 549 | function setupUserCss( OutputPage $out ) { |
550 | | - global $wgRequest; |
| 550 | + global $wgRequest, $wgUser; |
551 | 551 | global $wgUseSiteCss, $wgAllowUserCss, $wgAllowUserCssPrefs; |
552 | 552 | |
553 | 553 | wfProfileIn( __METHOD__ ); |
— | — | @@ -560,6 +560,9 @@ |
561 | 561 | // Per-site custom styles |
562 | 562 | if ( $wgUseSiteCss ) { |
563 | 563 | $out->addModuleStyles( 'site' ); |
| 564 | + if( $wgUser->isLoggedIn() ){ |
| 565 | + $out->addModuleStyles( 'user.groups' ); |
| 566 | + } |
564 | 567 | } |
565 | 568 | |
566 | 569 | // Per-user custom styles |
Index: trunk/phase3/includes/HTMLForm.php |
— | — | @@ -109,6 +109,7 @@ |
110 | 110 | protected $mButtons = array(); |
111 | 111 | |
112 | 112 | protected $mWrapperLegend = false; |
| 113 | + protected $mTokenAction = 'Edit'; |
113 | 114 | |
114 | 115 | /** |
115 | 116 | * Build a new HTMLForm from an array of field attributes |
— | — | @@ -184,7 +185,7 @@ |
185 | 186 | if ( !$class ) { |
186 | 187 | throw new MWException( "Descriptor with no class: " . print_r( $descriptor, true ) ); |
187 | 188 | } |
188 | | - |
| 189 | + |
189 | 190 | $descriptor['fieldname'] = $fieldname; |
190 | 191 | |
191 | 192 | $obj = new $class( $descriptor ); |
— | — | @@ -210,14 +211,15 @@ |
211 | 212 | |
212 | 213 | /** |
213 | 214 | * Try submitting, with edit token check first |
214 | | - * @return Status|boolean |
| 215 | + * @return Status|boolean |
215 | 216 | */ |
216 | 217 | function tryAuthorizedSubmit() { |
217 | 218 | global $wgUser, $wgRequest; |
218 | 219 | $editToken = $wgRequest->getVal( 'wpEditToken' ); |
219 | 220 | |
220 | 221 | $result = false; |
221 | | - if ( $this->getMethod() != 'post' || $wgUser->matchEditToken( $editToken ) ) { |
| 222 | + # FIXME |
| 223 | + if ( $wgRequest->wasPosted() ){#&& $this->getMethod() != 'post' || $wgUser->matchEditToken( $editToken ) ) { |
222 | 224 | $result = $this->trySubmit(); |
223 | 225 | } |
224 | 226 | return $result; |
— | — | @@ -249,6 +251,11 @@ |
250 | 252 | * display. |
251 | 253 | */ |
252 | 254 | function trySubmit() { |
| 255 | + # Check the session tokens |
| 256 | + # FIXME |
| 257 | + if ( false && !Token::match( null, $this->mTokenAction ) ) { |
| 258 | + return array( 'sessionfailure' ); |
| 259 | + } |
253 | 260 | # Check for validation |
254 | 261 | foreach ( $this->mFlatFields as $fieldname => $field ) { |
255 | 262 | if ( !empty( $field->mParams['nodata'] ) ) { |
— | — | @@ -424,9 +431,14 @@ |
425 | 432 | global $wgUser; |
426 | 433 | |
427 | 434 | $html = ''; |
428 | | - |
429 | 435 | if( $this->getMethod() == 'post' ){ |
430 | | - $html .= Html::hidden( 'wpEditToken', $wgUser->editToken(), array( 'id' => 'wpEditToken' ) ) . "\n"; |
| 436 | + # FIXME |
| 437 | + $token = new Token( $this->mTokenAction ); |
| 438 | + $html .= Html::hidden( |
| 439 | + "wp{$this->mTokenAction}Token", |
| 440 | + $token->set(), |
| 441 | + array( 'id' => 'wpEditToken' ) |
| 442 | + ) . "\n"; |
431 | 443 | $html .= Html::hidden( 'title', $this->getTitle()->getPrefixedText() ) . "\n"; |
432 | 444 | } |
433 | 445 | |
— | — | @@ -579,6 +591,7 @@ |
580 | 592 | $this->mSubmitTooltip = $name; |
581 | 593 | } |
582 | 594 | |
| 595 | + |
583 | 596 | /** |
584 | 597 | * Set the id for the submit button. |
585 | 598 | * @param $t String. FIXME: Integrity is *not* validated |
— | — | @@ -607,6 +620,15 @@ |
608 | 621 | function setMessagePrefix( $p ) { |
609 | 622 | $this->mMessagePrefix = $p; |
610 | 623 | } |
| 624 | + /** |
| 625 | + * If you want to protect the form from CSRF by a token other than |
| 626 | + * the usual wsEditToken, set something here. |
| 627 | + * @see Token::set() |
| 628 | + * @param $a |
| 629 | + */ |
| 630 | + function setTokenAction( $a ){ |
| 631 | + $this->mTokenAction = ucfirst( $a ); |
| 632 | + } |
611 | 633 | |
612 | 634 | /** |
613 | 635 | * Set the title for form submission |
— | — | @@ -623,7 +645,7 @@ |
624 | 646 | function getTitle() { |
625 | 647 | return $this->mTitle; |
626 | 648 | } |
627 | | - |
| 649 | + |
628 | 650 | /** |
629 | 651 | * Set the method used to submit the form |
630 | 652 | * @param $method String |
— | — | @@ -631,7 +653,7 @@ |
632 | 654 | public function setMethod( $method='post' ){ |
633 | 655 | $this->mMethod = $method; |
634 | 656 | } |
635 | | - |
| 657 | + |
636 | 658 | public function getMethod(){ |
637 | 659 | return $this->mMethod; |
638 | 660 | } |
— | — | @@ -840,12 +862,12 @@ |
841 | 863 | if ( isset( $params['name'] ) ) { |
842 | 864 | $this->mName = $params['name']; |
843 | 865 | } |
844 | | - |
| 866 | + |
845 | 867 | $validName = Sanitizer::escapeId( $this->mName ); |
846 | 868 | if ( $this->mName != $validName && !isset( $params['nodata'] ) ) { |
847 | 869 | throw new MWException( "Invalid name '{$this->mName}' passed to " . __METHOD__ ); |
848 | 870 | } |
849 | | - |
| 871 | + |
850 | 872 | $this->mID = "mw-input-{$this->mName}"; |
851 | 873 | |
852 | 874 | if ( isset( $params['default'] ) ) { |
— | — | @@ -887,10 +909,10 @@ |
888 | 910 | global $wgRequest; |
889 | 911 | |
890 | 912 | $errors = $this->validate( $value, $this->mParent->mFieldData ); |
891 | | - |
| 913 | + |
892 | 914 | $cellAttributes = array(); |
893 | 915 | $verticalLabel = false; |
894 | | - |
| 916 | + |
895 | 917 | if ( !empty($this->mParams['vertical-label']) ) { |
896 | 918 | $cellAttributes['colspan'] = 2; |
897 | 919 | $verticalLabel = true; |
— | — | @@ -908,9 +930,9 @@ |
909 | 931 | array( 'class' => 'mw-input' ) + $cellAttributes, |
910 | 932 | $this->getInputHTML( $value ) . "\n$errors" |
911 | 933 | ); |
912 | | - |
| 934 | + |
913 | 935 | $fieldType = get_class( $this ); |
914 | | - |
| 936 | + |
915 | 937 | if ($verticalLabel) { |
916 | 938 | $html = Html::rawElement( 'tr', |
917 | 939 | array( 'class' => 'mw-htmlform-vertical-label' ), $label ); |
— | — | @@ -1139,11 +1161,11 @@ |
1140 | 1162 | if ( $p !== true ) { |
1141 | 1163 | return $p; |
1142 | 1164 | } |
1143 | | - |
| 1165 | + |
1144 | 1166 | $value = trim( $value ); |
1145 | 1167 | |
1146 | 1168 | # http://dev.w3.org/html5/spec/common-microsyntaxes.html#real-numbers |
1147 | | - # with the addition that a leading '+' sign is ok. |
| 1169 | + # with the addition that a leading '+' sign is ok. |
1148 | 1170 | if ( !preg_match( '/^((\+|\-)?\d+(\.\d+)?(E(\+|\-)?\d+)?)?$/i', $value ) ) { |
1149 | 1171 | return wfMsgExt( 'htmlform-float-invalid', 'parse' ); |
1150 | 1172 | } |
— | — | @@ -1182,8 +1204,8 @@ |
1183 | 1205 | } |
1184 | 1206 | |
1185 | 1207 | # http://dev.w3.org/html5/spec/common-microsyntaxes.html#signed-integers |
1186 | | - # with the addition that a leading '+' sign is ok. Note that leading zeros |
1187 | | - # are fine, and will be left in the input, which is useful for things like |
| 1208 | + # with the addition that a leading '+' sign is ok. Note that leading zeros |
| 1209 | + # are fine, and will be left in the input, which is useful for things like |
1188 | 1210 | # phone numbers when you know that they are integers (the HTML5 type=tel |
1189 | 1211 | # input does not require its value to be numeric). If you want a tidier |
1190 | 1212 | # value to, eg, save in the DB, clean it up with intval(). |
— | — | @@ -1415,8 +1437,8 @@ |
1416 | 1438 | } else { |
1417 | 1439 | $thisAttribs = array( 'id' => "{$this->mID}-$info", 'value' => $info ); |
1418 | 1440 | |
1419 | | - $checkbox = Xml::check( |
1420 | | - $this->mName . '[]', |
| 1441 | + $checkbox = Xml::check( |
| 1442 | + $this->mName . '[]', |
1421 | 1443 | in_array( $info, $value, true ), |
1422 | 1444 | $attribs + $thisAttribs ); |
1423 | 1445 | $checkbox .= ' ' . Html::rawElement( 'label', array( 'for' => "{$this->mID}-$info" ), $label ); |
— | — | @@ -1556,7 +1578,7 @@ |
1557 | 1579 | class HTMLHiddenField extends HTMLFormField { |
1558 | 1580 | public function __construct( $params ) { |
1559 | 1581 | parent::__construct( $params ); |
1560 | | - |
| 1582 | + |
1561 | 1583 | # Per HTML5 spec, hidden fields cannot be 'required' |
1562 | 1584 | # http://dev.w3.org/html5/spec/states-of-the-type-attribute.html#hidden-state |
1563 | 1585 | unset( $this->mParams['required'] ); |
— | — | @@ -1605,7 +1627,7 @@ |
1606 | 1628 | protected function needsLabel() { |
1607 | 1629 | return false; |
1608 | 1630 | } |
1609 | | - |
| 1631 | + |
1610 | 1632 | /** |
1611 | 1633 | * Button cannot be invalid |
1612 | 1634 | */ |
Index: trunk/phase3/includes/User.php |
— | — | @@ -5,12 +5,6 @@ |
6 | 6 | */ |
7 | 7 | |
8 | 8 | /** |
9 | | - * Int Number of characters in user_token field. |
10 | | - * @ingroup Constants |
11 | | - */ |
12 | | -define( 'USER_TOKEN_LENGTH', 32 ); |
13 | | - |
14 | | -/** |
15 | 9 | * Int Serialized record version. |
16 | 10 | * @ingroup Constants |
17 | 11 | */ |
— | — | @@ -41,13 +35,6 @@ |
42 | 36 | * of the database. |
43 | 37 | */ |
44 | 38 | class User { |
45 | | - /** |
46 | | - * Global constants made accessible as class constants so that autoloader |
47 | | - * magic can be used. |
48 | | - */ |
49 | | - const USER_TOKEN_LENGTH = USER_TOKEN_LENGTH; |
50 | | - const MW_USER_VERSION = MW_USER_VERSION; |
51 | | - const EDIT_TOKEN_SUFFIX = EDIT_TOKEN_SUFFIX; |
52 | 39 | |
53 | 40 | /** |
54 | 41 | * Array of Strings List of member variables which are saved to the |
— | — | @@ -377,7 +364,7 @@ |
378 | 365 | /** |
379 | 366 | * Create a new user object from a user row. |
380 | 367 | * The row should have all fields from the user table in it. |
381 | | - * @param $row Array A row from the user table |
| 368 | + * @param $row array A row from the user table |
382 | 369 | * @return User |
383 | 370 | */ |
384 | 371 | static function newFromRow( $row ) { |
— | — | @@ -627,6 +614,7 @@ |
628 | 615 | if( !wfRunHooks( 'isValidPassword', array( $password, &$result, $this ) ) ) |
629 | 616 | return $result; |
630 | 617 | |
| 618 | + |
631 | 619 | if ( $result === false ) { |
632 | 620 | if( strlen( $password ) < $wgMinimalPasswordLength ) { |
633 | 621 | return 'passwordtooshort'; |
— | — | @@ -1250,6 +1238,9 @@ |
1251 | 1239 | // Deprecated, but kept for backwards-compatibility config |
1252 | 1240 | return false; |
1253 | 1241 | } |
| 1242 | + |
| 1243 | + |
| 1244 | + |
1254 | 1245 | if( in_array( wfGetIP(), $wgRateLimitsExcludedIPs ) ) { |
1255 | 1246 | // No other good way currently to disable rate limits |
1256 | 1247 | // for specific IPs. :P |
— | — | @@ -1786,7 +1777,7 @@ |
1787 | 1778 | } |
1788 | 1779 | |
1789 | 1780 | if( !$this->isValidPassword( $str ) ) { |
1790 | | - global $wgMinimalPasswordLength; |
| 1781 | + global $wgMinimalPasswordLength; |
1791 | 1782 | $valid = $this->getPasswordValidity( $str ); |
1792 | 1783 | if ( is_array( $valid ) ) { |
1793 | 1784 | $message = array_shift( $valid ); |
— | — | @@ -1796,7 +1787,7 @@ |
1797 | 1788 | $params = array( $wgMinimalPasswordLength ); |
1798 | 1789 | } |
1799 | 1790 | throw new PasswordError( wfMsgExt( $message, array( 'parsemag' ), $params ) ); |
1800 | | - } |
| 1791 | + } |
1801 | 1792 | } |
1802 | 1793 | |
1803 | 1794 | if( !$wgAuth->setPassword( $this, $str ) ) { |
— | — | @@ -2206,6 +2197,7 @@ |
2207 | 2198 | } |
2208 | 2199 | |
2209 | 2200 | /** |
| 2201 | + |
2210 | 2202 | * Check if user is allowed to access a feature / make an action |
2211 | 2203 | * @param $action String action to be checked |
2212 | 2204 | * @return Boolean: True if action is allowed, else false |
— | — | @@ -2529,8 +2521,8 @@ |
2530 | 2522 | 'user_newpassword' => $this->mNewpassword, |
2531 | 2523 | 'user_newpass_time' => $dbw->timestampOrNull( $this->mNewpassTime ), |
2532 | 2524 | 'user_real_name' => $this->mRealName, |
2533 | | - 'user_email' => $this->mEmail, |
2534 | | - 'user_email_authenticated' => $dbw->timestampOrNull( $this->mEmailAuthenticated ), |
| 2525 | + 'user_email' => $this->mEmail, |
| 2526 | + 'user_email_authenticated' => $dbw->timestampOrNull( $this->mEmailAuthenticated ), |
2535 | 2527 | 'user_options' => '', |
2536 | 2528 | 'user_touched' => $dbw->timestamp( $this->mTouched ), |
2537 | 2529 | 'user_token' => $this->mToken, |
— | — | @@ -2589,7 +2581,6 @@ |
2590 | 2582 | } |
2591 | 2583 | $dbw = wfGetDB( DB_MASTER ); |
2592 | 2584 | $seqVal = $dbw->nextSequenceValue( 'user_user_id_seq' ); |
2593 | | - |
2594 | 2585 | $fields = array( |
2595 | 2586 | 'user_id' => $seqVal, |
2596 | 2587 | 'user_name' => $name, |
— | — | @@ -2801,7 +2792,7 @@ |
2802 | 2793 | // are shorter than this, doesn't mean people wont be able |
2803 | 2794 | // to. Certain authentication plugins do NOT want to save |
2804 | 2795 | // domain passwords in a mysql database, so we should |
2805 | | - // check this (in case $wgAuth->strict() is false). |
| 2796 | + // check this (incase $wgAuth->strict() is false). |
2806 | 2797 | if( !$this->isValidPassword( $password ) ) { |
2807 | 2798 | return false; |
2808 | 2799 | } |
— | — | @@ -2860,7 +2851,7 @@ |
2861 | 2852 | return EDIT_TOKEN_SUFFIX; |
2862 | 2853 | } else { |
2863 | 2854 | if( !isset( $_SESSION['wsEditToken'] ) ) { |
2864 | | - $token = self::generateToken(); |
| 2855 | + $token = $this->generateToken(); |
2865 | 2856 | $_SESSION['wsEditToken'] = $token; |
2866 | 2857 | } else { |
2867 | 2858 | $token = $_SESSION['wsEditToken']; |
— | — | @@ -2878,7 +2869,7 @@ |
2879 | 2870 | * @param $salt String Optional salt value |
2880 | 2871 | * @return String The new random token |
2881 | 2872 | */ |
2882 | | - public static function generateToken( $salt = '' ) { |
| 2873 | + function generateToken( $salt = '' ) { |
2883 | 2874 | $token = dechex( mt_rand() ) . dechex( mt_rand() ); |
2884 | 2875 | return md5( $token . $salt ); |
2885 | 2876 | } |
— | — | @@ -2986,7 +2977,7 @@ |
2987 | 2978 | $now = time(); |
2988 | 2979 | $expires = $now + $wgUserEmailConfirmationTokenExpiry; |
2989 | 2980 | $expiration = wfTimestamp( TS_MW, $expires ); |
2990 | | - $token = self::generateToken( $this->mId . $this->mEmail . $expires ); |
| 2981 | + $token = wfGenerateToken( $this->mId . $this->mEmail . $expires ); |
2991 | 2982 | $hash = md5( $token ); |
2992 | 2983 | $this->load(); |
2993 | 2984 | $this->mEmailToken = $hash; |
— | — | @@ -3140,7 +3131,7 @@ |
3141 | 3132 | * Get the timestamp of account creation. |
3142 | 3133 | * |
3143 | 3134 | * @return String|Bool Timestamp of account creation, or false for |
3144 | | - * non-existent/anonymous user accounts. |
| 3135 | + * non-existent/anonymous user accounts. |
3145 | 3136 | */ |
3146 | 3137 | public function getRegistration() { |
3147 | 3138 | return $this->getId() > 0 |
— | — | @@ -3152,7 +3143,7 @@ |
3153 | 3144 | * Get the timestamp of the first edit |
3154 | 3145 | * |
3155 | 3146 | * @return String|Bool Timestamp of first edit, or false for |
3156 | | - * non-existent/anonymous user accounts. |
| 3147 | + * non-existent/anonymous user accounts. |
3157 | 3148 | */ |
3158 | 3149 | public function getFirstEditTimestamp() { |
3159 | 3150 | if( $this->getId() == 0 ) { |
— | — | @@ -3342,9 +3333,9 @@ |
3343 | 3334 | * |
3344 | 3335 | * @param $group String: the group to check for whether it can add/remove |
3345 | 3336 | * @return Array array( 'add' => array( addablegroups ), |
3346 | | - * 'remove' => array( removablegroups ), |
3347 | | - * 'add-self' => array( addablegroups to self), |
3348 | | - * 'remove-self' => array( removable groups from self) ) |
| 3337 | + * 'remove' => array( removablegroups ), |
| 3338 | + * 'add-self' => array( addablegroups to self), |
| 3339 | + * 'remove-self' => array( removable groups from self) ) |
3349 | 3340 | */ |
3350 | 3341 | static function changeableByGroup( $group ) { |
3351 | 3342 | global $wgAddGroups, $wgRemoveGroups, $wgGroupsAddToSelf, $wgGroupsRemoveFromSelf; |
— | — | @@ -3582,31 +3573,27 @@ |
3583 | 3574 | * @param $byEmail Boolean: account made by email? |
3584 | 3575 | * @param $reason String: user supplied reason |
3585 | 3576 | */ |
3586 | | - public function addNewUserLogEntry( $byEmail = false, $reason = '' ) { |
3587 | | - global $wgUser, $wgContLang, $wgNewUserLog; |
| 3577 | + public function addNewUserLogEntry( $creator, $byEmail = false ) { |
| 3578 | + global $wgUser, $wgNewUserLog; |
3588 | 3579 | if( empty( $wgNewUserLog ) ) { |
3589 | 3580 | return true; // disabled |
3590 | 3581 | } |
3591 | 3582 | |
3592 | | - if( $this->getName() == $wgUser->getName() ) { |
3593 | | - $action = 'create'; |
3594 | | - } else { |
3595 | | - $action = 'create2'; |
3596 | | - if ( $byEmail ) { |
3597 | | - if ( $reason === '' ) { |
3598 | | - $reason = wfMsgForContent( 'newuserlog-byemail' ); |
3599 | | - } else { |
3600 | | - $reason = $wgContLang->commaList( array( |
3601 | | - $reason, wfMsgForContent( 'newuserlog-byemail' ) ) ); |
3602 | | - } |
3603 | | - } |
3604 | | - } |
| 3583 | + $action = ( $creator == $wgUser ) |
| 3584 | + ? 'create2' # Safe to publish the creator |
| 3585 | + : 'create'; # Creator is an IP, don't splash it all over Special:Log |
| 3586 | + |
| 3587 | + $message = $byEmail |
| 3588 | + ? wfMsgForContent( 'newuserlog-byemail' ) |
| 3589 | + : ''; |
| 3590 | + |
3605 | 3591 | $log = new LogPage( 'newusers' ); |
3606 | 3592 | $log->addEntry( |
3607 | 3593 | $action, |
3608 | 3594 | $this->getUserPage(), |
3609 | | - $reason, |
3610 | | - array( $this->getId() ) |
| 3595 | + $message, |
| 3596 | + array( $this->getId() ), |
| 3597 | + $creator |
3611 | 3598 | ); |
3612 | 3599 | return true; |
3613 | 3600 | } |
— | — | @@ -3616,12 +3603,18 @@ |
3617 | 3604 | * Used by things like CentralAuth and perhaps other authplugins. |
3618 | 3605 | */ |
3619 | 3606 | public function addNewUserLogEntryAutoCreate() { |
3620 | | - global $wgNewUserLog, $wgLogAutocreatedAccounts; |
3621 | | - if( !$wgNewUserLog || !$wgLogAutocreatedAccounts ) { |
| 3607 | + global $wgNewUserLog; |
| 3608 | + if( empty( $wgNewUserLog ) ) { |
3622 | 3609 | return true; // disabled |
3623 | 3610 | } |
3624 | 3611 | $log = new LogPage( 'newusers', false ); |
3625 | | - $log->addEntry( 'autocreate', $this->getUserPage(), '', array( $this->getId() ) ); |
| 3612 | + $log->addEntry( |
| 3613 | + 'autocreate', |
| 3614 | + $this->getUserPage(), |
| 3615 | + '', |
| 3616 | + array( $this->getId() ), |
| 3617 | + $this->getId() |
| 3618 | + ); |
3626 | 3619 | return true; |
3627 | 3620 | } |
3628 | 3621 | |
Index: trunk/phase3/includes/OutputPage.php |
— | — | @@ -2555,28 +2555,29 @@ |
2556 | 2556 | // Legacy Scripts |
2557 | 2557 | $scripts .= "\n" . $this->mScripts; |
2558 | 2558 | |
| 2559 | + $userScripts = array( 'user.options' ); |
| 2560 | + |
2559 | 2561 | // Add site JS if enabled |
2560 | 2562 | if ( $wgUseSiteJs ) { |
2561 | 2563 | $scripts .= $this->makeResourceLoaderLink( $sk, 'site', ResourceLoaderModule::TYPE_SCRIPTS ); |
| 2564 | + if( $wgUser->isLoggedIn() ){ |
| 2565 | + $userScripts[] = 'user.groups'; |
| 2566 | + } |
2562 | 2567 | } |
2563 | 2568 | |
2564 | | - // Add user JS if enabled - trying to load user.options as a bundle if possible |
2565 | | - $userOptionsAdded = false; |
| 2569 | + // Add user JS if enabled |
2566 | 2570 | if ( $wgAllowUserJs && $wgUser->isLoggedIn() ) { |
2567 | 2571 | $action = $wgRequest->getVal( 'action', 'view' ); |
2568 | 2572 | if( $this->mTitle && $this->mTitle->isJsSubpage() && $sk->userCanPreview( $action ) ) { |
2569 | 2573 | # XXX: additional security check/prompt? |
2570 | 2574 | $scripts .= Html::inlineScript( "\n" . $wgRequest->getText( 'wpTextbox1' ) . "\n" ) . "\n"; |
2571 | 2575 | } else { |
2572 | | - $scripts .= $this->makeResourceLoaderLink( |
2573 | | - $sk, array( 'user', 'user.options' ), ResourceLoaderModule::TYPE_SCRIPTS |
2574 | | - ); |
2575 | | - $userOptionsAdded = true; |
| 2576 | + # FIXME: this means that User:Me/Common.js doesn't load when previewing |
| 2577 | + # User:Me/Vector.js, and vice versa (bug26283) |
| 2578 | + $userScripts[] = 'user'; |
2576 | 2579 | } |
2577 | 2580 | } |
2578 | | - if ( !$userOptionsAdded ) { |
2579 | | - $scripts .= $this->makeResourceLoaderLink( $sk, 'user.options', ResourceLoaderModule::TYPE_SCRIPTS ); |
2580 | | - } |
| 2581 | + $scripts .= $this->makeResourceLoaderLink( $sk, $userScripts, ResourceLoaderModule::TYPE_SCRIPTS ); |
2581 | 2582 | |
2582 | 2583 | return $scripts; |
2583 | 2584 | } |