Index: trunk/extensions/CreateRedirect/CreateRedirect.body.php |
— | — | @@ -0,0 +1,189 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +/* |
| 5 | + * MediaWiki Extension |
| 6 | + * CreateRedirect |
| 7 | + * By Marco Zafra ("Digi") |
| 8 | + * Started: September 18, 2007 |
| 9 | + * |
| 10 | + * Adds a special page that eases creation of redirects via a simple form. Also adds a menu item to the sidebar as a shortcut. |
| 11 | + * |
| 12 | + * This program, CreateRedirect, is Copyright (C) 2007 Marco Zafra. CreateRedirect is released under the GNU Lesser General Public License version 3. |
| 13 | + * |
| 14 | + * This file is part of CreateRedirect. See the main file ("CreateRedirect.setup.php") for additional information. |
| 15 | + * |
| 16 | + * CreateRedirect is free software: you can redistribute it and/or modify |
| 17 | + * it under the terms of the GNU Lesser General Public License as published by |
| 18 | + * the Free Software Foundation, either version 3 of the License, or |
| 19 | + * (at your option) any later version. |
| 20 | + */ |
| 21 | + |
| 22 | +/* Body file: |
| 23 | + * The bulk of the routines are stored here. This is where all the internal processing actually occurs. |
| 24 | + */ |
| 25 | + |
| 26 | +# Alert the user that this is not a valid entry point to MediaWiki if they try to access the file directly. |
| 27 | +if (!defined('MEDIAWIKI')) { |
| 28 | + echo <<<EOT |
| 29 | +To install the CreateRedirect extension, put the following line in LocalSettings.php: |
| 30 | +require_once( "$IP/extensions/CreateRedirect/CreateRedirect.setup.php" ); |
| 31 | +EOT; |
| 32 | + exit( 1 ); |
| 33 | +} |
| 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 | + } |
| 43 | + |
| 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; |
| 55 | + } |
| 56 | + |
| 57 | + function execute( $par ) { |
| 58 | + global $wgRequest, $wgOut, $wgTitle, $wgUser; |
| 59 | + |
| 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. |
| 61 | + $this->setHeaders(); |
| 62 | + $output = ""; |
| 63 | + |
| 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! |
| 98 | + // 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 | + $crOrigTitle = $wgRequest->getText("crOrigTitle"); |
| 100 | + $crRedirectTitle = $wgRequest->getText("crRedirectTitle"); |
| 101 | + |
| 102 | + // 2. We need to construct a "FauxRequest", or fake a request that MediaWiki would otherwise get naturally by a client browser to do whatever it has to do. Let's put together the params. |
| 103 | + $title = $crOrigTitle; |
| 104 | + // a. We know our title, so we can instantiate a "Title" and "Article" object. We don't actually plug this into the FauxRequest, but they're required for the writing process, and they contain important information on the article in question that's being edited. |
| 105 | + $crEditTitle = Title::newFromText($crOrigTitle); // First, construct "Title". "Article" relies on the former object being set. |
| 106 | + $crEditArticle = new Article($crEditTitle, 0); // Then, construct "Article". This is where most of the article's information is. |
| 107 | + $wpStarttime = wfTimestampNow(); // POST var "wpStarttime" stores when the edit was started. |
| 108 | + $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. |
| 110 | + $wpSave = 1; |
| 111 | + $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 | + $wpEditToken = htmlspecialchars($wgUser->editToken()); |
| 113 | + |
| 114 | + // 3. Put together the params that we'll use in "FauxRequest" into a single array. |
| 115 | + $crRequestParams = array( |
| 116 | + 'title' => $title, |
| 117 | + 'wpStarttime' => $wpStarttime, |
| 118 | + 'wpEdittime' => $wpEdittime, |
| 119 | + 'wpTextbox1' => $wpTextbox1, |
| 120 | + 'wpSave' => $wpSave, |
| 121 | + 'wpMinoredit' => $wpMinoredit, |
| 122 | + 'wpEditToken' => $wpEditToken |
| 123 | + ); |
| 124 | + |
| 125 | + // 4. Construct "FauxRequest"! Using a FauxRequest object allows for a transparent interface of generated request params that aren't retrieved from the client itself (i.e. $_REQUEST). It's a very useful tool. |
| 126 | + $crRequest = new FauxRequest($crRequestParams, true); |
| 127 | + |
| 128 | + // 5. Construct "EditPage", which contains routines to write all the data. This is where all the magic happens. |
| 129 | + $crEdit = new EditPage($crEditArticle); // We plug in the "Article" object here so EditPage can center on the article that we need to edit. |
| 130 | + // a. We have to plug in the correct information that we just generated. While we fed EditPage with the correct "Article" object, it doesn't have the correct "Title" object. The "Title" object actually points to Special:Createredirect, which don't do us any good. Instead, explicitly plug in the correct objects; the objects "Article" and "Title" that we generated earlier. This will center EditPage on the correct article. |
| 131 | + $crEdit->mArticle = $crEditArticle; |
| 132 | + $crEdit->mTitle = $crEditTitle; |
| 133 | + // b. Then import the "form data" (or the FauxRequest object that we just constructed). EditPage now has all the information we generated. |
| 134 | + $crEdit->importFormData($crRequest); |
| 135 | + |
| 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(); |
| 140 | + } |
| 141 | + |
| 142 | + $output .= "ERROR: Authentication failed."; |
| 143 | + |
| 144 | + // TODO: Implement error handling (i.e. "Edit conflict!" or "You don't have permissions to edit this page!") --Digi 11/4/07 |
| 145 | + } |
| 146 | + |
| 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); |
| 159 | + |
| 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 | + } |
| 169 | + |
| 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 | + } |
| 177 | + } |
| 178 | + } |
| 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 | + } |
| 188 | + } |
| 189 | + |
| 190 | +} |
Property changes on: trunk/extensions/CreateRedirect/CreateRedirect.body.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 191 | + native |
Index: trunk/extensions/CreateRedirect/CreateRedirect.i18n.php |
— | — | @@ -0,0 +1,42 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +/* |
| 5 | + * MediaWiki Extension |
| 6 | + * CreateRedirect |
| 7 | + * By Marco Zafra ("Digi") |
| 8 | + * Started: September 18, 2007 |
| 9 | + * |
| 10 | + * Adds a special page that eases creation of redirects via a simple form. Also adds a menu item to the sidebar as a shortcut. |
| 11 | + * |
| 12 | + * This program, CreateRedirect, is Copyright (C) 2007 Marco Zafra. CreateRedirect is released under the GNU Lesser General Public License version 3. |
| 13 | + * |
| 14 | + * This file is part of CreateRedirect. See the main file ("CreateRedirect.setup.php") for additional information. |
| 15 | + * |
| 16 | + * CreateRedirect is free software: you can redistribute it and/or modify |
| 17 | + * it under the terms of the GNU Lesser General Public License as published by |
| 18 | + * the Free Software Foundation, either version 3 of the License, or |
| 19 | + * (at your option) any later version. |
| 20 | + */ |
| 21 | + |
| 22 | +/* i18n (Internationalization) file: |
| 23 | + * Contains messages that are translated in multiple languages. |
| 24 | + */ |
| 25 | + |
| 26 | +# Alert the user that this is not a valid entry point to MediaWiki if they try to access the file directly. |
| 27 | +if (!defined('MEDIAWIKI')) { |
| 28 | + echo <<<EOT |
| 29 | +To install the CreateRedirect extension, put the following line in LocalSettings.php: |
| 30 | +require_once( "$IP/extensions/CreateRedirect/CreateRedirect.setup.php" ); |
| 31 | +EOT; |
| 32 | + exit( 1 ); |
| 33 | +} |
| 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 | + ) |
| 43 | +); |
Property changes on: trunk/extensions/CreateRedirect/CreateRedirect.i18n.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 44 | + native |
Index: trunk/extensions/CreateRedirect/CreateRedirect.setup.php |
— | — | @@ -0,0 +1,101 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +/* |
| 5 | + * MediaWiki Extension |
| 6 | + * CreateRedirect |
| 7 | + * By Marco Zafra ("Digi") |
| 8 | + * Started: September 18, 2007 |
| 9 | + * |
| 10 | + * Adds a special page that eases creation of redirects via a simple form. Also adds a menu item to the sidebar as a shortcut. |
| 11 | + * |
| 12 | + * This program, CreateRedirect, is Copyright (C) 2007 Marco Zafra. CreateRedirect is released under the GNU Lesser General Public License version 3. |
| 13 | + * |
| 14 | + * This file is part of CreateRedirect. |
| 15 | + * |
| 16 | + * CreateRedirect is free software: you can redistribute it and/or modify |
| 17 | + * it under the terms of the GNU Lesser General Public License as published by |
| 18 | + * the Free Software Foundation, either version 3 of the License, or |
| 19 | + * (at your option) any later version. |
| 20 | + * |
| 21 | + * CreateRedirect is distributed in the hope that it will be useful, |
| 22 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 23 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 24 | + * GNU Lesser General Public License for more details. |
| 25 | + * |
| 26 | + * You should have received a copy of the GNU Lesser General Public License |
| 27 | + * along with CreateRedirect. If not, see <http://www.gnu.org/licenses/>. |
| 28 | + */ |
| 29 | + |
| 30 | +/* Setup file: |
| 31 | + * Performs setup routines to hook the extension up to MediaWiki. |
| 32 | + */ |
| 33 | + |
| 34 | +# Alert the user that this is not a valid entry point to MediaWiki if they try to access the file directly. |
| 35 | +if (!defined('MEDIAWIKI')) { |
| 36 | + echo <<<EOT |
| 37 | +To install the CreateRedirect extension, put the following line in LocalSettings.php: |
| 38 | +require_once( "$IP/extensions/CreateRedirect/CreateRedirect.setup.php" ); |
| 39 | +EOT; |
| 40 | + exit( 1 ); |
| 41 | +} |
| 42 | + |
| 43 | +# Add this extension to Special:Credits. |
| 44 | +$wgExtensionCredits['specialpage'][] = array( |
| 45 | + 'name' => 'CreateRedirect', |
| 46 | + 'author' => 'Digiku', |
| 47 | + 'version' => 1.0, |
| 48 | + 'description' => 'Adds [[Special:CreateRedirect]] to easily create redirects.' |
| 49 | +); |
| 50 | + |
| 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. |
| 56 | + |
| 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 | +# Other hooks. |
| 70 | +$wgHooks['MonoBookTemplateToolboxEnd'][] = 'createRedirect_addToolboxLink'; # Add a shortcut link to the sidebar menu in Monobook; specifically the toolbox. |
| 71 | + |
| 72 | +/* |
| 73 | + * 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 | + * Params: None |
| 75 | + * Returns: true |
| 76 | + */ |
| 77 | +function createRedirect_AddToolboxLink() { |
| 78 | + global $wgRequest, $wgOut, $wgScript; |
| 79 | + |
| 80 | + // 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 | + // 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; } |
| 87 | + |
| 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 | + // 4. Add the link! |
| 98 | + $finalItem = "<li><a href=\"" . $wgScript . "?title=Special:Createredirect$crTitle\">Create redirect</a></li>"; |
| 99 | + echo $finalItem; |
| 100 | + |
| 101 | + return true; |
| 102 | +} |
Property changes on: trunk/extensions/CreateRedirect/CreateRedirect.setup.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 103 | + native |