Extension:DeletePagePermanently
|
Release status: beta |
|||
|---|---|---|---|
| Implementation | User interface | ||
| Description | Delete a page permanently from the database | ||
| Author(s) | Wolfgang Stöttinger, Ludovic MOUTON (LeLorrainTalk) | ||
| Last Version | 2.1.3 (MW1.16.x 2.1.3) | ||
| MediaWiki | 1.13+, 1.16.x | ||
| License | GPL | ||
| Download | This page | ||
|
|||
|
|||
|
|||
|
check usage (experimental) |
|||
This extension can delete pages in every namespace configured (also images) without leaving any trace in the database. This extension will automatically delete talk pages and subpages, if any.
I improved the original Version of Ludovic MOUTON. The original Version can be found at Extension:DeletePagePermanently/1.0
The extension DeletePagePermanently adds a new tab that allows you to delete a page permanently from the database. Although version 2.0 is safer than version 1.0 it can still harm your wiki, especially when used wrong. I advise you to test the extension carefully and backup your database as the extension is still in beta status.
Since version 2.1 it is possible to use the function from other PHP files.
Contents |
[edit] Installation
The extension was designed for MediaWiki 1.13 but it should be compatible with later version as long as the database layout is the same as MediaWiki 1.13.0 for the tables.
As the Table structure of MediaWiki 1.14 is similar to 1.13 it also works here, I tested and did not figure out any problems.
[edit] Download
Please cut and paste the code found below and place it in $IP/extensions/DeletePagePermanently/DeletePagePermanently.php and $IP/extensions/DeletePagePermanently/DeletePagePermanently.i18n.php. Note: $IP stands for the root directory of your MediaWiki installation, the same directory that holds LocalSettings.php.
[edit] Install
To install this extension, add the following to LocalSettings.php:
require_once("$IP/extensions/DeletePagePermanently/DeletePagePermanently.php");
[edit] Configuration
[edit] User rights
The extension introduces a new user rights deleteperm. You can configure the rights in LocalSettings.php:
Defaults from DeletePagePermanently.php:
$wgGroupPermissions['*'] ['deleteperm'] = false; $wgGroupPermissions['user'] ['deleteperm'] = false; $wgGroupPermissions['bureaucrat']['deleteperm'] = false; $wgGroupPermissions['sysop'] ['deleteperm'] = true;
[edit] Namespaces
Since version 2.0 is the possibility to configure the namespaces in which pages can be deleted. To configure this, add some lines to your LocalSettings.php:
$wgDeletePagePermanentlyNamespaces = array( NS_MAIN => true, NS_IMAGE => true, NS_CATEGORY => true, NS_TEMPLATE => true, NS_TALK => true, );
Built-in namespaces are described on meta-wiki.
[edit] Code
[edit] DeletePagePermanently.php
<?php /** * DeletePagePermanently.php * based on Version 1.0 BETA from Ludovic MOUTON (2008) * Wolfgang Stöttinger 2008 * v. 2.1.3 BETA * GPL * * BE CAREFUL WHEN USING THIS EXTENSION. ONCE A PAGE IS DELETED, IT CAN NOT BE RESTORED ANY MORE. * Changed in Version 2.1.3: * - Delete automatically the talk page * - Delete subpages and associeted talk pages (for the moment, not recursively) * Changed in Version 2.1.2: * - Update category count * Changed in Version 2.1.1: * - Title is removed from cache. * Changed in Version 2.1.0: * - deletePage() can now be used from outside in PHP. * * Features of Version 2.0: * - defined $wgDeletePagePermanentlyNamespaces as an array of namespaces in which pages can be deleted. * $wgDeletePagePermanentlyNamespaces = array ( * NS_MAIN => true, * NS_IMAGE => true, * NS_CATEGORY => true, * NS_TEMPLATE => true, * NS_TALK => true, * ); * * - The tab "Delete permanently" is only shown on pages that can be deleted. * - An aditional page to approve the deletion * - Also log entries are deleted. * - Also redirects, external links, language links, searchindex entries, page_restrictions, pagelinks, categorylinks, templatelinks, archive entries and image links are deleted. * - The watchlist entries are also removed. * - If the page is an image page, all versions of the image are deleted from the database, the archive and the filesystem. (Thumbnlais won't be removed) */ if ( !defined( 'MEDIAWIKI' ) ) { exit( 1 ) ; } $wgExtensionCredits['other'][] = array( 'name' => 'DeletePagePermanently', 'version' => '2.1', 'author' => 'Ludovic MOUTON, Wolfgang STÖTTINGER', 'description' => 'Adds a new delete tab to each page. Pages are deleted permanently from the database.', 'url' => 'http://www.mediawiki.org/wiki/Extension:DeletePagePermanently', ); # Default settings $wgGroupPermissions['*'] ['deleteperm'] = false; $wgGroupPermissions['user'] ['deleteperm'] = false; $wgGroupPermissions['bureaucrat']['deleteperm'] = false; $wgGroupPermissions['sysop'] ['deleteperm'] = true; $wgExtensionMessagesFiles['DeletePagePermanently'] = dirname( __FILE__ ) . '/DeletePagePermanently.i18n.php'; $wgExtensionFunctions[] = 'wfDeletePagePermanently'; function wfDeletePagePermanently() { new DeletePagePermanently(); return true; } class DeletePagePermanently { function DeletePagePermanently() { global $wgHooks, $wgMessageCache, $wgUser; wfLoadExtensionMessages( 'DeletePagePermanently' ); $wgMessageCache->addMessage( 'delete_permanently', wfMsg('tab_label')); $wgHooks['SkinTemplateContentActions'][] = array(&$this, 'AddContentHook'); $wgHooks['UnknownAction'][] = array(&$this, 'AddActionHook'); } function AddContentHook( &$content_actions ) { global $wgRequest, $wgRequest, $wgTitle, $wgUser, $wgDeletePagePermanentlyNamespaces; if(!$wgUser->isAllowed( 'deleteperm' ) ) return false; $action = $wgRequest->getText( 'action' ); #Special pages can not be deleted (special pages have no article id anyway). if ( $wgTitle->getArticleID() != 0 && $wgDeletePagePermanentlyNamespaces[$wgTitle->getNamespace()] == true && $wgTitle->getNamespace() != NS_SPECIAL ) { wfLoadExtensionMessages( 'DeletePagePermanently' ); $content_actions['ask_delete_permanently'] = array( 'class' => $action == 'ask_delete_permanently' ? 'selected' : false, 'text' => wfMsg( 'delete_permanently' ), 'href' => $wgTitle->getLocalUrl( 'action=ask_delete_permanently' ) ); } return true; } function AddActionHook( $action, $wgArticle ) { global $wgOut, $wgUser, $wgDeletePagePermanentlyNamespaces; wfLoadExtensionMessages( 'DeletePagePermanently' ); if(!$wgUser->isAllowed( 'deleteperm' )) { $wgOut->permissionRequired('deleteperm'); return false; } # Print a form to approve deletion if ($action == 'ask_delete_permanently' ) { $action = $wgArticle->getTitle()->escapeLocalUrl( 'action=delete_permanently' ); $wgOut->addHTML("<form id='ask_delete_permanently' method='post' action=\"$action\"> <table> <tr> <td>" . wfMsg('ask_deletion') . "</td> </tr> <tr> <td><input type='submit' name='submit' value=\"" . wfMsg('yes') . "\" /></td> </tr> </table></form>"); return false; } # Perform actual deletion elseif ($action == 'delete_permanently' ) { $ns = $wgArticle->mTitle->getNamespace(); $t = $wgArticle->mTitle->getDBkey(); $id = $wgArticle->mTitle->getArticleID(); if ( $t == '' || $id == 0 || $wgDeletePagePermanentlyNamespaces[$ns] != true || $ns == NS_SPECIAL) { $wgOut->addHTML(wfMsgHtml('del_impossible')); return false; } #delete the page and the talk page too $this->deletePermanently($wgArticle->mTitle); $this->deletePermanentlyTalkPage($wgArticle->mTitle); # delete subpages and associeted talk pages if($wgArticle->mTitle->hasSubpages()) { $subPagesList = $wgArticle->mTitle->getSubpages(); if($subPagesList != array()) { foreach( $subPagesList as $subpage ) { $this->deletePermanently($subpage); $this->deletePermanentlyTalkPage($subpage); } } } $wgOut->addHTML(wfMsgHtml('del_done')); return false; } //$wgOut->addHTML(wfMsgHtml('del_not_done')); return true; } function deletePermanently($title){ global $wgOut; $ns = $title->getNamespace(); $t = $title->getDBkey(); $id = $title->getArticleID(); $cats = $title->getParentCategories(); $dbw = wfGetDB( DB_MASTER ); $dbw->begin(); #### ## First delete entries, which are in direct relation with the page: #### # delete redirect... $dbw->delete( 'redirect', array( 'rd_from' => $id ), __METHOD__); # delete external link... $dbw->delete( 'externallinks', array( 'el_from' => $id ), __METHOD__); # delete language link... $dbw->delete( 'langlinks', array( 'll_from' => $id ), __METHOD__); # delete search index... $dbw->delete( 'searchindex', array( 'si_page' => $id ), __METHOD__); # Delete restrictions for the page $dbw->delete( 'page_restrictions', array ( 'pr_page' => $id ), __METHOD__ ); # Delete page Links $dbw->delete( 'pagelinks', array ( 'pl_from' => $id ), __METHOD__ ); # delete category links $dbw->delete( 'categorylinks', array( 'cl_from' => $id ), __METHOD__); # delete template links $dbw->delete( 'templatelinks', array( 'tl_from' => $id ), __METHOD__); # read text entries for all revisions and delete them. $res = $dbw->select ('revision', 'rev_text_id', "rev_page=$id"); while( $row = $dbw->fetchObject($res) ) { $value = $row->rev_text_id; $dbw->delete('text', array('old_id'=>$value), __METHOD__); } # In the table 'revision' : Delete all the revision of the page where 'rev_page' = $id $dbw->delete('revision', array('rev_page'=>$id), __METHOD__); # delete image links $dbw->delete( 'imagelinks', array( 'il_from' => $id ), __METHOD__); #### ## then delete entries which are not in direct relation with the page: #### # Clean up recentchanges entries... $dbw->delete( 'recentchanges', array( 'rc_namespace' => $ns, 'rc_title' => $t ), __METHOD__ ); # read text entries for all archived pages and delete them. $res = $dbw->select ('archive', 'ar_text_id', array( 'ar_namespace' => $ns, 'ar_title' => $t )); while( $row = $dbw->fetchObject($res) ) { $value = $row->ar_text_id; $dbw->delete('text', array('old_id'=>$value), __METHOD__); } # Clean archive entries... $dbw->delete( 'archive', array( 'ar_namespace' => $ns, 'ar_title' => $t ), __METHOD__ ); # Clean up log entries... $dbw->delete( 'logging', array( 'log_namespace' => $ns, 'log_title' => $t ), __METHOD__ ); # Clean up watchlist... $dbw->delete( 'watchlist', array( 'wl_namespace' => $ns, 'wl_title' => $t ), __METHOD__ ); # In the table 'page' : Delete the page entry $dbw->delete( 'page', array( 'page_id' => $id ), __METHOD__); #### ## If the article belongs to a category, update category counts #### if(!empty($cats)) { foreach($cats as $parentcat => $currentarticle) { $catname = split(':', $parentcat, 2); $cat = Category::newFromName($catname[1]); $cat->refreshCounts(); } } #### ## If an image is beeing deleted, some extra work needs to be done #### if ($ns == NS_IMAGE) { $file = wfFindFile($t); if ($file) { # Get all filenames of old versions: $fields = OldLocalFile::selectFields(); $res = $dbw->select ('oldimage', $fields, array( 'oi_name' => $t )); while( $row = $dbw->fetchObject($res) ) { $oldLocalFile = OldLocalFile::newFromRow($row, $file->repo); $path = $oldLocalFile->getArchivePath().'/'.$oldLocalFile->getArchiveName(); try { # Using the FileStore to delete the file $transaction = FileStore::deleteFile( $path ); $transaction->commit(); } catch (Exception $e) { $wgOut->addHTML($e->getMessage()); } } $path = $file->getPath(); try { # Using the FileStore to delete the file itself $transaction = FileStore::deleteFile( $path ); $transaction->commit(); } catch (Exception $e) { $wgOut->addHTML($e->getMessage()); } } # clean the filearchive for the given filename: $fa_archive_name = array(); $res = $dbw->select ('filearchive', 'fa_storage_key', array( 'fa_name' => $t )); while( $row = $dbw->fetchObject($res) ) { $key = $row->fa_storage_key; # Using the FileStore to delete the file $store = FileStore::get( 'deleted' ); $transaction = $store->delete($key); $transaction->commit(); } # Delete old db entries of the image: $dbw->delete( 'oldimage', array( 'oi_name' => $t ), __METHOD__ ); # Delete archive entries of the image: $dbw->delete( 'filearchive', array( 'fa_name' => $t ), __METHOD__ ); # Delete image entry: $dbw->delete( 'image', array( 'img_name' => $t ), __METHOD__ ); $dbw->commit(); $linkCache = LinkCache::singleton(); $linkCache->clear(); } } function deletePermanentlyTalkPage($title) { global $wgDeletePagePermanentlyNamespaces; $talkPage = $title->getTalkPage(); $id = $title->getArticleID(); $ns = $title->getNamespace(); if ( $id != 0 && $wgDeletePagePermanentlyNamespaces[$ns] == true ) { $this->deletePermanently($talkPage); } } }
[edit] DeletePagePermanently.i18n.php
<?php /** * DeletePagePermanently.i18n.php * Internationalisation file * based on Version 1.0 BETA from Ludovic MOUTON (2008) * Wolfgang Stöttinger 2008 * v. 2.0 BETA * GPL */ $messages = array(); /** English */ $messages['en'] = array( 'tab_label' => 'Delete permanently', 'del_impossible' => 'This page can not be deleted permanently', 'ask_deletion' => 'Are you sure, you want to delete this page permanently? All versions and log entries will be deleted. There is no chance to undo this process after completion.', 'yes' => 'Yes', 'del_done' => 'The page has been permanently deleted.', 'del_not_done' => 'The page has NOT been permanently deleted.', 'right-deleteperm' => 'Delete pages permanently' ); /** German (Deutsch) */ $messages['de'] = array( 'tab_label' => 'Dauerhaft löschen', 'del_impossible' => 'Diese Seite kann nicht dauerhaft gelöscht werden.', 'ask_deletion' => 'Sind Sie sicher, dass Sie diese Seite dauerhaft löschen wollen? Es werden alle Versionen und Logeinträge gelöscht. Danach besteht keine Möglichkeit, diesen Vorgang rückgängig zu machen.', 'yes' => 'Ja', 'del_done' => 'Diese Seite wurde dauerhaft gelöscht.', 'del_not_done' => 'Die Seite wurde nicht dauerhaft gelöscht.', 'right-deleteperm' => 'Dauerhaft löschen' ); /** French (Français) */ $messages['fr'] = array( 'tab_label' => 'Supprimer définitivement', 'del_impossible' => 'Cette page ne peut pas être supprimée définitivement.', 'ask_deletion' => 'Êtes-vous sûr de vouloir supprimer cette page définitivement ? Toutes les révisions et les entrées du log seront supprimées. Il sera impossible d\’annuler la suppression.', 'yes' => 'Oui', 'del_done' => 'La page a été supprimée définitivement.', 'del_not_done' => 'La page n\’a pas été supprimée définitivement.', 'right-deleteperm' => 'Supprimer définitivement' ); /** Russian (Русский) */ $messages['ru'] = array( 'tab_label' => 'Удалить с концами', 'del_impossible' => 'Эту страницу невозможно удалить.', 'ask_deletion' => 'Вы собираетесь удалить страницу из БД. Все предыдущие версии записи и история изменений будут удалены без возможности восстановления. Вы уверены?', 'yes' => 'Да, удалить страницу', 'del_done' => 'Страница удалена.', 'del_not_done' => 'Страница НЕ удалена.', 'right-deleteperm' => 'Удалить с концами' ); /** Polish (Polski) */ $messages['pl'] = array( 'tab_label' => 'Usuń trwale', 'del_impossible' => 'Ta strona nie może zostać trwale usunięta', 'ask_deletion' => 'Czy na pewno chcesz trwale usunąć tę stronę? Wszystkie wersje oraz wpisy w historii zostaną usunięte. Nie będzie możliwości cofnąć tego procesu po jego zakończeniu.', 'yes' => 'Tak', 'del_done' => 'Ta strona została trwale usunięta.', 'del_not_done' => 'Ta strona nie została trwale usunięta.', 'right-deleteperm' => 'Usuń trwale' ); /** Portuguese (Português) */ $messages['pt'] = array( 'tab_label' => 'Eliminar permanentemente', 'del_impossible' => 'Esta página não pode ser eliminada permanentemente', 'ask_deletion' => 'Tem certeza que quer eliminar esta página permanentemente? Todas as versões prévias e registros serão excluídos. Não há como reverter este processo após finalizado.', 'yes' => 'Sim', 'del_done' => 'A página foi eliminada permanentemente.', 'del_not_done' => 'A página NÃO foi eliminada.', 'right-deleteperm' => 'Eliminar permanentemente' ); $messages['pt-br'] = $messages['pt']; //No differences here between Brazilian and European Portuguese /** Spanish (Español-España)*/ $messages['es'] = array( 'tab_label' => 'Borrar permanentemente', 'del_impossible' => 'Esta página no se puede eliminar de forma permanente', 'ask_deletion' => '¿Está seguro, que desea eliminar esta página de forma permanente? Todas las versiones y las entradas de registro serán borradas. No hay ninguna posibilidad de deshacer este proceso después de su finalización.', 'yes' => 'Si', 'del_done' => 'La página ha sido borrada permanentemente.', 'del_not_done' => 'La página no ha sido borrada permanentemente.', 'right-deleteperm' => 'Borrar permanentemente' ); /** Japanese(日本語) */ $messages['ja'] = array( 'tab_label' => '完全削除', 'del_impossible' => 'このページは完全削除できません。', 'ask_deletion' => 'あなたはこのページを完全に削除しようとしています。このページに関するデータやログは完全に削除され、恒久的に復元することはできません。', 'yes' => '上記の内容を完全に理解して完全削除する', 'del_done' => 'このページは完全に削除されました。', 'del_not_done' => '完全削除ができませんでした。', 'right-deleteperm' => 'ページの完全削除' );
[edit] MediaWiki 1.16.x
If you are using MediaWiki 1.16.x, please use the following code as DeletePagePermanently.php
<?php /** * DeletePagePermanently.php * based on Version 1.0 BETA from Ludovic MOUTON (2008) * Wolfgang Stöttinger 2008 * v. 2.1.3 BETA * GPL * * BE CAREFUL WHEN USING THIS EXTENSION. ONCE A PAGE IS DELETED, IT CAN NOT BE RESTORED ANY MORE. * Changed in Version 2.1.3: * - Correctly displays on Vector skin * - Also deletes thumbnails on images * - Using alternate methods to delete files due do deprecation of FileStore in MW 1.16.x * Changed in Version 2.1.2: * - Update category count * Changed in Version 2.1.1: * - Title is removed from cache. * Changed in Version 2.1.0: * - deletePage() can now be used from outside in PHP. * * Features of Version 2.0: * - defined $wgDeletePagePermanentlyNamespaces as an array of namespaces in which pages can be deleted. * $wgDeletePagePermanentlyNamespaces = array ( * NS_MAIN => true, * NS_IMAGE => true, * NS_CATEGORY => true, * NS_TEMPLATE => true, * NS_TALK => true, * ); * * - The tab "Delete permanently" is only shown on pages that can be deleted. * - An aditional page to approve the deletion * - Also log entries are deleted. * - Also redirects, external links, language links, searchindex entries, page_restrictions, pagelinks, categorylinks, templatelinks, archive entries and image links are deleted. * - The watchlist entries are also removed. * - If the page is an image page, all versions of the image are deleted from the database, the archive and the filesystem. (Thumbnlais won't be removed) */ if (!defined('MEDIAWIKI')) { exit(1); } $wgExtensionCredits['other'][] = array ( 'name' => 'DeletePagePermanently', 'version' => '2.1', 'author' => 'Ludovic MOUTON, Wolfgang STÖTTINGER', 'description' => 'Adds a new delete tab to each page. Pages are deleted permanently from the database.', 'url' => 'http://www.mediawiki.org/wiki/Extension:DeletePagePermanently', ); # Default settings $wgGroupPermissions['*']['deleteperm'] = false; $wgGroupPermissions['user']['deleteperm'] = false; $wgGroupPermissions['bureaucrat']['deleteperm'] = false; $wgGroupPermissions['sysop']['deleteperm'] = true; $wgDeletePagePermanentlyNamespaces = array ( NS_MAIN => true, NS_IMAGE => true, NS_CATEGORY => true, NS_TEMPLATE => true, NS_TALK => true, ); $wgExtensionMessagesFiles['DeletePagePermanently'] = dirname(__FILE__) . '/DeletePagePermanently.i18n.php'; $wgExtensionFunctions[] = 'wfDeletePagePermanently'; function wfDeletePagePermanently() { new DeletePagePermanently(); return true; } class DeletePagePermanently { function DeletePagePermanently() { global $wgHooks, $wgMessageCache, $wgUser; wfLoadExtensionMessages('DeletePagePermanently'); $wgMessageCache->addMessage('delete_permanently', wfMsg('tab_label')); $wgHooks['SkinTemplateContentActions'][] = array ( &$this, 'AddContentHook' ); $wgHooks['SkinTemplateNavigation'][] = array ( &$this, 'AddVectorHook' ); $wgHooks['UnknownAction'][] = array ( &$this, 'AddActionHook' ); } function AddContentHook(&$content_actions) { global $wgRequest, $wgRequest, $wgTitle, $wgUser, $wgDeletePagePermanentlyNamespaces; if (!$wgUser->isAllowed('deleteperm')) return false; $action = $wgRequest->getText('action'); #Special pages can not be deleted (special pages have no article id anyway). if ($wgTitle->getArticleID() != 0 && $wgDeletePagePermanentlyNamespaces[$wgTitle->getNamespace()] == true && $wgTitle->getNamespace() != NS_SPECIAL) { wfLoadExtensionMessages('DeletePagePermanently'); $content_actions['ask_delete_permanently'] = array ( 'class' => $action == 'ask_delete_permanently' ? 'selected' : false, 'text' => wfMsg('tab_label'), 'href' => $wgTitle->getLocalUrl('action=ask_delete_permanently') ); } return true; } function AddVectorHook(&$sktemplate, &$links) { global $wgRequest, $wgRequest, $wgTitle, $wgUser, $wgDeletePagePermanentlyNamespaces; if (!$wgUser->isAllowed('deleteperm')) return false; $action = $wgRequest->getText('action'); #Special pages can not be deleted (special pages have no article id anyway). if ($wgTitle->getArticleID() != 0 && $wgDeletePagePermanentlyNamespaces[$wgTitle->getNamespace()] == true && $wgTitle->getNamespace() != NS_SPECIAL) { wfLoadExtensionMessages('DeletePagePermanently'); $links['actions']['ask_delete_permanently'] = array ( 'class' => $action == 'ask_delete_permanently' ? 'selected' : false, 'text' => wfMsg('delete_permanently'), 'href' => $wgTitle->getLocalUrl('action=ask_delete_permanently') ); } return true; } function AddActionHook($action, $wgArticle) { global $wgOut, $wgUser, $wgDeletePagePermanentlyNamespaces; wfLoadExtensionMessages('DeletePagePermanently'); if (!$wgUser->isAllowed('deleteperm')) { $wgOut->permissionRequired('deleteperm'); return false; } # Print a form to approve deletion if ($action == 'ask_delete_permanently') { $action = $wgArticle->getTitle()->escapeLocalUrl() . "&action=delete_permanently"; $wgOut->addHTML("<form id='ask_delete_permanently' method='post' action=\"$action\"> <table> <tr> <td>" . wfMsg('ask_deletion') . "</td> </tr> <tr> <td><input type='submit' name='submit' value=\"" . wfMsg('yes') . "\" /></td> </tr> </table></form>"); return false; } # Perform actual deletion elseif ($action == 'delete_permanently') { $ns = $wgArticle->mTitle->getNamespace(); $t = $wgArticle->mTitle->getDBkey(); $id = $wgArticle->mTitle->getArticleID(); if ($t == '' || $id == 0 || $wgDeletePagePermanentlyNamespaces[$ns] != true || $ns == NS_SPECIAL) { $wgOut->addHTML(wfMsgHtml('del_impossible')); return false; } $this->deletePermanently($wgArticle->mTitle); $wgOut->addHTML(wfMsgHtml('del_done')); return false; } //$wgOut->addHTML(wfMsgHtml('del_not_done')); return true; } function deletePermanently($title) { global $wgOut; $ns = $title->getNamespace(); $t = $title->getDBkey(); $id = $title->getArticleID(); $cats = $title->getParentCategories(); $dbw = wfGetDB(DB_MASTER); $dbw->begin(); #### ## First delete entries, which are in direct relation with the page: #### # delete redirect... $dbw->delete('redirect', array ('rd_from' => $id), __METHOD__); # delete external link... $dbw->delete('externallinks', array ('el_from' => $id), __METHOD__); # delete language link... $dbw->delete('langlinks', array ('ll_from' => $id), __METHOD__); # delete search index... $dbw->delete('searchindex', array ('si_page' => $id), __METHOD__); # Delete restrictions for the page $dbw->delete('page_restrictions', array ('pr_page' => $id), __METHOD__); # Delete page Links $dbw->delete('pagelinks', array ('pl_from' => $id), __METHOD__); # delete category links $dbw->delete('categorylinks', array ('cl_from' => $id), __METHOD__); # delete template links $dbw->delete('templatelinks', array ('tl_from' => $id), __METHOD__); # read text entries for all revisions and delete them. $res = $dbw->select('revision', 'rev_text_id', "rev_page=$id"); while ($row = $dbw->fetchObject($res)) { $value = $row->rev_text_id; $dbw->delete('text', array ('old_id' => $value), __METHOD__); } # In the table 'revision' : Delete all the revision of the page where 'rev_page' = $id $dbw->delete('revision', array ('rev_page' => $id), __METHOD__); # delete image links $dbw->delete('imagelinks', array ('il_from' => $id), __METHOD__); #### ## then delete entries which are not in direct relation with the page: #### # Clean up recentchanges entries... $dbw->delete('recentchanges', array ( 'rc_namespace' => $ns, 'rc_title' => $t ), __METHOD__); # read text entries for all archived pages and delete them. $res = $dbw->select('archive', 'ar_text_id', array ( 'ar_namespace' => $ns, 'ar_title' => $t )); while ($row = $dbw->fetchObject($res)) { $value = $row->ar_text_id; $dbw->delete('text', array ('old_id' => $value), __METHOD__); } # Clean archive entries... $dbw->delete('archive', array ( 'ar_namespace' => $ns, 'ar_title' => $t ), __METHOD__); # Clean up log entries... $dbw->delete('logging', array ( 'log_namespace' => $ns, 'log_title' => $t ), __METHOD__); # Clean up watchlist... $dbw->delete('watchlist', array ( 'wl_namespace' => $ns, 'wl_title' => $t ), __METHOD__); # In the table 'page' : Delete the page entry $dbw->delete('page', array ('page_id' => $id), __METHOD__); #### ## If the article belongs to a category, update category counts #### if (!empty($cats)) { foreach ($cats as $parentcat => $currentarticle) { $catname = split(':', $parentcat, 2); $cat = Category::newFromName($catname[1]); $cat->refreshCounts(); } } #### ## If an image is beeing deleted, some extra work needs to be done #### if ($ns == NS_IMAGE) { $file = wfFindFile($t); if ($file) { # Get all filenames of old versions: $fields = OldLocalFile::selectFields(); $res = $dbw->select('oldimage', $fields, array ('oi_name' => $t)); while ($row = $dbw->fetchObject($res)) { $oldLocalFile = OldLocalFile::newFromRow($row, $file->repo); $path = $oldLocalFile->getArchivePath() . '/' . $oldLocalFile->getArchiveName(); try { @unlink($path); } catch (Exception $e) { $wgOut->addHTML($e->getMessage()); } } $path = $file->getPath(); try { $file->purgeThumbnails(); @unlink($path); } catch (Exception $e) { $wgOut->addHTML($e->getMessage()); } } # clean the filearchive for the given filename: $dbw->delete('filearchive', array ('fa_name' => $t), __METHOD__); # Delete old db entries of the image: $dbw->delete('oldimage', array ('oi_name' => $t), __METHOD__); # Delete archive entries of the image: $dbw->delete('filearchive', array ('fa_name' => $t), __METHOD__); # Delete image entry: $dbw->delete('image', array ('img_name' => $t), __METHOD__); $dbw->commit(); $linkCache = LinkCache::singleton(); $linkCache->clear(); } } }

