Index: trunk/extensions/CreateRedirect/CreateRedirect.body.php |
— | — | @@ -26,74 +26,28 @@ |
27 | 27 | if (!defined('MEDIAWIKI')) { |
28 | 28 | echo <<<EOT |
29 | 29 | To install the CreateRedirect extension, put the following line in LocalSettings.php: |
30 | | -require_once( "$IP/extensions/CreateRedirect/CreateRedirect.setup.php" ); |
| 30 | +require_once( "$IP/extensions/CreateRedirect/CreateRedirect.php" ); |
31 | 31 | EOT; |
32 | 32 | exit( 1 ); |
33 | 33 | } |
34 | 34 | |
35 | | -class CreateRedirect extends SpecialPage |
36 | | -{ |
37 | | - function CreateRedirect() { |
38 | | - SpecialPage::SpecialPage("Createredirect", "", true); |
39 | | - self::loadMessages(); |
40 | | - |
41 | | - $title_text = wfMsg('cr_title'); |
42 | | - } |
| 35 | +class SpecialCreateRedirect extends SpecialPage { |
43 | 36 | |
44 | | - function loadMessages() { |
45 | | - static $messagesLoaded = false; |
46 | | - global $wgMessageCache; |
47 | | - if ( $messagesLoaded ) return; |
48 | | - $messagesLoaded = true; |
49 | | - |
50 | | - require_once( dirname( __FILE__ ) . '/CreateRedirect.i18n.php' ); |
51 | | - foreach ( $allMessages as $lang => $langMessages ) { |
52 | | - $wgMessageCache->addMessages( $langMessages, $lang ); |
53 | | - } |
54 | | - return true; |
| 37 | + function __construct() { |
| 38 | + parent::__construct("CreateRedirect"); |
55 | 39 | } |
56 | 40 | |
57 | 41 | function execute( $par ) { |
58 | | - global $wgRequest, $wgOut, $wgTitle, $wgUser; |
| 42 | + global $wgRequest, $wgOut, $wgUser; |
59 | 43 | |
60 | | - // 1. Do some prep stuff. We call $this->setHeaders() (a method of SpecialPage) for the page, and we also initialize $output, which will hold the text output to serve with the page. |
| 44 | + if( wfReadOnly() ) { |
| 45 | + $wgOut->readOnlyPage(); |
| 46 | + return; |
| 47 | + } |
| 48 | + |
61 | 49 | $this->setHeaders(); |
62 | | - $output = ""; |
63 | 50 | |
64 | | - // 2. Break from here: "crWrite" determines whether we're serving the form or we're performing the write routine. We send it along with the form on submission, so if we see a POST var "crWrite", then we've got form data to process; if it's not there, then we don't have form data to process, and we have to serve the form. |
65 | | - if(!$wgRequest->getVal('crWrite')) { // Serve the form! |
66 | | - // 1. Get the local URL for the "action" param, used by <form>. This points the form back to this page (again), where if crWrite exists (which it does,) we process the submitted form. |
67 | | - $action = $wgTitle->escapeLocalURL(); |
68 | | - $crTitle = $wgRequest->getText("crTitle"); // Also retrieve "crTitle". If this GET var is found, we autofill the "Redirect to:" field with that text. |
69 | | - |
70 | | - // 2. Start rendering the output! The output is entirely the form. It's all HTML, and may be self-explanatory. |
71 | | - $output .= "<p>Using the form below, you can create a redirect page or replace an existing page with a redirect.</p>"; |
72 | | - $output .= <<<END |
73 | | -<form id="redirectform" name="redirectform" method="post" action="$action" enctype="multipart/form-data"> |
74 | | -<table> |
75 | | -<tr> |
76 | | -<td><label for="crOrigTitle">Page title:</label></td> |
77 | | -<td><input type="text" name="crOrigTitle" id="crOrigTitle" size="60" tabindex="1" /></td> |
78 | | -</tr> |
79 | | -<tr> |
80 | | -<td><label for="crRedirectTitle">Redirect to:</label></td> |
81 | | -<td><input type="text" name="crRedirectTitle" id="crRedirectTitle" value="{$crTitle}" size="60" tabindex="2" /></td> |
82 | | -</tr> |
83 | | -<tr> |
84 | | -<td /> |
85 | | -<td><input type="submit" name="crWrite" id="crWrite" value="Save page" tabindex="4" /></td> |
86 | | -</tr> |
87 | | -</table> |
88 | | -</form> |
89 | | -END; |
90 | | - $output .= <<<END |
91 | | -<script language="javascript"> |
92 | | -//<![CDATA[ |
93 | | -document.redirectform.crOrigTitle.focus(); |
94 | | -//]]> |
95 | | -</script> |
96 | | -END; |
97 | | - } else { // Process submitted form data! |
| 51 | + if ( $wgRequest->wasPosted() ) { |
98 | 52 | // 1. Retrieve POST vars. First, we want "crOrigTitle", holding the title of the page we're writing to, and "crRedirectTitle", holding the title of the page we're redirecting to. |
99 | 53 | $crOrigTitle = $wgRequest->getText("crOrigTitle"); |
100 | 54 | $crRedirectTitle = $wgRequest->getText("crRedirectTitle"); |
— | — | @@ -105,7 +59,7 @@ |
106 | 60 | $crEditArticle = new Article($crEditTitle, 0); // Then, construct "Article". This is where most of the article's information is. |
107 | 61 | $wpStarttime = wfTimestampNow(); // POST var "wpStarttime" stores when the edit was started. |
108 | 62 | $wpEdittime = $crEditArticle->getTimestamp(); // POST var "wpEdittime" stores when the article was ''last edited''. This is used to check against edit conflicts, and also why we needed to construct "Article" so early. "Article" contains the article's last edittime. |
109 | | - $wpTextbox1 = "#REDIRECT[[$crRedirectTitle]]"."\r\n"; // POST var "wpTextbox1" stores the content that's actually going to be written. This is where we write the #REDIRECT[[Article]] stuff. We plug in $crRedirectTitle here. |
| 63 | + $wpTextbox1 = "#REDIRECT [[$crRedirectTitle]]"."\r\n"; // POST var "wpTextbox1" stores the content that's actually going to be written. This is where we write the #REDIRECT[[Article]] stuff. We plug in $crRedirectTitle here. |
110 | 64 | $wpSave = 1; |
111 | 65 | $wpMinoredit = 1; // TODO: Decide on this; should this really be marked and hardcoded as a minor edit, or not? Or should we provide an option? --Digi 11/4/07 |
112 | 66 | $wpEditToken = htmlspecialchars($wgUser->editToken()); |
— | — | @@ -132,58 +86,85 @@ |
133 | 87 | // b. Then import the "form data" (or the FauxRequest object that we just constructed). EditPage now has all the information we generated. |
134 | 88 | $crEdit->importFormData($crRequest); |
135 | 89 | |
136 | | - // 6. Write the data! |
137 | | - |
138 | | - if($this->checkUserPermissions($crEdit)) { // WORKAROUND: Since EditPage::attemptSave() doesn't actually check user permissions, and EditPage::edit() imports its own form data (hence we can't use it,) we have to reimplement user permission checking. See CreateRedirect::checkUserPermissions(). --Digi 11/5/07 |
139 | | - $crEdit->attemptSave(); |
| 90 | + $permErrors = $crEditTitle->getUserPermissionsErrors( 'edit', $wgUser ); |
| 91 | + # Can this title be created? |
| 92 | + if ( !$crEditTitle->exists() ) { |
| 93 | + $permErrors = array_merge( $permErrors, |
| 94 | + wfArrayDiff2( $crEditTitle->getUserPermissionsErrors( 'create', $wgUser ), $permErrors ) ); |
140 | 95 | } |
| 96 | + if ( $permErrors ) { |
| 97 | + wfDebug( __METHOD__ . ": User can't edit\n" ); |
| 98 | + $wgOut->addWikiText( $crEdit->formatPermissionsErrorMessage( $permErrors, 'edit' ) ); |
| 99 | + wfProfileOut( __METHOD__ ); |
| 100 | + return; |
| 101 | + } |
141 | 102 | |
142 | | - $output .= "ERROR: Authentication failed."; |
| 103 | + $resultDetails = false; |
| 104 | + $value = $crEdit->internalAttemptSave( $resultDetails, $wgUser->isAllowed( 'bot' ) && $wgRequest->getBool('bot', true) ); |
143 | 105 | |
144 | | - // TODO: Implement error handling (i.e. "Edit conflict!" or "You don't have permissions to edit this page!") --Digi 11/4/07 |
145 | | - } |
| 106 | + if ( $value == EditPage::AS_SUCCESS_UPDATE || $value == EditPage::AS_SUCCESS_NEW_ARTICLE ) { |
| 107 | + $wgOut->wrapWikiMsg( "<div class=\"mw-createredirect-done\">\n$1</div>", array( 'crredirectdone', $crOrigTitle, $crRedirectTitle ) ); |
| 108 | + } |
| 109 | + |
| 110 | + switch ( $value ) { |
| 111 | + case EditPage::AS_SPAM_ERROR: |
| 112 | + $crEdit->spamPage( $resultDetails['spam'] ); |
| 113 | + return; |
146 | 114 | |
147 | | - // Return $output so as to serve the page. Note that we only reach this if we haven't processed form data; if we processed form data, then we don't reach this. |
148 | | - $wgOut->addHTML( $output ); |
149 | | - } |
150 | | - |
151 | | - function checkUserPermissions(&$crEdit) { |
152 | | - // I can't believe I have to do this, but I have to reimplement user permission checking from EditPage::edit();. What prevents me from using the method is one line: it performs importFormData($wgRequest), even though we have to use a different request object. --Digi 11/5/07 |
153 | | - // The below is (almost) verbatim copying from MediaWiki 1.11.0, "/includes/EditPage.php", save minor changes to get everything working. |
154 | | - global $wgUser, $wgOut; |
155 | | - |
156 | | - $permErrors = $crEdit->mTitle->getUserPermissionsErrors( 'edit', $wgUser); |
157 | | - if( !$crEdit->mTitle->exists() ) |
158 | | - $permErrors += $crEdit->mTitle->getUserPermissionsErrors( 'create', $wgUser); |
| 115 | + case EditPage::AS_BLOCKED_PAGE_FOR_USER: |
| 116 | + $crEdit->blockedPage(); |
| 117 | + return; |
159 | 118 | |
160 | | - # Ignore some permissions errors. |
161 | | - $remove = array(); |
162 | | - foreach( $permErrors as $error ) { |
163 | | - if ($crEdit->preview || $crEdit->diff && |
164 | | - ($error[0] == 'blockedtext' || $error[0] == 'autoblockedtext')) |
165 | | - { |
166 | | - // Don't worry about blocks when previewing/diffing |
167 | | - $remove[] = $error; |
168 | | - } |
| 119 | + case EditPage::AS_READ_ONLY_PAGE_ANON: |
| 120 | + $crEdit->userNotLoggedInPage(); |
| 121 | + return; |
169 | 122 | |
170 | | - if ($error[0] == 'readonlytext') |
171 | | - { |
172 | | - if ($crEdit->edit) { |
173 | | - $crEdit->formtype = 'preview'; |
174 | | - } elseif ($crEdit->save || $crEdit->preview || $crEdit->diff) { |
175 | | - $remove[] = $error; |
176 | | - } |
| 123 | + case EditPage::AS_READ_ONLY_PAGE_LOGGED: |
| 124 | + case EditPage::AS_READ_ONLY_PAGE: |
| 125 | + $wgOut->readOnlyPage(); |
| 126 | + return; |
| 127 | + |
| 128 | + case EditPage::AS_RATE_LIMITED: |
| 129 | + $wgOut->rateLimited(); |
| 130 | + break; |
| 131 | + |
| 132 | + case EditPage::AS_NO_CREATE_PERMISSION: |
| 133 | + $crEdit->noCreatePermission(); |
| 134 | + return; |
177 | 135 | } |
| 136 | + |
| 137 | + $wgOut->mRedirect = ''; |
| 138 | + $wgOut->mRedirectCode = ''; |
| 139 | + |
| 140 | + // TODO: Implement error handling (i.e. "Edit conflict!" or "You don't have permissions to edit this page!") --Digi 11/4/07 |
178 | 141 | } |
179 | | - # array_diff returns elements in $permErrors that are not in $remove. |
180 | | - $permErrors = array_diff( $permErrors, $remove ); |
181 | | - |
182 | | - if ( !empty($permErrors) ) |
183 | | - { |
184 | | - return false; |
185 | | - } else { |
186 | | - return true; |
187 | | - } |
| 142 | + |
| 143 | + $action = htmlspecialchars($this->getTitle()->getLocalURL()); |
| 144 | + $crTitle = $wgRequest->getText("crRedirectTitle", $wgRequest->getText("crTitle", $par)); // Also retrieve "crTitle". If this GET var is found, we autofill the "Redirect to:" field with that text. |
| 145 | + $crTitle = Title::newFromText($crTitle); |
| 146 | + $crTitle = htmlspecialchars(isset($crTitle) ? $crTitle->getPrefixedText() : ""); |
| 147 | + |
| 148 | + // 2. Start rendering the output! The output is entirely the form. It's all HTML, and may be self-explanatory. |
| 149 | + $wgOut->addHTML( "<p>Using the form below, you can create a redirect page or replace an existing page with a redirect.</p>" ); |
| 150 | + $wgOut->addHTML( <<<END |
| 151 | +<form id="redirectform" name="redirectform" method="post" action="$action"> |
| 152 | +<table> |
| 153 | +<tr> |
| 154 | +<td><label for="crOrigTitle">Page title:</label></td> |
| 155 | +<td><input type="text" name="crOrigTitle" id="crOrigTitle" size="60" tabindex="1" /></td> |
| 156 | +</tr> |
| 157 | +<tr> |
| 158 | +<td><label for="crRedirectTitle">Redirect to:</label></td> |
| 159 | +<td><input type="text" name="crRedirectTitle" id="crRedirectTitle" value="{$crTitle}" size="60" tabindex="2" /></td> |
| 160 | +</tr> |
| 161 | +<tr> |
| 162 | +<td></td> |
| 163 | +<td><input type="submit" name="crWrite" id="crWrite" value="Save page" tabindex="4" /></td> |
| 164 | +</tr> |
| 165 | +</table> |
| 166 | +</form> |
| 167 | +END |
| 168 | + ); |
188 | 169 | } |
189 | | - |
| 170 | + |
190 | 171 | } |
Index: trunk/extensions/CreateRedirect/CreateRedirect.i18n.php |
— | — | @@ -26,17 +26,19 @@ |
27 | 27 | if (!defined('MEDIAWIKI')) { |
28 | 28 | echo <<<EOT |
29 | 29 | To install the CreateRedirect extension, put the following line in LocalSettings.php: |
30 | | -require_once( "$IP/extensions/CreateRedirect/CreateRedirect.setup.php" ); |
| 30 | +require_once( "$IP/extensions/CreateRedirect/CreateRedirect.php" ); |
31 | 31 | EOT; |
32 | 32 | exit( 1 ); |
33 | 33 | } |
34 | 34 | |
35 | | -$allMessages = array( |
36 | | - 'en' => array( |
37 | | - "createredirect" => "Create redirect", |
38 | | - "crmsgform" => "Using the form below, you can create a redirect page or replace an existing page with a redirect.", |
39 | | - "crorigtitle" => "Page title:", |
40 | | - "crredirecttitle" => "Redirect to:", |
41 | | - "crerror" => "ERROR: Authentication failed." // TODO: Figure out error cases. One message just is not going to do. --Digi 11/5/07 |
42 | | - ) |
| 35 | +$messages = array(); |
| 36 | + |
| 37 | +$messages['en'] = array( |
| 38 | + "createredirect" => "Create Redirect", |
| 39 | + "crmsgform" => "Using the form below, you can create a redirect page or replace an existing page with a redirect.", |
| 40 | + "crorigtitle" => "Page title:", |
| 41 | + "crredirecttitle" => "Redirect to:", |
| 42 | + "crredirectdone" => "Redirect created from $1 to $2", |
| 43 | + "crerror" => "ERROR: Authentication failed." // TODO: Figure out error cases. One message just is not going to do. --Digi 11/5/07 |
43 | 44 | ); |
| 45 | + |
Index: trunk/extensions/CreateRedirect/CreateRedirect.php |
— | — | @@ -48,25 +48,14 @@ |
49 | 49 | ); |
50 | 50 | |
51 | 51 | # Set up the actual extension functionality. |
52 | | -$wgAutoloadClasses['CreateRedirect'] = dirname(__FILE__) . '/CreateRedirect.body.php'; # Tell MediaWiki to load the extension body. |
53 | | -$wgSpecialPages['Createredirect'] = 'CreateRedirect'; # Let MediaWiki know about your new special page. |
54 | | -$wgHooks['LoadAllMessages'][] = 'CreateRedirect::loadMessages'; # Load the internationalization messages for your special page. |
55 | | -$wgHooks['LanguageGetSpecialPageAliases'][] = 'createRedirect_LanguageGetSpecialPageAliases'; # Add any aliases for the special page. |
| 52 | +$wgAutoloadClasses['SpecialCreateRedirect'] = dirname(__FILE__) . '/CreateRedirect.body.php'; # Tell MediaWiki to load the extension body. |
| 53 | +$wgSpecialPages['CreateRedirect'] = 'SpecialCreateRedirect'; # Let MediaWiki know about your new special page. |
| 54 | +$wgSpecialPageGroups['CreateRedirect'] = 'pagetools'; |
| 55 | +$wgExtensionMessagesFiles['CreateRedirect'] = dirname(__FILE__) . '/CreateRedirect.i18n.php'; |
| 56 | +$wgExtensionAliasesFiles['CreateRedirect'] = dirname(__FILE__) . '/CreateRedirect.alias.php'; |
56 | 57 | |
57 | | -function createRedirect_LanguageGetSpecialPageAliases(&$specialPageArray, $code) { |
58 | | - # The localized title of the special page is among the messages of the extension: |
59 | | - CreateRedirect::loadMessages(); |
60 | | - $text = wfMsg('createredirect'); |
61 | | - |
62 | | - # Convert from title in text form to DBKey and put it into the alias array: |
63 | | - $title = Title::newFromText($text); |
64 | | - $specialPageArray['CreateRedirect'][] = $title->getDBKey(); |
65 | | - |
66 | | - return true; |
67 | | -} |
68 | | - |
69 | 58 | # Other hooks. |
70 | | -$wgHooks['MonoBookTemplateToolboxEnd'][] = 'createRedirect_addToolboxLink'; # Add a shortcut link to the sidebar menu in Monobook; specifically the toolbox. |
| 59 | +$wgHooks['SkinTemplateToolboxEnd'][] = 'createRedirect_addToolboxLink'; # Add a shortcut link to the sidebar menu in Monobook; specifically the toolbox. |
71 | 60 | |
72 | 61 | /* |
73 | 62 | * createRedirect_AddToolboxLink(): Adds to the "toolbox" menu in the Monobook skin a shortcut link pointing to Special:Createredirect. If applicable, also adds a reference to the current title as a GET param. |
— | — | @@ -74,28 +63,17 @@ |
75 | 64 | * Returns: true |
76 | 65 | */ |
77 | 66 | function createRedirect_AddToolboxLink() { |
78 | | - global $wgRequest, $wgOut, $wgScript; |
| 67 | + global $wgRequest, $wgOut, $wgScript, $wgTitle; |
79 | 68 | |
80 | 69 | // 1. Determine whether to actually add the link at all. There are certain cases, e.g. in the edit dialog, in a special page, where it's inappropriate for the link to appear. |
81 | | - // First, see if "action" exists. If there's an "action" parameter in the URL, we assume that to mean "action=edit" or any other thing. In which case, we don't display the link. |
82 | | - if($wgRequest->getText("action")) { return true; } |
83 | | - |
84 | 70 | // 2. Check the title. Is it a "Special:" page? Don't display the link. |
85 | | - $title = $wgRequest->getText("title"); // We use this for more than one thing. |
86 | | - if(strpos($title, "Special:") === 0) { return true; } |
| 71 | + $action = $wgRequest->getText("action", "view"); |
| 72 | + if( $action != "view" && $action != "purge" && !$wgTitle->isSpecialPage() ) |
| 73 | + return true; |
87 | 74 | |
88 | | - // TODO: Determine better ways to detect cases to not display the link. --Digi 11/4/07 |
89 | | - |
90 | | - // 3. Are we still here? Good; we can display the link! If $title exists, we pass that as a GET var; the special page can automatically fill in a field using that var. |
91 | | - if($title) { |
92 | | - $crTitle = "&crTitle=$title"; |
93 | | - } else { |
94 | | - $crTitle = ""; |
95 | | - } |
96 | | - |
97 | 75 | // 4. Add the link! |
98 | | - $finalItem = "<li><a href=\"" . $wgScript . "?title=Special:Createredirect$crTitle\">Create redirect</a></li>"; |
99 | | - echo $finalItem; |
| 76 | + $href = SpecialPage::getTitleFor('CreateRedirect', $wgTitle->getPrefixedText())->getLocalURL(); |
| 77 | + echo Html::rawElement( 'li', null, Html::element( 'a', array( 'href' => $href ), wfMsg('createredirect') ) ); |
100 | 78 | |
101 | 79 | return true; |
102 | 80 | } |