return self::listPages( $dbr, '' );
}
+ /**
+ * List deleted pages recorded in the archive matching the
+ * given term, using search engine archive.
+ * Returns result wrapper with (ar_namespace, ar_title, count) fields.
+ *
+ * @param string $term Search term
+ * @return ResultWrapper
+ */
+ public static function listPagesBySearch( $term ) {
+ $title = Title::newFromText( $term );
+ if ( $title ) {
+ $ns = $title->getNamespace();
+ $termMain = $title->getText();
+ $termDb = $title->getDBkey();
+ } else {
+ // Prolly won't work too good
+ // @todo handle bare namespace names cleanly?
+ $ns = 0;
+ $termMain = $termDb = $term;
+ }
+
+ // Try search engine first
+ $engine = MediaWikiServices::getInstance()->newSearchEngine();
+ $engine->setLimitOffset( 100 );
+ $engine->setNamespaces( [ $ns ] );
+ $results = $engine->searchArchiveTitle( $termMain );
+ if ( !$results->isOK() ) {
+ $results = [];
+ } else {
+ $results = $results->getValue();
+ }
+
+ if ( !$results ) {
+ // Fall back to regular prefix search
+ return self::listPagesByPrefix( $term );
+ }
+
+ $dbr = wfGetDB( DB_REPLICA );
+ $condTitles = array_unique( array_map( function ( Title $t ) {
+ return $t->getDBkey();
+ }, $results ) );
+ $conds = [
+ 'ar_namespace' => $ns,
+ $dbr->makeList( [ 'ar_title' => $condTitles ], LIST_OR ) . " OR ar_title " .
+ $dbr->buildLike( $termDb, $dbr->anyString() )
+ ];
+
+ return self::listPages( $dbr, $conds );
+ }
+
/**
* List deleted pages recorded in the archive table matching the
* given title prefix.
$fields = [
'ar_minor_edit', 'ar_timestamp', 'ar_user', 'ar_user_text',
'ar_comment', 'ar_len', 'ar_deleted', 'ar_rev_id', 'ar_sha1',
+ 'ar_page_id'
];
if ( $this->config->get( 'ContentHandlerUseDB' ) ) {
$restored = 0; // number of revisions restored
/** @var Revision $revision */
$revision = null;
-
+ $restoredPages = [];
// If there are no restorable revisions, we can skip most of the steps.
if ( $latestRestorableRow === null ) {
$failedRevisionCount = $rev_count;
Hooks::run( 'ArticleRevisionUndeleted',
[ &$this->title, $revision, $row->ar_page_id ] );
+ $restoredPages[$row->ar_page_id] = true;
}
// Now that it's safely stored, take it out of the archive
);
}
- Hooks::run( 'ArticleUndelete', [ &$this->title, $created, $comment, $oldPageId ] );
+ Hooks::run( 'ArticleUndelete',
+ [ &$this->title, $created, $comment, $oldPageId, $restoredPages ] );
if ( $this->title->getNamespace() == NS_FILE ) {
DeferredUpdates::addUpdate( new HTMLCacheUpdate( $this->title, 'imagelinks' ) );
}
return null;
}
+ /**
+ * Perform a title search in the article archive.
+ * NOTE: these results still should be filtered by
+ * matching against PageArchive, permissions checks etc
+ * The results returned by this methods are only sugegstions and
+ * may not end up being shown to the user.
+ *
+ * @param string $term Raw search term
+ * @return Status<Title[]>
+ * @since 1.29
+ */
+ function searchArchiveTitle( $term ) {
+ return Status::newGood( [] );
+ }
+
/**
* Perform a title-only search query and return a result set.
* If title searches are not supported or disabled, return null.
* @ingroup SpecialPage
*/
+use MediaWiki\MediaWikiServices;
use Wikimedia\Rdbms\ResultWrapper;
/**
/** @var Title */
private $mTargetObj;
+ /**
+ * @var string Search prefix
+ */
+ private $mSearchPrefix;
function __construct() {
parent::__construct( 'Undelete', 'deletedhistory' );
Xml::openElement( 'form', [ 'method' => 'get', 'action' => wfScript() ] ) .
Xml::fieldset( $this->msg( 'undelete-search-box' )->text() ) .
Html::hidden( 'title', $this->getPageTitle()->getPrefixedDBkey() ) .
+ Html::hidden( 'fuzzy', $this->getRequest()->getVal( 'fuzzy' ) ) .
Html::rawElement(
'label',
[ 'for' => 'prefix' ],
20,
$this->mSearchPrefix,
[ 'id' => 'prefix', 'autofocus' => '' ]
- ) . ' ' .
- Xml::submitButton( $this->msg( 'undelete-search-submit' )->text() ) .
+ ) .
+ ' ' .
+ Xml::submitButton(
+ $this->msg( 'undelete-search-submit' )->text(),
+ [ 'id' => 'searchUndelete' ]
+ ) .
Xml::closeElement( 'fieldset' ) .
Xml::closeElement( 'form' )
);
# List undeletable articles
if ( $this->mSearchPrefix ) {
- $result = PageArchive::listPagesByPrefix( $this->mSearchPrefix );
+ // For now, we enable search engine match only when specifically asked to
+ // by using fuzzy=1 parameter.
+ if ( $this->getRequest()->getVal( "fuzzy", false ) ) {
+ $result = PageArchive::listPagesBySearch( $this->mSearchPrefix );
+ } else {
+ $result = PageArchive::listPagesByPrefix( $this->mSearchPrefix );
+ }
$this->showList( $result );
}
}
$linkRenderer = $this->getLinkRenderer();
$undelete = $this->getPageTitle();
- $out->addHTML( "<ul>\n" );
+ $out->addHTML( "<ul id='undeleteResultsList'>\n" );
foreach ( $result as $row ) {
$title = Title::makeTitleSafe( $row->ar_namespace, $row->ar_title );
if ( $title !== null ) {
);
}
$revs = $this->msg( 'undeleterevisions' )->numParams( $row->count )->parse();
- $out->addHTML( "<li>{$item} ({$revs})</li>\n" );
+ $out->addHTML( "<li class='undeleteResult'>{$item} ({$revs})</li>\n" );
}
$result->free();
$out->addHTML( "</ul>\n" );