From: Brion Vibber Date: Wed, 17 Jan 2007 02:38:40 +0000 (+0000) Subject: * Add title prefix search for Special:Undelete X-Git-Tag: 1.31.0-rc.0~54351 X-Git-Url: http://git.cyclocoop.org/%24image?a=commitdiff_plain;h=1ae54a81e9856a876b3ed6146d56c22f03df03df;p=lhc%2Fweb%2Fwiklou.git * Add title prefix search for Special:Undelete * Remove full-archive list from Special:Undelete * Undelete page list can use plural marker Integrating the log more cleanly might be nice. I did a little experimenting with joining on logging -> archive, but found that it wanted to do a big expensive filesort. Additionally we may want to include the filearchive table in here to turn up image versions in the archive that don't have text revisions attached. Prefix search has a hardcoded limit of 100, no paging. --- diff --git a/RELEASE-NOTES b/RELEASE-NOTES index b2146f8df1..c59b3febd1 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -97,6 +97,9 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN * profile AutoLoader * rebuild empty DjVu metadata containing '' * security fix for DjVu metadata retrieval +* Add title prefix search for Special:Undelete +* Remove full-archive list from Special:Undelete +* Undelete page list can use plural marker == Languages updated == diff --git a/includes/SpecialUndelete.php b/includes/SpecialUndelete.php index a156b97966..3d4f5ceb36 100644 --- a/includes/SpecialUndelete.php +++ b/includes/SpecialUndelete.php @@ -24,32 +24,74 @@ function wfSpecialUndelete( $par ) { * @subpackage SpecialPage */ class PageArchive { - var $title; + protected $title; - function PageArchive( &$title ) { + function __construct( $title ) { if( is_null( $title ) ) { throw new MWException( 'Archiver() given a null title.'); } - $this->title =& $title; + $this->title = $title; } /** * List all deleted pages recorded in the archive table. Returns result * wrapper with (ar_namespace, ar_title, count) fields, ordered by page - * namespace/title. Can be called staticaly. + * namespace/title. * * @return ResultWrapper */ - /* static */ function listAllPages() { - $dbr =& wfGetDB( DB_SLAVE ); - $archive = $dbr->tableName( 'archive' ); - - $sql = "SELECT ar_namespace,ar_title, COUNT(*) AS count FROM $archive " . - "GROUP BY ar_namespace,ar_title ORDER BY ar_namespace,ar_title"; - - return $dbr->resultObject( $dbr->query( $sql, 'PageArchive::listAllPages' ) ); + public static function listAllPages() { + $dbr = wfGetDB( DB_SLAVE ); + return self::listPages( $dbr, '' ); + } + + /** + * List deleted pages recorded in the archive table matching the + * given title prefix. + * Returns result wrapper with (ar_namespace, ar_title, count) fields. + * + * @return ResultWrapper + */ + public static function listPagesByPrefix( $prefix ) { + $dbr = wfGetDB( DB_SLAVE ); + + $title = Title::newFromText( $prefix ); + if( $title ) { + $ns = $title->getNamespace(); + $encPrefix = $dbr->escapeLike( $title->getDbKey() ); + } else { + // Prolly won't work too good + // @todo handle bare namespace names cleanly? + $ns = 0; + $encPrefix = $dbr->escapeLike( $prefix ); + } + $conds = array( + 'ar_namespace' => $ns, + "ar_title LIKE '$encPrefix%'", + ); + return self::listPages( $dbr, $conds ); } + protected static function listPages( $dbr, $condition ) { + return $dbr->resultObject( + $dbr->select( + array( 'archive' ), + array( + 'ar_namespace', + 'ar_title', + 'COUNT(*) AS count', + ), + $condition, + __METHOD__, + array( + 'GROUP BY' => 'ar_namespace,ar_title', + 'ORDER BY' => 'ar_namespace,ar_title', + 'LIMIT' => 100, + ) + ) + ); + } + /** * List the revisions of the given page. Returns result wrapper with * (ar_minor_edit, ar_timestamp, ar_user, ar_user_text, ar_comment) fields. @@ -57,7 +99,7 @@ class PageArchive { * @return ResultWrapper */ function listRevisions() { - $dbr =& wfGetDB( DB_SLAVE ); + $dbr = wfGetDB( DB_SLAVE ); $res = $dbr->select( 'archive', array( 'ar_minor_edit', 'ar_timestamp', 'ar_user', 'ar_user_text', 'ar_comment' ), array( 'ar_namespace' => $this->title->getNamespace(), @@ -78,7 +120,7 @@ class PageArchive { */ function listFiles() { if( $this->title->getNamespace() == NS_IMAGE ) { - $dbr =& wfGetDB( DB_SLAVE ); + $dbr = wfGetDB( DB_SLAVE ); $res = $dbr->select( 'filearchive', array( 'fa_id', @@ -119,7 +161,7 @@ class PageArchive { * @return Revision */ function getRevision( $timestamp ) { - $dbr =& wfGetDB( DB_SLAVE ); + $dbr = wfGetDB( DB_SLAVE ); $row = $dbr->selectRow( 'archive', array( 'ar_rev_id', @@ -163,7 +205,7 @@ class PageArchive { return Revision::getRevisionText( $row, "ar_" ); } else { // New-style: keyed to the text storage backend. - $dbr =& wfGetDB( DB_SLAVE ); + $dbr = wfGetDB( DB_SLAVE ); $text = $dbr->selectRow( 'text', array( 'old_text', 'old_flags' ), array( 'old_id' => $row->ar_text_id ), @@ -182,7 +224,7 @@ class PageArchive { * @return string */ function getLastRevisionText() { - $dbr =& wfGetDB( DB_SLAVE ); + $dbr = wfGetDB( DB_SLAVE ); $row = $dbr->selectRow( 'archive', array( 'ar_text', 'ar_flags', 'ar_text_id' ), array( 'ar_namespace' => $this->title->getNamespace(), @@ -201,7 +243,7 @@ class PageArchive { * @return bool */ function isDeleted() { - $dbr =& wfGetDB( DB_SLAVE ); + $dbr = wfGetDB( DB_SLAVE ); $n = $dbr->selectField( 'archive', 'COUNT(ar_title)', array( 'ar_namespace' => $this->title->getNamespace(), 'ar_title' => $this->title->getDBkey() ) ); @@ -282,7 +324,7 @@ class PageArchive { $restoreAll = empty( $timestamps ); - $dbw =& wfGetDB( DB_MASTER ); + $dbw = wfGetDB( DB_MASTER ); $page = $dbw->tableName( 'archive' ); # Does this page already exist? We'll have to update it... @@ -419,10 +461,11 @@ class UndeleteForm { var $mAction, $mTarget, $mTimestamp, $mRestore, $mTargetObj; var $mTargetTimestamp, $mAllowed, $mComment; - function UndeleteForm( &$request, $par = "" ) { + function UndeleteForm( $request, $par = "" ) { global $wgUser; $this->mAction = $request->getVal( 'action' ); $this->mTarget = $request->getVal( 'target' ); + $this->mSearchPrefix = $request->getText( 'prefix' ); $time = $request->getVal( 'timestamp' ); $this->mTimestamp = $time ? wfTimestamp( TS_MW, $time ) : ''; $this->mFile = $request->getVal( 'file' ); @@ -467,9 +510,23 @@ class UndeleteForm { } function execute() { - + global $wgOut; + if ( $this->mAllowed ) { + $wgOut->setPagetitle( wfMsg( "undeletepage" ) ); + } else { + $wgOut->setPagetitle( wfMsg( "viewdeletedpage" ) ); + } + if( is_null( $this->mTargetObj ) ) { - return $this->showList(); + $this->showSearchForm(); + + # List undeletable articles + if( $this->mSearchPrefix ) { + $result = PageArchive::listPagesByPrefix( + $this->mSearchPrefix ); + $this->showList( $result ); + } + return; } if( $this->mTimestamp !== '' ) { return $this->showRevision( $this->mTimestamp ); @@ -483,17 +540,35 @@ class UndeleteForm { return $this->showHistory(); } - /* private */ function showList() { - global $wgLang, $wgContLang, $wgUser, $wgOut; - - # List undeletable articles - $result = PageArchive::listAllPages(); + function showSearchForm() { + global $wgOut, $wgScript; + $wgOut->addWikiText( wfMsg( 'undelete-header' ) ); + + $wgOut->addHtml( + Xml::openElement( 'form', array( + 'method' => 'get', + 'action' => $wgScript ) ) . + '
' . + Xml::element( 'legend', array(), + wfMsg( 'undelete-search-box' ) ) . + Xml::hidden( 'title', + SpecialPage::getTitleFor( 'Undelete' )->getPrefixedDbKey() ) . + Xml::inputLabel( wfMsg( 'undelete-search-prefix' ), + 'prefix', 'prefix', 20, + $this->mSearchPrefix ) . + Xml::submitButton( wfMsg( 'undelete-search-submit' ) ) . + '
' . + '' ); + } - if ( $this->mAllowed ) { - $wgOut->setPagetitle( wfMsg( "undeletepage" ) ); - } else { - $wgOut->setPagetitle( wfMsg( "viewdeletedpage" ) ); + /* private */ function showList( $result ) { + global $wgLang, $wgContLang, $wgUser, $wgOut; + + if( $result->numRows() == 0 ) { + $wgOut->addWikiText( wfMsg( 'undelete-no-results' ) ); + return; } + $wgOut->addWikiText( wfMsg( "undeletepagetext" ) ); $sk = $wgUser->getSkin(); @@ -502,7 +577,10 @@ class UndeleteForm { while( $row = $result->fetchObject() ) { $title = Title::makeTitleSafe( $row->ar_namespace, $row->ar_title ); $link = $sk->makeKnownLinkObj( $undelete, htmlspecialchars( $title->getPrefixedText() ), 'target=' . $title->getPrefixedUrl() ); - $revs = wfMsgHtml( 'undeleterevisions', $wgLang->formatNum( $row->count ) ); + #$revs = wfMsgHtml( 'undeleterevisions', $wgLang->formatNum( $row->count ) ); + $revs = wfMsgExt( 'undeleterevisions', + array( 'parseinline' ), + $wgLang->formatNum( $row->count ) ); $wgOut->addHtml( "
  • {$link} ({$revs})
  • \n" ); } $result->free(); @@ -754,7 +832,7 @@ class UndeleteForm { $this->mFileVersions ); if( $ok ) { - $skin =& $wgUser->getSkin(); + $skin = $wgUser->getSkin(); $link = $skin->makeKnownLinkObj( $this->mTargetObj ); $wgOut->addHtml( wfMsgWikiHtml( 'undeletedpage', $link ) ); return true; diff --git a/languages/messages/MessagesEn.php b/languages/messages/MessagesEn.php index 3aed86e1d4..8332eaf231 100644 --- a/languages/messages/MessagesEn.php +++ b/languages/messages/MessagesEn.php @@ -1773,7 +1773,7 @@ click '''''Restore'''''. To perform a selective restoration, check the boxes cor revisions to be restored, and click '''''Restore'''''. Clicking '''''Reset''''' will clear the comment field and all checkboxes.", 'undeletearticle' => 'Restore deleted page', -'undeleterevisions' => "$1 revisions archived", +'undeleterevisions' => "$1 {{PLURAL:$1|revision|revisions}} archived", 'undeletehistory' => 'If you restore the page, all revisions will be restored to the history. If a new page with the same name has been created since the deletion, the restored revisions will appear in the prior history, and the current revision of the live page @@ -1795,6 +1795,11 @@ revision may have been restored or removed from the archive.", 'undeletedpage' => "'''$1 has been restored''' Consult the [[Special:Log/delete|deletion log]] for a record of recent deletions and restorations.", +'undelete-header' => 'See [[Special:Log/delete|the deletion log]] for recently deleted pages.', +'undelete-search-box' => 'Search deleted pages', +'undelete-search-prefix' => 'Show pages starting with:', +'undelete-search-submit' => 'Search', +'undelete-no-results' => 'No matching pages found in the deletion archive.', # Namespace form on various pages 'namespace' => 'Namespace:',