From: Bartosz DziewoƄski Date: Thu, 12 Jun 2014 14:59:46 +0000 (+0200) Subject: Autocomplete special pages' subpages in search suggestions X-Git-Tag: 1.31.0-rc.0~15389 X-Git-Url: https://git.cyclocoop.org/%7B%24admin_url%7Dcompta/operations/modifier.php?a=commitdiff_plain;h=ef5c2a62e13f8d381b9983cdc49166e455ebab43;p=lhc%2Fweb%2Fwiklou.git Autocomplete special pages' subpages in search suggestions Includes basic "example" implementations for: * Special:Watchlist (predefined subpage list) * Special:Log (based on config variable) Bug: 20210 Change-Id: I2b0505df244b9d23bd23d5fb4d3405dc28d57739 --- diff --git a/RELEASE-NOTES-1.24 b/RELEASE-NOTES-1.24 index 54e78acaa0..746e0c74fa 100644 --- a/RELEASE-NOTES-1.24 +++ b/RELEASE-NOTES-1.24 @@ -64,6 +64,9 @@ production. that won't deplete openssl's entropy pool. * ResourceLoader: File modules can now provide a skip function that uses an inline feature test to bypass loading of the module. +* (bug 20210) Special pages may now provide autocompletion of their subpage + names in search suggestions. Right now the only useful implementation is in + Special:Log, but more are to come. === Bug fixes in 1.24 === * (bug 49116) Footer copyright notice is now always displayed in user language diff --git a/includes/PrefixSearch.php b/includes/PrefixSearch.php index a796d35723..13696ad5e1 100644 --- a/includes/PrefixSearch.php +++ b/includes/PrefixSearch.php @@ -166,10 +166,26 @@ abstract class PrefixSearch { protected function specialSearch( $search, $limit ) { global $wgContLang; - # normalize searchKey, so aliases with spaces can be found - bug 25675 - $search = str_replace( ' ', '_', $search ); + list( $searchKey, $subpageSearch ) = explode( '/', $search, 2 ); + + // Handle subpage search separately. + if ( $subpageSearch !== null ) { + // Try matching the full search string as a page name + $specialTitle = Title::makeTitleSafe( NS_SPECIAL, $searchKey ); + $special = SpecialPageFactory::getPage( $specialTitle->getText() ); + if ( $special ) { + $subpages = $special->prefixSearchSubpages( $subpageSearch, $limit ); + return array_map( function ( $sub ) use ( $specialTitle ) { + return $specialTitle->getSubpage( $sub ); + }, $subpages ); + } else { + return array(); + } + } - $searchKey = $wgContLang->caseFold( $search ); + # normalize searchKey, so aliases with spaces can be found - bug 25675 + $searchKey = str_replace( ' ', '_', $searchKey ); + $searchKey = $wgContLang->caseFold( $searchKey ); // Unlike SpecialPage itself, we want the canonical forms of both // canonical and alias title forms... diff --git a/includes/specialpage/SpecialPage.php b/includes/specialpage/SpecialPage.php index 39681879df..da51a33f7d 100644 --- a/includes/specialpage/SpecialPage.php +++ b/includes/specialpage/SpecialPage.php @@ -329,6 +329,25 @@ class SpecialPage { } } + /** + * Return an array of subpages beginning with $search that this special page will accept. + * + * For example, if a page supports subpages "foo", "bar" and "baz" (as in Special:PageName/foo, + * etc.): + * + * - `prefixSearchSubpages( "ba" )` should return `array( "bar", "baz" )` + * - `prefixSearchSubpages( "f" )` should return `array( "foo" )` + * - `prefixSearchSubpages( "z" )` should return `array()` + * - `prefixSearchSubpages( "" )` should return `array( foo", "bar", "baz" )` + * + * @param string $search Prefix to search for + * @param integer $limit Maximum number of results to return + * @return string[] Matching subpages + */ + public function prefixSearchSubpages( $search, $limit = 10 ) { + return array(); + } + /** * Sets headers - this should be called from the execute() method of all derived classes! */ diff --git a/includes/specials/SpecialLog.php b/includes/specials/SpecialLog.php index 6da66745f4..aaa55a3a21 100644 --- a/includes/specials/SpecialLog.php +++ b/includes/specials/SpecialLog.php @@ -115,6 +115,22 @@ class SpecialLog extends SpecialPage { $this->show( $opts, $qc ); } + /** + * Return an array of subpages beginning with $search that this special page will accept. + * + * @param string $search Prefix to search for + * @param integer $limit Maximum number of results to return + * @return string[] Matching subpages + */ + public function prefixSearchSubpages( $search, $limit = 10 ) { + global $wgLogTypes; + $subpages = $wgLogTypes; + $subpages[] = 'all'; + sort( $subpages ); + $escaped = preg_quote( $search ); + return array_slice( preg_grep( "/^$escaped/i", $subpages ), 0, $limit ); + } + private function parseParams( FormOptions $opts, $par ) { global $wgLogTypes; diff --git a/includes/specials/SpecialWatchlist.php b/includes/specials/SpecialWatchlist.php index 490e81f00b..1add311360 100644 --- a/includes/specials/SpecialWatchlist.php +++ b/includes/specials/SpecialWatchlist.php @@ -79,6 +79,19 @@ class SpecialWatchlist extends ChangesListSpecialPage { parent::execute( $subpage ); } + /** + * Return an array of subpages beginning with $search that this special page will accept. + * + * @param string $search Prefix to search for + * @param integer $limit Maximum number of results to return + * @return string[] Matching subpages + */ + public function prefixSearchSubpages( $search, $limit = 10 ) { + $subpages = array( 'edit', 'raw' ); + $escaped = preg_quote( $search ); + return array_slice( preg_grep( "/^$escaped/i", $subpages ), 0, $limit ); + } + /** * Get a FormOptions object containing the default options *