Use quickUserCan instead of userCan for searches
[lhc/web/wiklou.git] / includes / specials / SpecialSearch.php
index c2b5f9b..f44703c 100644 (file)
@@ -30,7 +30,7 @@
 class SpecialSearch extends SpecialPage {
        /**
         * Current search profile. Search profile is just a name that identifies
-        * the active search tab on the search page (content, help, discussions...)
+        * the active search tab on the search page (content, discussions...)
         * For users tt replaces the set of enabled namespaces from the query
         * string when applicable. Extensions can add new profiles with hooks
         * with custom search options just for that profile.
@@ -207,8 +207,10 @@ class SpecialSearch extends SpecialPage {
 
                $profile = new ProfileSection( __METHOD__ );
                $search = $this->getSearchEngine();
-               $search->setLimitOffset( $this->limit, $this->offset );
+               // Request an extra result to determine whether a "next page" link is useful
+               $search->setLimitOffset( $this->limit + 1, $this->offset );
                $search->setNamespaces( $this->namespaces );
+               $this->saveNamespaces();
                $search->prefix = $this->mPrefix;
                $term = $search->transformSearchTerm( $term );
 
@@ -226,7 +228,11 @@ class SpecialSearch extends SpecialPage {
                                $out->addHTML(
                                        Xml::openElement( 'fieldset' ) .
                                        Xml::element( 'legend', null, $this->msg( 'search-external' )->text() ) .
-                                       Xml::element( 'p', array( 'class' => 'mw-searchdisabled' ), $this->msg( 'searchdisabled' )->text() ) .
+                                       Xml::element(
+                                               'p',
+                                               array( 'class' => 'mw-searchdisabled' ),
+                                               $this->msg( 'searchdisabled' )->text()
+                                       ) .
                                        $this->msg( 'googlesearch' )->rawParams(
                                                htmlspecialchars( $term ),
                                                'UTF-8',
@@ -284,7 +290,8 @@ class SpecialSearch extends SpecialPage {
                                $stParams
                        );
 
-                       $this->didYouMeanHtml = '<div class="searchdidyoumean">' . $this->msg( 'search-suggest' )->rawParams( $suggestLink )->text() . '</div>';
+                       $this->didYouMeanHtml = '<div class="searchdidyoumean">'
+                               . $this->msg( 'search-suggest' )->rawParams( $suggestLink )->text() . '</div>';
                }
 
                if ( !wfRunHooks( 'SpecialSearchResultsPrepend', array( $this, $out, $term ) ) ) {
@@ -363,9 +370,12 @@ class SpecialSearch extends SpecialPage {
                        // Show the create link ahead
                        $this->showCreateLink( $title, $num, $titleMatches, $textMatches );
                        if ( $totalRes > $this->limit || $this->offset ) {
-                               $prevnext = $this->getLanguage()->viewPrevNext( $this->getPageTitle(), $this->offset, $this->limit,
+                               $prevnext = $this->getLanguage()->viewPrevNext(
+                                       $this->getPageTitle(),
+                                       $this->offset,
+                                       $this->limit,
                                        $this->powerSearchOptions() + array( 'search' => $term ),
-                                       max( $titleMatchesNum, $textMatchesNum ) < $this->limit
+                                       max( $titleMatchesNum, $textMatchesNum ) <= $this->limit
                                );
                        }
                        wfRunHooks( 'SpecialSearchResults', array( $term, &$titleMatches, &$textMatches ) );
@@ -402,7 +412,7 @@ class SpecialSearch extends SpecialPage {
                if ( $num === 0 ) {
                        if ( $textStatus ) {
                                $out->addHTML( '<div class="error">' .
-                                       htmlspecialchars( $textStatus->getWikiText( 'search-error' ) ) . '</div>' );
+                                       $textStatus->getMessage( 'search-error' ) . '</div>' );
                        } else {
                                $out->wrapWikiMsg( "<p class=\"mw-search-nonefound\">\n$1</p>",
                                        array( 'search-nonefound', wfEscapeWikiText( $term ) ) );
@@ -439,12 +449,16 @@ class SpecialSearch extends SpecialPage {
 
                if ( $title->isKnown() ) {
                        $messageName = 'searchmenu-exists';
-               } elseif ( $title->userCan( 'create', $this->getUser() ) ) {
+               } elseif ( $title->quickUserCan( 'create', $this->getUser() ) ) {
                        $messageName = 'searchmenu-new';
                } else {
                        $messageName = 'searchmenu-new-nocreate';
                }
-               $params = array( $messageName, wfEscapeWikiText( $title->getPrefixedText() ), Message::numParam( $num ) );
+               $params = array(
+                       $messageName,
+                       wfEscapeWikiText( $title->getPrefixedText() ),
+                       Message::numParam( $num )
+               );
                wfRunHooks( 'SpecialSearchCreateLink', array( $title, &$params ) );
 
                // Extensions using the hook might still return an empty $messageName
@@ -510,6 +524,37 @@ class SpecialSearch extends SpecialPage {
                return $opt + $this->extraParams;
        }
 
+       /**
+        * Save namespace preferences when we're supposed to
+        *
+        * @return bool Whether we wrote something
+        */
+       protected function saveNamespaces() {
+               $user = $this->getUser();
+               $request = $this->getRequest();
+
+               if ( $user->isLoggedIn() &&
+                       !is_null( $request->getVal( 'nsRemember' ) ) &&
+                       $user->matchEditToken( $request->getVal( 'nsToken' ) )
+               ) {
+                       // Reset namespace preferences: namespaces are not searched
+                       // when they're not mentioned in the URL parameters.
+                       foreach ( MWNamespace::getValidNamespaces() as $n ) {
+                               $user->setOption( 'searchNs' . $n, false );
+                       }
+                       // The request parameters include all the namespaces we just searched.
+                       // Even if they're the same as an existing profile, they're not eaten.
+                       foreach ( $this->namespaces as $n ) {
+                               $user->setOption( 'searchNs' . $n, true );
+                       }
+
+                       $user->saveSettings();
+                       return true;
+               }
+
+               return false;
+       }
+
        /**
         * Show whole set of results
         *
@@ -525,9 +570,11 @@ class SpecialSearch extends SpecialPage {
 
                $out = "<ul class='mw-search-results'>\n";
                $result = $matches->next();
-               while ( $result ) {
+               $count = 0;
+               while ( $result && $count < $this->limit ) {
                        $out .= $this->showHit( $result, $terms );
                        $result = $matches->next();
+                       $count++;
                }
                $out .= "</ul>\n";
 
@@ -708,7 +755,8 @@ class SpecialSearch extends SpecialPage {
                        &$score, &$size, &$date, &$related,
                        &$html
                ) ) ) {
-                       $html = "<li><div class='mw-search-result-heading'>{$link} {$redirect} {$section} {$fileMatch}</div> {$extract}\n" .
+                       $html = "<li><div class='mw-search-result-heading'>" .
+                               "{$link} {$redirect} {$section} {$fileMatch}</div> {$extract}\n" .
                                "<div class='mw-search-result-data'>{$score}{$size} - {$date}{$related}</div>" .
                                "</li>\n";
                }
@@ -734,7 +782,8 @@ class SpecialSearch extends SpecialPage {
 
                // work out custom project captions
                $customCaptions = array();
-               $customLines = explode( "\n", $this->msg( 'search-interwiki-custom' )->text() ); // format per line <iwprefix>:<caption>
+               // format per line <iwprefix>:<caption>
+               $customLines = explode( "\n", $this->msg( 'search-interwiki-custom' )->text() );
                foreach ( $customLines as $line ) {
                        $parts = explode( ":", $line, 2 );
                        if ( count( $parts ) == 2 ) { // validate line
@@ -756,8 +805,7 @@ class SpecialSearch extends SpecialPage {
                        }
                }
 
-
-               // TODO: should support paging in a non-confusing way (not sure how though, maybe via ajax)..
+               // @todo Should support paging in a non-confusing way (not sure how though, maybe via ajax)..
                $out .= "</ul></div>\n";
 
                // convert the whole thing to desired language variant
@@ -927,6 +975,19 @@ class SpecialSearch extends SpecialPage {
                        $hidden .= Html::hidden( $key, $value );
                }
 
+               # Stuff to feed saveNamespaces()
+               $remember = '';
+               $user = $this->getUser();
+               if ( $user->isLoggedIn() ) {
+                       $remember .= Html::hidden( 'nsToken', $user->getEditToken() ) .
+                       Xml::checkLabel(
+                               wfMessage( 'powersearch-remember' )->text(),
+                               'nsRemember',
+                               'mw-search-powersearch-remember',
+                               false
+                       );
+               }
+
                // Return final output
                return Xml::openElement(
                        'fieldset',
@@ -938,6 +999,8 @@ class SpecialSearch extends SpecialPage {
                        Xml::element( 'div', array( 'class' => 'divider' ), '', false ) .
                        implode( Xml::element( 'div', array( 'class' => 'divider' ), '', false ), $showSections ) .
                        $hidden .
+                       Xml::element( 'div', array( 'class' => 'divider' ), '', false ) .
+                       $remember .
                        Xml::closeElement( 'fieldset' );
        }
 
@@ -962,14 +1025,6 @@ class SpecialSearch extends SpecialPage {
                                'tooltip' => 'searchprofile-images-tooltip',
                                'namespaces' => array( NS_FILE ),
                        ),
-                       'help' => array(
-                               'message' => 'searchprofile-project',
-                               'tooltip' => 'searchprofile-project-tooltip',
-                               'namespaces' => SearchEngine::helpNamespaces(),
-                               'namespace-messages' => SearchEngine::namespacesAsText(
-                                       SearchEngine::helpNamespaces()
-                               ),
-                       ),
                        'all' => array(
                                'message' => 'searchprofile-everything',
                                'tooltip' => 'searchprofile-everything-tooltip',