Index: trunk/extensions/Translate/tag/SpecialPageTranslationDeletePage.php |
— | — | @@ -0,0 +1,355 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Special page which enables deleting translations of translatable pages |
| 5 | + * |
| 6 | + * @file |
| 7 | + * @author Niklas Laxström |
| 8 | + * @copyright Copyright © 2011, Niklas Laxström |
| 9 | + * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later |
| 10 | + */ |
| 11 | + |
| 12 | +/** |
| 13 | + * Special page which enables deleting translations of translatable pages |
| 14 | + * |
| 15 | + * @ingroup SpecialPage |
| 16 | + * @ingroup PageTranslation |
| 17 | + */ |
| 18 | +class SpecialPageTranslationDeletePage extends SpecialPage { |
| 19 | + // Basic form parameters both as text and as titles |
| 20 | + protected $text, $title; |
| 21 | + |
| 22 | + // Other form parameters |
| 23 | + /// 'check' or 'perform' |
| 24 | + protected $subaction; |
| 25 | + |
| 26 | + /// There must be reason for everything. |
| 27 | + protected $reason; |
| 28 | + |
| 29 | + /// Allow skipping non-translation subpages. |
| 30 | + protected $doSubpages = false; |
| 31 | + |
| 32 | + |
| 33 | + /// TranslatablePage instance. |
| 34 | + protected $page; |
| 35 | + /// Contains the language code if we are working with translation page |
| 36 | + protected $code; |
| 37 | + |
| 38 | + /// User instance. |
| 39 | + protected $user; |
| 40 | + |
| 41 | + public function __construct() { |
| 42 | + parent::__construct( 'PageTranslationDeletePage' ); |
| 43 | + } |
| 44 | + |
| 45 | + public function execute( $par ) { |
| 46 | + global $wgOut, $wgRequest, $wgUser; |
| 47 | + |
| 48 | + // Yes, the use of getVal() and getText() is wanted, see bug 20365 |
| 49 | + $this->text = $wgRequest->getVal( 'wpTitle', $par ); |
| 50 | + $this->title = Title::newFromText( $this->text ); |
| 51 | + $this->reason = $wgRequest->getText( 'reason' ); |
| 52 | + // Checkboxes that default being checked are tricky |
| 53 | + $this->doSubpages = $wgRequest->getBool( 'subpages', !$wgRequest->wasPosted() ); |
| 54 | + |
| 55 | + $this->user = $wgUser; |
| 56 | + |
| 57 | + if ( $this->doBasicChecks() !== true ) { |
| 58 | + return; |
| 59 | + } |
| 60 | + |
| 61 | + // Real stuff starts here |
| 62 | + if ( TranslatablePage::isSourcePage( $this->title ) ) { |
| 63 | + $wgOut->setPagetitle( wfMsg( 'pt-deletepage-full-title', $this->title->getPrefixedText() ) ); |
| 64 | + |
| 65 | + $this->code = ''; |
| 66 | + $this->page = TranslatablePage::newFromTitle( $this->title ); |
| 67 | + } else { |
| 68 | + $page = TranslatablePage::isTranslationPage( $this->title ); |
| 69 | + if ( $page ) { |
| 70 | + $wgOut->setPagetitle( wfMsg( 'pt-deletepage-lang-title', $this->title->getPrefixedText() ) ); |
| 71 | + |
| 72 | + list( , $this->code ) = TranslateUtils::figureMessage( $this->title->getText() ); |
| 73 | + $this->page = $page; |
| 74 | + } else { |
| 75 | + $wgOut->showErrorPage( 'pt-deletepage-invalid-title', 'pt-deletepage-invalid-text' ); |
| 76 | + return; |
| 77 | + } |
| 78 | + } |
| 79 | + |
| 80 | + if ( !$this->user->isAllowed( 'pagetranslation' ) ) { |
| 81 | + $wgOut->permissionRequired( 'pagetranslation' ); |
| 82 | + return; |
| 83 | + } |
| 84 | + |
| 85 | + // Is there really no better way to do this? |
| 86 | + $subactionText = $wgRequest->getText( 'subaction' ); |
| 87 | + switch ( $subactionText ) { |
| 88 | + case wfMsg( 'pt-deletepage-action-check' ): |
| 89 | + $subaction = 'check'; break; |
| 90 | + case wfMsg( 'pt-deletepage-action-perform' ): |
| 91 | + $subaction = 'perform'; break; |
| 92 | + case wfMsg( 'pt-deletepage-action-other' ): |
| 93 | + $subaction = ''; break; |
| 94 | + default: |
| 95 | + $subaction = ''; |
| 96 | + } |
| 97 | + |
| 98 | + if ( $subaction === 'check' && $this->checkToken() && $wgRequest->wasPosted() ) { |
| 99 | + $this->showConfirmation(); |
| 100 | + } elseif ( $subaction === 'perform' && $this->checkToken() && $wgRequest->wasPosted() ) { |
| 101 | + $this->performAction(); |
| 102 | + } else { |
| 103 | + $this->showForm(); |
| 104 | + } |
| 105 | + |
| 106 | + } |
| 107 | + |
| 108 | + /** |
| 109 | + * Do the basic checks whether moving is possible and whether |
| 110 | + * the input looks anywhere near sane. |
| 111 | + */ |
| 112 | + protected function doBasicChecks() { |
| 113 | + global $wgOut; |
| 114 | + # Check for database lock |
| 115 | + if ( wfReadOnly() ) { |
| 116 | + $wgOut->readOnlyPage(); |
| 117 | + return; |
| 118 | + } |
| 119 | + |
| 120 | + if ( !$this->title->exists() ) { |
| 121 | + $wgOut->showErrorPage( 'nopagetitle', 'nopagetext' ); |
| 122 | + return; |
| 123 | + } |
| 124 | + |
| 125 | + # Check rights |
| 126 | + $permErrors = $this->title->getUserPermissionsErrors( 'delete', $this->user ); |
| 127 | + if ( !empty( $permErrors ) ) { |
| 128 | + $wgOut->showPermissionsErrorPage( $permErrors ); |
| 129 | + return; |
| 130 | + } |
| 131 | + |
| 132 | + // Let the caller know it's safe to continue |
| 133 | + return true; |
| 134 | + } |
| 135 | + |
| 136 | + /** |
| 137 | + * Checks token. Use before real actions happen. Have to use wpEditToken |
| 138 | + * for compatibility for SpecialMovepage.php. |
| 139 | + */ |
| 140 | + protected function checkToken() { |
| 141 | + global $wgRequest; |
| 142 | + return $this->user->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) ); |
| 143 | + } |
| 144 | + |
| 145 | + /** |
| 146 | + * The query form. |
| 147 | + */ |
| 148 | + protected function showForm() { |
| 149 | + global $wgOut; |
| 150 | + |
| 151 | + $wgOut->addWikiMsg( 'pt-deletepage-intro' ); |
| 152 | + |
| 153 | + $br = Html::element( 'br' ); |
| 154 | + $subaction = array( 'name' => 'subaction' ); |
| 155 | + $formParams = array( 'method' => 'post', 'action' => $this->getTitle( $this->text )->getLocalURL() ); |
| 156 | + |
| 157 | + $form = array(); |
| 158 | + $form[] = Xml::fieldset( wfMsg( 'pt-deletepage-any-legend' ) ); |
| 159 | + $form[] = Html::openElement( 'form', $formParams ); |
| 160 | + $form[] = Html::hidden( 'wpEditToken', $this->user->editToken() ); |
| 161 | + $this->addInputLabel( $form, wfMsg( 'pt-deletepage-current' ), 'wpTitle', 30, $this->text ); |
| 162 | + $this->addInputLabel( $form, wfMsg( 'pt-deletepage-reason' ), 'reason', 60, $this->reason ); |
| 163 | + $form[] = Xml::submitButton( wfMsg( 'pt-deletepage-action-check' ), $subaction ); |
| 164 | + $form[] = Xml::closeElement( 'form' ); |
| 165 | + $form[] = Xml::closeElement( 'fieldset' ); |
| 166 | + $wgOut->addHTML( implode( "\n", $form ) ); |
| 167 | + } |
| 168 | + |
| 169 | + /** |
| 170 | + * Shortcut for keeping the code at least a bit readable. Adds label and input into $form array. |
| 171 | + * @param $form \list{String} Array where input element and label is appended. |
| 172 | + * @param $label \string Label text. |
| 173 | + * @param $name \string Name attribute. |
| 174 | + * @param $size \int Size attribute of the input element. Default false. |
| 175 | + * @param $text \string Text of the value attribute. Default false. |
| 176 | + * @param $attribs \array Extra attributes. Default empty array. |
| 177 | + */ |
| 178 | + protected function addInputLabel( &$form, $label, $name, $size = false , $text = false, $attribs = array() ) { |
| 179 | + $br = Html::element( 'br' ); |
| 180 | + list( $label, $input ) = Xml::inputLabelSep( $label, $name, $name, $size, $text, $attribs ); |
| 181 | + $form[] = $label . $br; |
| 182 | + $form[] = $input . $br; |
| 183 | + } |
| 184 | + |
| 185 | + /** |
| 186 | + * The second form, which still allows changing some things. |
| 187 | + * Lists all the action which would take place. |
| 188 | + */ |
| 189 | + protected function showConfirmation() { |
| 190 | + global $wgOut, $wgLang; |
| 191 | + |
| 192 | + $wgOut->addWikiMsg( 'pt-deletepage-intro' ); |
| 193 | + |
| 194 | + $base = $this->title->getPrefixedText(); |
| 195 | + $target = $this->title; |
| 196 | + $count = 1; // Base page |
| 197 | + |
| 198 | + $wgOut->wrapWikiMsg( '== $1 ==', 'pt-deletepage-list-pages' ); |
| 199 | + if ( !$this->singleLanguage() ) { |
| 200 | + $this->printChangeLine( $this->title ); |
| 201 | + } |
| 202 | + |
| 203 | + $wgOut->wrapWikiMsg( '=== $1 ===', 'pt-deletepage-list-translation' ); |
| 204 | + $translationPages = $this->getTranslationPages(); |
| 205 | + foreach ( $translationPages as $old ) { |
| 206 | + $count++; |
| 207 | + $this->printChangeLine( $old ); |
| 208 | + } |
| 209 | + |
| 210 | + $wgOut->wrapWikiMsg( '=== $1 ===', 'pt-deletepage-list-section' ); |
| 211 | + $sectionPages = $this->getSectionPages( $target ); |
| 212 | + foreach ( $sectionPages as $old ) { |
| 213 | + $count++; |
| 214 | + $this->printChangeLine( $old ); |
| 215 | + } |
| 216 | + |
| 217 | + $wgOut->wrapWikiMsg( '=== $1 ===', 'pt-deletepage-list-other' ); |
| 218 | + $subpages = $this->getSubpages(); |
| 219 | + foreach ( $subpages as $old ) { |
| 220 | + if ( TranslatablePage::isTranslationPage( $old ) ) continue; |
| 221 | + if ( $this->doSubpages ) { $count++; } |
| 222 | + $this->printChangeLine( $old, $this->doSubpages ); |
| 223 | + } |
| 224 | + |
| 225 | + $wgOut->addWikiText( "----\n" ); |
| 226 | + $wgOut->addWikiMsg( 'pt-deletepage-list-count', $wgLang->formatNum( $count ) ); |
| 227 | + |
| 228 | + $br = Html::element( 'br' ); |
| 229 | + $readonly = array( 'readonly' => 'readonly' ); |
| 230 | + |
| 231 | + $subaction = array( 'name' => 'subaction' ); |
| 232 | + $formParams = array( 'method' => 'post', 'action' => $this->getTitle( $this->text )->getLocalURL() ); |
| 233 | + |
| 234 | + $form = array(); |
| 235 | + if ( $this->singleLanguage() ) { |
| 236 | + $form[] = Xml::fieldset( wfMsg( 'pt-deletepage-lang-legend' ) ); |
| 237 | + } else { |
| 238 | + $form[] = Xml::fieldset( wfMsg( 'pt-deletepage-full-legend' ) ); |
| 239 | + } |
| 240 | + $form[] = Html::openElement( 'form', $formParams ); |
| 241 | + $form[] = Html::hidden( 'wpEditToken', $this->user->editToken() ); |
| 242 | + $this->addInputLabel( $form, wfMsg( 'pt-deletepage-current' ), 'wpTitle', 30, $this->text, $readonly ); |
| 243 | + $this->addInputLabel( $form, wfMsg( 'pt-deletepage-reason' ), 'reason', 60, $this->reason ); |
| 244 | + $form[] = Xml::checkLabel( wfMsg( 'pt-deletepage-subpages' ), 'subpages', 'mw-subpages', $this->doSubpages, $readonly ) . $br; |
| 245 | + $form[] = Xml::submitButton( wfMsg( 'pt-deletepage-action-perform' ), $subaction ); |
| 246 | + $form[] = Xml::submitButton( wfMsg( 'pt-deletepage-action-other' ), $subaction ); |
| 247 | + $form[] = Xml::closeElement( 'form' ); |
| 248 | + $form[] = Xml::closeElement( 'fieldset' ); |
| 249 | + $wgOut->addHTML( implode( "\n", $form ) ); |
| 250 | + } |
| 251 | + |
| 252 | + protected function printChangeLine( $title, $enabled = true ) { |
| 253 | + global $wgOut; |
| 254 | + if ( $enabled ) { |
| 255 | + $wgOut->addWikiText( '* ' . $title->getPrefixedText() ); |
| 256 | + } else { |
| 257 | + $wgOut->addWikiText( '* <s>' . $title->getPrefixedText() . '</s>' ); |
| 258 | + } |
| 259 | + } |
| 260 | + |
| 261 | + protected function performAction() { |
| 262 | + $jobs = array(); |
| 263 | + $target = $this->title; |
| 264 | + |
| 265 | + $translationPages = $this->getTranslationPages(); |
| 266 | + foreach ( $translationPages as $old ) { |
| 267 | + $jobs[$old->getPrefixedText()] = DeleteJob::newJob( $old, !$this->singleLanguage(), $this->user ); |
| 268 | + } |
| 269 | + |
| 270 | + $sectionPages = $this->getSectionPages(); |
| 271 | + foreach ( $sectionPages as $old ) { |
| 272 | + $to = $this->newPageTitle( $base, $old, $target ); |
| 273 | + $jobs[$old->getPrefixedText()] = DeleteJob::newJob( $old, !$this->singleLanguage(), $this->user ); |
| 274 | + } |
| 275 | + |
| 276 | + if ( !$this->doSubpages ) { |
| 277 | + $subpages = $this->getSubpages(); |
| 278 | + foreach ( $subpages as $old ) { |
| 279 | + if ( TranslatablePage::isTranslationPage( $old ) ) { |
| 280 | + continue; |
| 281 | + } |
| 282 | + |
| 283 | + $to = $this->newPageTitle( $base, $old, $target ); |
| 284 | + $jobs[$old->getPrefixedText()] = DeleteJob::newJob( $old, !$this->singleLanguage(), $this->user ); |
| 285 | + } |
| 286 | + } |
| 287 | + |
| 288 | + Job::batchInsert( $jobs ); |
| 289 | + |
| 290 | + global $wgMemc; |
| 291 | + $wgMemc->set( wfMemcKey( 'pt-base', $base ), array_keys( $jobs ), 60 * 60 * 6 ); |
| 292 | + |
| 293 | + |
| 294 | + if ( !$this->singleLanguage() ) { |
| 295 | + $this->page->removeTags(); |
| 296 | + } |
| 297 | + |
| 298 | + MessageGroups::clearCache(); |
| 299 | + // TODO: defer or make faster |
| 300 | + MessageIndexRebuilder::execute(); |
| 301 | + |
| 302 | + global $wgOut; |
| 303 | + $wgOut->addWikiMsg( 'pt-deletepage-started' ); |
| 304 | + } |
| 305 | + |
| 306 | + /** |
| 307 | + * Returns all section pages, including those which are currently not active. |
| 308 | + * @return TitleArray. |
| 309 | + */ |
| 310 | + protected function getSectionPages() { |
| 311 | + if ( !isset( $this->sectionPages ) ) { |
| 312 | + $base = $this->page->getTitle()->getPrefixedDBKey(); |
| 313 | + |
| 314 | + $dbw = wfGetDB( DB_MASTER ); |
| 315 | + if ( $this->singleLanguage() ) { |
| 316 | + $like = $dbw->buildLike( "$base/", $dbw->anyString(), "/{$this->code}" ); |
| 317 | + } else { |
| 318 | + $like = $dbw->buildLike( "$base/", $dbw->anyString() ); |
| 319 | + } |
| 320 | + |
| 321 | + $fields = array( 'page_namespace', 'page_title' ); |
| 322 | + $titleCond = 'page_title ' . $like; |
| 323 | + $conds = array( 'page_namespace' => NS_TRANSLATIONS, $titleCond ); |
| 324 | + $result = $dbw->select( 'page', $fields, $conds, __METHOD__ ); |
| 325 | + $this->sectionPages = TitleArray::newFromResult( $result ); |
| 326 | + } |
| 327 | + return $this->sectionPages; |
| 328 | + } |
| 329 | + |
| 330 | + /** |
| 331 | + * Returns only translation subpages. |
| 332 | + * @return Array of titles. |
| 333 | + */ |
| 334 | + protected function getTranslationPages() { |
| 335 | + if ( $this->singleLanguage() ) { |
| 336 | + return array( $this->title ); |
| 337 | + } |
| 338 | + |
| 339 | + if ( !isset( $this->translationPages ) ) { |
| 340 | + $this->translationPages = $this->page->getTranslationPages(); |
| 341 | + } |
| 342 | + return $this->translationPages; |
| 343 | + } |
| 344 | + |
| 345 | + /** |
| 346 | + * Returns all subpages, if the namespace has them enabled. |
| 347 | + * @return Empty array or TitleArray |
| 348 | + */ |
| 349 | + protected function getSubpages() { |
| 350 | + return $this->title->getSubpages(); |
| 351 | + } |
| 352 | + |
| 353 | + protected function singleLanguage() { |
| 354 | + return $this->code !== ''; |
| 355 | + } |
| 356 | +} |
Property changes on: trunk/extensions/Translate/tag/SpecialPageTranslationDeletePage.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 357 | + native |
Index: trunk/extensions/Translate/tag/DeleteJob.php |
— | — | @@ -0,0 +1,163 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Contains class with job for deleting translatable and translation pages. |
| 5 | + * |
| 6 | + * @file |
| 7 | + * @author Niklas Laxström |
| 8 | + * @copyright Copyright © 2008-2011, Niklas Laxström |
| 9 | + * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later |
| 10 | + */ |
| 11 | + |
| 12 | +/** |
| 13 | + * Contains class with job for deleting translatable and translation pages. |
| 14 | + * |
| 15 | + * @ingroup PageTranslation JobQueue |
| 16 | + * @todo Get rid of direct reference to $wgMemc. |
| 17 | + */ |
| 18 | +class DeleteJob extends Job { |
| 19 | + public static function newJob( Title $target, $full, /*User*/ $performer ) { |
| 20 | + global $wgTranslateFuzzyBotName; |
| 21 | + |
| 22 | + $job = new self( $target ); |
| 23 | + $job->setUser( $wgTranslateFuzzyBotName ); |
| 24 | + $job->setFull( $full ); |
| 25 | + $msg = $this->getFull() ? 'pt-deletepage-full-logreason' : 'pt-deletepage-lang-logreason'; |
| 26 | + $job->setSummary( wfMsgForContent( 'pt-deletepage-logreason', $target->getPrefixedText() ) ); |
| 27 | + $job->setPerformer( $performer ); |
| 28 | + $job->lock(); |
| 29 | + return $job; |
| 30 | + } |
| 31 | + |
| 32 | + function __construct( $title, $params = array(), $id = 0 ) { |
| 33 | + parent::__construct( __CLASS__, $title, $params, $id ); |
| 34 | + } |
| 35 | + |
| 36 | + function run() { |
| 37 | + global $wgUser; |
| 38 | + |
| 39 | + // Initialization |
| 40 | + $title = $this->title; |
| 41 | + // Other stuff |
| 42 | + $user = $this->getUser(); |
| 43 | + $summary = $this->getSummary(); |
| 44 | + $target = $this->getTarget(); |
| 45 | + |
| 46 | + PageTranslationHooks::$allowTargetEdit = true; |
| 47 | + $oldUser = $wgUser; |
| 48 | + $wgUser = $user; |
| 49 | + |
| 50 | + $error = ''; |
| 51 | + $ok = new Article( $title, 0 )->doDeleteArticle( $summary, false, 0, true, $error ); |
| 52 | + if ( !$ok ) { |
| 53 | + $logger = new LogPage( 'pagetranslation' ); |
| 54 | + $params = array( |
| 55 | + 'user' => $this->getPerformer(), |
| 56 | + 'target' => $target->getPrefixedText(), |
| 57 | + 'error' => base64_encode( serialize( $ok ) ), // This is getting ridiculous |
| 58 | + ); |
| 59 | + $doer = User::newFromName( $this->getPerformer() ); |
| 60 | + $msg = $this->getFull() ? 'deletefnok' : 'deletelnok'; |
| 61 | + $logger->addEntry( $msg, $title, null, array( serialize( $params ) ), $doer ); |
| 62 | + } |
| 63 | + |
| 64 | + PageTranslationHooks::$allowTargetEdit = false; |
| 65 | + |
| 66 | + global $wgMemc; |
| 67 | + $pages = (array) $wgMemc->get( wfMemcKey( 'pt-base', $title->getPrefixedText() ) ); |
| 68 | + $last = true; |
| 69 | + |
| 70 | + foreach ( $pages as $page ) { |
| 71 | + if ( $wgMemc->get( wfMemcKey( 'pt-lock', $page ) ) === true ) { |
| 72 | + $last = false; |
| 73 | + break; |
| 74 | + } |
| 75 | + } |
| 76 | + |
| 77 | + if ( $last ) { |
| 78 | + $wgMemc->delete( wfMemcKey( 'pt-base', $title->getPrefixedText() ) ); |
| 79 | + $logger = new LogPage( 'pagetranslation' ); |
| 80 | + $params = array( 'user' => $this->getPerformer() ); |
| 81 | + $doer = User::newFromName( $this->getPerformer() ); |
| 82 | + $msg = $this->getFull() ? 'deletefok' : 'deletelok'; |
| 83 | + $logger->addEntry( $msg, $title, null, array( serialize( $params ) ), $doer ); |
| 84 | + } |
| 85 | + |
| 86 | + $wgUser = $oldUser; |
| 87 | + |
| 88 | + return true; |
| 89 | + } |
| 90 | + |
| 91 | + public function setSummary( $summary ) { |
| 92 | + $this->params['summary'] = $summary; |
| 93 | + } |
| 94 | + |
| 95 | + public function getSummary() { |
| 96 | + return $this->params['summary']; |
| 97 | + } |
| 98 | + |
| 99 | + public function setFull( $full ) { |
| 100 | + $this->params['full'] = $full; |
| 101 | + } |
| 102 | + |
| 103 | + public function getFull() { |
| 104 | + return $this->params['full']; |
| 105 | + } |
| 106 | + |
| 107 | + public function setPerformer( $performer ) { |
| 108 | + if ( is_object( $performer ) ) { |
| 109 | + $this->params['performer'] = $performer->getName(); |
| 110 | + } else { |
| 111 | + $this->params['performer'] = $performer; |
| 112 | + } |
| 113 | + } |
| 114 | + |
| 115 | + public function getPerformer() { |
| 116 | + return $this->params['performer']; |
| 117 | + } |
| 118 | + |
| 119 | + public function setUser( $user ) { |
| 120 | + if ( is_object( $user ) ) { |
| 121 | + $this->params['user'] = $user->getName(); |
| 122 | + } else { |
| 123 | + $this->params['user'] = $user; |
| 124 | + } |
| 125 | + } |
| 126 | + |
| 127 | + /** |
| 128 | + * Get a user object for doing edits. |
| 129 | + */ |
| 130 | + public function getUser() { |
| 131 | + return User::newFromName( $this->params['user'], false ); |
| 132 | + } |
| 133 | + |
| 134 | + /** |
| 135 | + * Adapted from wfSuppressWarnings to allow not leaving redirects. |
| 136 | + */ |
| 137 | + public static function forceRedirects( $end = false ) { |
| 138 | + static $suppressCount = 0; |
| 139 | + static $originalLevel = null; |
| 140 | + |
| 141 | + global $wgGroupPermissions; |
| 142 | + global $wgUser; |
| 143 | + |
| 144 | + if ( $end ) { |
| 145 | + if ( $suppressCount ) { |
| 146 | + --$suppressCount; |
| 147 | + if ( !$suppressCount ) { |
| 148 | + if ( $originalLevel === null ) { |
| 149 | + unset( $wgGroupPermissions['*']['suppressredirect'] ); |
| 150 | + } else { |
| 151 | + $wgGroupPermissions['*']['suppressredirect'] = $originalLevel; |
| 152 | + } |
| 153 | + } |
| 154 | + } |
| 155 | + } else { |
| 156 | + if ( !$suppressCount ) { |
| 157 | + $originalLevel = isset( $wgGroupPermissions['*']['suppressredirect'] ) ? $wgGroupPermissions['*']['suppressredirect'] : null; |
| 158 | + $wgGroupPermissions['*']['suppressredirect'] = true; |
| 159 | + } |
| 160 | + ++$suppressCount; |
| 161 | + } |
| 162 | + $wgUser->clearInstanceCache(); |
| 163 | + } |
| 164 | +} |
Property changes on: trunk/extensions/Translate/tag/DeleteJob.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 165 | + native |
Index: trunk/extensions/Translate/tag/PageTranslationHooks.php |
— | — | @@ -357,7 +357,7 @@ |
358 | 358 | /// Prevent editing of translation pages directly |
359 | 359 | public static function preventDirectEditing( $title, $user, $action, &$result ) { |
360 | 360 | $page = TranslatablePage::isTranslationPage( $title ); |
361 | | - if ( $page !== false ) { |
| 361 | + if ( $page !== false && $action !== 'delete' ) { |
362 | 362 | if ( self::$allowTargetEdit ) { |
363 | 363 | return true; |
364 | 364 | } |
— | — | @@ -372,17 +372,19 @@ |
373 | 373 | |
374 | 374 | return false; |
375 | 375 | } |
376 | | - } elseif ( $action === 'delete' ) { |
377 | | - $page = TranslatablePage::newFromTitle( $title ); |
378 | | - if ( $page->getMarkedTag() ) { |
379 | | - $result = array( 'tpt-delete-impossible' ); |
380 | | - return false; |
381 | | - } |
382 | 376 | } |
383 | 377 | |
384 | 378 | return true; |
385 | 379 | } |
386 | 380 | |
| 381 | + public static function disableDelete( $article, $wgOut, &$reason ) { |
| 382 | + if ( TranslatablePage::isSourcePage( $article->mTitle ) || TranslatablePage::isTranslationPage( $article->mTitle ) ) { |
| 383 | + $new = SpecialPage::getTitleFor( 'PageTranslationDeletePage', $article->mTitle->getPrefixedText() ); |
| 384 | + $wgOut->redirect( $new->getFullUrl() ); |
| 385 | + } |
| 386 | + return true; |
| 387 | + } |
| 388 | + |
387 | 389 | public static function schemaUpdates( $updater = null ) { |
388 | 390 | $dir = dirname( __FILE__ ) . '/..'; |
389 | 391 | |
— | — | @@ -550,6 +552,14 @@ |
551 | 553 | return wfMsgExt( 'pt-log-moveok', $opts, $title->getPrefixedText(), $user ); |
552 | 554 | } elseif ( $action === 'movenok' ) { |
553 | 555 | return wfMsgExt( 'pt-log-movenok', $opts, $title->getPrefixedText(), $user, $_['target'] ); |
| 556 | + } elseif ( $action === 'deletefnok' ) { |
| 557 | + return wfMsgExt( 'pt-log-delete-full-nok', $opts, $title->getPrefixedText(), $user, $_['target'] ); |
| 558 | + } elseif ( $action === 'deletelnok' ) { |
| 559 | + return wfMsgExt( 'pt-log-delete-lang-nok', $opts, $title->getPrefixedText(), $user, $_['target'] ); |
| 560 | + } elseif ( $action === 'deletelok' ) { |
| 561 | + return wfMsgExt( 'pt-log-delete-full-ok', $opts, $title->getPrefixedText(), $user ); |
| 562 | + } elseif ( $action === 'deletefok' ) { |
| 563 | + return wfMsgExt( 'pt-log-delete-lang-ok', $opts, $title->getPrefixedText(), $user ); |
554 | 564 | } |
555 | 565 | } |
556 | 566 | |
Index: trunk/extensions/Translate/Translate.php |
— | — | @@ -8,7 +8,7 @@ |
9 | 9 | * |
10 | 10 | * @author Niklas Laxström |
11 | 11 | * @author Siebrand Mazeland |
12 | | - * @copyright Copyright © 2006-2010, Niklas Laxström, Siebrand Mazeland |
| 12 | + * @copyright Copyright © 2006-2011, Niklas Laxström, Siebrand Mazeland |
13 | 13 | * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later |
14 | 14 | */ |
15 | 15 | |
— | — | @@ -541,6 +541,8 @@ |
542 | 542 | global $wgSpecialPages, $wgAvailableRights, $wgSpecialPageGroups; |
543 | 543 | $wgSpecialPages['PageTranslation'] = 'SpecialPageTranslation'; |
544 | 544 | $wgSpecialPageGroups['PageTranslation'] = 'pagetools'; |
| 545 | + $wgSpecialPages['PageTranslationDeletePage'] = 'SpecialPageTranslationDeletePage'; |
| 546 | + $wgSpecialPageGroups['PageTranslationDeletePage'] = 'pagetools'; |
545 | 547 | $wgAvailableRights[] = 'pagetranslation'; |
546 | 548 | |
547 | 549 | global $wgLogNames, $wgLogActionsHandlers, $wgLogTypes, $wgLogHeaders; |
— | — | @@ -621,6 +623,9 @@ |
622 | 624 | |
623 | 625 | // Replace subpage logic behaviour |
624 | 626 | $wgHooks['SkinSubPageSubtitle'][] = 'PageTranslationHooks::replaceSubtitle'; |
| 627 | + |
| 628 | + // Disable action=delete |
| 629 | + $wgHooks['ArticleConfirmDelete'][] = 'PageTranslationHooks::disableDelete'; |
625 | 630 | } |
626 | 631 | } |
627 | 632 | |
Index: trunk/extensions/Translate/_autoload.php |
— | — | @@ -4,7 +4,7 @@ |
5 | 5 | * |
6 | 6 | * @file |
7 | 7 | * @author Niklas Laxström |
8 | | - * @copyright Copyright © 2008-2010, Niklas Laxström |
| 8 | + * @copyright Copyright © 2008-2011, Niklas Laxström |
9 | 9 | * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later |
10 | 10 | */ |
11 | 11 | |
— | — | @@ -115,7 +115,6 @@ |
116 | 116 | |
117 | 117 | $wgAutoloadClasses['MessageHandle'] = $dir . 'utils/MessageHandle.php'; |
118 | 118 | |
119 | | - |
120 | 119 | /**@}*/ |
121 | 120 | |
122 | 121 | /** |
— | — | @@ -150,8 +149,10 @@ |
151 | 150 | $wgAutoloadClasses['TPSection'] = $dir . 'tag/TPSection.php'; |
152 | 151 | $wgAutoloadClasses['SpecialPageTranslation'] = $dir . 'tag/SpecialPageTranslation.php'; |
153 | 152 | $wgAutoloadClasses['SpecialPageTranslationMovePage'] = $dir . 'tag/SpecialPageTranslationMovePage.php'; |
| 153 | +$wgAutoloadClasses['SpecialPageTranslationDeletePage'] = $dir . 'tag/SpecialPageTranslationDeletePage.php'; |
154 | 154 | $wgAutoloadClasses['RenderJob'] = $dir . 'tag/RenderJob.php'; |
155 | 155 | $wgAutoloadClasses['MoveJob'] = $dir . 'tag/MoveJob.php'; |
| 156 | +$wgAutoloadClasses['DeleteJob'] = $dir . 'tag/MoveJob.php'; |
156 | 157 | /**@}*/ |
157 | 158 | |
158 | 159 | /** |
Index: trunk/extensions/Translate/PageTranslation.i18n.php |
— | — | @@ -77,7 +77,6 @@ |
78 | 78 | This page is a translation of page [[$1]] and the translation can be updated using [$2 the translation tool].', |
79 | 79 | 'tpt-unknown-page' => 'This namespace is reserved for content page translations. |
80 | 80 | The page you are trying to edit does not seem to correspond any page marked for translation.', |
81 | | - 'tpt-delete-impossible' => 'Deleting pages marked for translation is not yet possible.', |
82 | 81 | |
83 | 82 | 'tpt-install' => 'Run php maintenance/update.php or web install to enable page translation feature.', |
84 | 83 | |
— | — | @@ -104,6 +103,10 @@ |
105 | 104 | 'pt-log-unmark' => '{{GENDER:$2|removed}} page "[[:$1]]" from translation', |
106 | 105 | 'pt-log-moveok' => '{{GENDER:$2|completed}} renaming of translatable page $1 to a new name', |
107 | 106 | 'pt-log-movenok' => '{{GENDER:$2|encountered}} a problem while moving [[:$1]] to [[:$3]]', |
| 107 | + 'pt-log-delete-full-ok' => '{{GENDER:$2|completed}} deletion of translatable page $1', |
| 108 | + 'pt-log-delete-full-nok' => '{{GENDER:$2|encountered}} a problem while deleting translatable page [[:$1]]', |
| 109 | + 'pt-log-delete-lang-ok' => '{{GENDER:$2|completed}} deletion of translation page $e', |
| 110 | + 'pt-log-delete-lang-nok' => '{{GENDER:$2|encountered}} a problem while deleting translation page [[:$1]]', |
108 | 111 | |
109 | 112 | |
110 | 113 | # move page replacement |
— | — | @@ -144,6 +147,39 @@ |
145 | 148 | Please check the [[Special:Log/pagetranslation|page translation log]] for errors and completion message.', |
146 | 149 | |
147 | 150 | 'pt-locked-page' => 'This page is locked because the translatable page is currently being moved.', |
| 151 | + |
| 152 | + |
| 153 | + 'pt-deletepage-lang-title' => 'Deleting translation page $1.', |
| 154 | + 'pt-deletepage-full-title' => 'Deleting translatable page $1.', |
| 155 | + |
| 156 | + 'pt-deletepage-invalid-title' => 'The specified page is not valid.', |
| 157 | + 'pt-deletepage-invalid-text' => 'The specified page is not a translatable page nor translation of it.', |
| 158 | + |
| 159 | + 'pt-deletepage-action-check' => 'List pages to be deleted', |
| 160 | + 'pt-deletepage-action-perform' => 'Do the deletion', |
| 161 | + 'pt-deletepage-action-other' => 'Change target', |
| 162 | + |
| 163 | + 'pt-deletepage-lang-legend' => 'Delete translation page', |
| 164 | + 'pt-deletepage-full-legend' => 'Delete translatable page', |
| 165 | + 'pt-deletepage-any-legend' => 'Delete translatable page or translation of translatable page', |
| 166 | + 'pt-deletepage-current' => 'Page name:', |
| 167 | + 'pt-deletepage-reason' => 'Reason:', |
| 168 | + 'pt-deletepage-subpages' => 'Delete all subpages', |
| 169 | + |
| 170 | + 'pt-deletepage-list-pages' => 'List of pages to delete', |
| 171 | + 'pt-deletepage-list-translation' => 'Translation pages', |
| 172 | + 'pt-deletepage-list-section' => 'Section pages', |
| 173 | + 'pt-deletepage-list-other' => 'Other subpages', |
| 174 | + 'pt-deletepage-list-count' => 'In total $1 {{PLURAL:$1|page|pages}} to delete.', |
| 175 | + |
| 176 | + 'pt-deletepage-full-logreason' => 'Part of translatable page $1.', |
| 177 | + 'pt-deletepage-lang-logreason' => 'Part of translation page $1.', |
| 178 | + 'pt-deletepage-started' => 'Please check the [[Special:Log/pagetranslation|page translation log]] for errors and completion message.', |
| 179 | + |
| 180 | + 'pt-deletepage-intro' => 'This special page allows you delete whole translatable pages or translations into one language. |
| 181 | +The delete action will not be instant, because many pages will need to be deleted. |
| 182 | +Failures will be logged in the [[Special:Log/pagetranslation|page translation log]] and they need to be repaired by hand.', |
| 183 | + |
148 | 184 | ); |
149 | 185 | |
150 | 186 | /** Message documentation (Message documentation) |
Index: trunk/extensions/Translate/Translate.alias.php |
— | — | @@ -22,6 +22,7 @@ |
23 | 23 | 'FirstSteps' => array( 'FirstSteps' ), |
24 | 24 | 'SupportedLanguages' => array( 'SupportedLanguages' ), |
25 | 25 | 'MyLanguage' => array( 'MyLanguage' ), |
| 26 | + 'PageTranslationDeletePage' => array( 'PageTranslationDeletePage' ), |
26 | 27 | ); |
27 | 28 | |
28 | 29 | /** Afrikaans (Afrikaans) */ |