MediaWiki  master
SearchFormWidget.php
Go to the documentation of this file.
1 <?php
2 
4 
5 use Html;
11 use SpecialSearch;
12 use Xml;
13 
16  protected $specialSearch;
18  protected $searchConfig;
20  protected $profiles;
22  private $hookContainer;
24  private $hookRunner;
25 
32  public function __construct(
36  array $profiles
37  ) {
38  $this->specialSearch = $specialSearch;
39  $this->searchConfig = $searchConfig;
40  $this->hookContainer = $hookContainer;
41  $this->hookRunner = new HookRunner( $hookContainer );
42  $this->profiles = $profiles;
43  }
44 
55  public function render(
56  $profile,
57  $term,
58  $numResults,
59  $totalResults,
60  $offset,
61  $isPowerSearch,
62  array $options = []
63  ) {
64  $user = $this->specialSearch->getUser();
65 
66  return '<div class="mw-search-form-wrapper">' .
68  'form',
69  [
70  'id' => $isPowerSearch ? 'powersearch' : 'search',
71  // T151903: default to POST in case JS is disabled
72  'method' => ( $isPowerSearch && $user->isLoggedIn() ) ? 'post' : 'get',
73  'action' => wfScript(),
74  ]
75  ) .
76  '<div id="mw-search-top-table">' .
77  $this->shortDialogHtml( $profile, $term, $numResults, $totalResults, $offset, $options ) .
78  '</div>' .
79  "<div class='mw-search-visualclear'></div>" .
80  "<div class='mw-search-profile-tabs'>" .
81  $this->profileTabsHtml( $profile, $term ) .
82  "<div style='clear:both'></div>" .
83  "</div>" .
84  $this->optionsHtml( $term, $isPowerSearch, $profile ) .
85  '</form>' .
86  '</div>';
87  }
88 
98  protected function shortDialogHtml(
99  $profile,
100  $term,
101  $numResults,
102  $totalResults,
103  $offset,
104  array $options = []
105  ) {
106  $html = '';
107 
108  $searchWidget = new SearchInputWidget( $options + [
109  'id' => 'searchText',
110  'name' => 'search',
111  'autofocus' => trim( $term ) === '',
112  'title' => $this->specialSearch->msg( 'searchsuggest-search' )->text(),
113  'value' => $term,
114  'dataLocation' => 'content',
115  'infusable' => true,
116  ] );
117 
118  $layout = new \OOUI\ActionFieldLayout( $searchWidget, new \OOUI\ButtonInputWidget( [
119  'type' => 'submit',
120  'label' => $this->specialSearch->msg( 'searchbutton' )->text(),
121  'flags' => [ 'progressive', 'primary' ],
122  ] ), [
123  'align' => 'top',
124  ] );
125 
126  $html .= $layout;
127 
128  if ( $this->specialSearch->getPrefix() !== '' ) {
129  $html .= Html::hidden( 'prefix', $this->specialSearch->getPrefix() );
130  }
131 
132  if ( $totalResults > 0 && $offset < $totalResults ) {
133  $html .= Xml::tags(
134  'div',
135  [
136  'class' => 'results-info',
137  'data-mw-num-results-offset' => $offset,
138  'data-mw-num-results-total' => $totalResults
139  ],
140  $this->specialSearch->msg( 'search-showingresults' )
141  ->numParams( $offset + 1, $offset + $numResults, $totalResults )
142  ->numParams( $numResults )
143  ->parse()
144  );
145  }
146 
147  $html .=
148  Html::hidden( 'title', $this->specialSearch->getPageTitle()->getPrefixedText() ) .
149  Html::hidden( 'profile', $profile ) .
150  Html::hidden( 'fulltext', '1' );
151 
152  return $html;
153  }
154 
162  protected function profileTabsHtml( $profile, $term ) {
163  $bareterm = $this->startsWithImage( $term )
164  ? substr( $term, strpos( $term, ':' ) + 1 )
165  : $term;
166  $lang = $this->specialSearch->getLanguage();
167  $items = [];
168  foreach ( $this->profiles as $id => $profileConfig ) {
169  $profileConfig['parameters']['profile'] = $id;
170  $tooltipParam = isset( $profileConfig['namespace-messages'] )
171  ? $lang->commaList( $profileConfig['namespace-messages'] )
172  : null;
173  $items[] = Xml::tags(
174  'li',
175  [ 'class' => $profile === $id ? 'current' : 'normal' ],
176  $this->makeSearchLink(
177  $bareterm,
178  $this->specialSearch->msg( $profileConfig['message'] )->text(),
179  $this->specialSearch->msg( $profileConfig['tooltip'], $tooltipParam )->text(),
180  $profileConfig['parameters']
181  )
182  );
183  }
184 
185  return "<div class='search-types'>" .
186  "<ul>" . implode( '', $items ) . "</ul>" .
187  "</div>";
188  }
189 
196  protected function startsWithImage( $term ) {
197  $parts = explode( ':', $term );
198  return count( $parts ) > 1
199  ? MediaWikiServices::getInstance()->getContentLanguage()->getNsIndex( $parts[0] ) ===
200  NS_FILE
201  : false;
202  }
203 
213  protected function makeSearchLink( $term, $label, $tooltip, array $params = [] ) {
214  $params += [
215  'search' => $term,
216  'fulltext' => 1,
217  ];
218 
219  return Xml::element(
220  'a',
221  [
222  'href' => $this->specialSearch->getPageTitle()->getLocalURL( $params ),
223  'title' => $tooltip,
224  ],
225  $label
226  );
227  }
228 
238  protected function optionsHtml( $term, $isPowerSearch, $profile ) {
239  $html = '';
240 
241  if ( $isPowerSearch ) {
242  $html .= $this->powerSearchBox( $term, [] );
243  } else {
244  $form = '';
245  $this->getHookRunner()->onSpecialSearchProfileForm(
246  $this->specialSearch, $form, $profile, $term, [] );
247  $html .= $form;
248  }
249 
250  return $html;
251  }
252 
259  protected function powerSearchBox( $term, array $opts ) {
260  $rows = [];
261  $activeNamespaces = $this->specialSearch->getNamespaces();
262  $langConverter = $this->specialSearch->getLanguage();
263  foreach ( $this->searchConfig->searchableNamespaces() as $namespace => $name ) {
264  $subject = MediaWikiServices::getInstance()->getNamespaceInfo()->
265  getSubject( $namespace );
266  if ( !isset( $rows[$subject] ) ) {
267  $rows[$subject] = "";
268  }
269 
270  $name = $langConverter->convertNamespace( $namespace );
271  if ( $name === '' ) {
272  $name = $this->specialSearch->msg( 'blanknamespace' )->text();
273  }
274 
275  $rows[$subject] .=
276  '<td>' .
278  $name,
279  "ns{$namespace}",
280  "mw-search-ns{$namespace}",
281  in_array( $namespace, $activeNamespaces )
282  ) .
283  '</td>';
284  }
285 
286  // Lays out namespaces in multiple floating two-column tables so they'll
287  // be arranged nicely while still accomodating diferent screen widths
288  $tableRows = [];
289  foreach ( $rows as $row ) {
290  $tableRows[] = "<tr>{$row}</tr>";
291  }
292  $namespaceTables = [];
293  foreach ( array_chunk( $tableRows, 4 ) as $chunk ) {
294  $namespaceTables[] = implode( '', $chunk );
295  }
296 
297  $showSections = [
298  'namespaceTables' => "<table>" . implode( '</table><table>', $namespaceTables ) . '</table>',
299  ];
300  $this->getHookRunner()->onSpecialSearchPowerBox( $showSections, $term, $opts );
301 
302  $hidden = '';
303  foreach ( $opts as $key => $value ) {
304  $hidden .= Html::hidden( $key, $value );
305  }
306 
307  $divider = "<div class='divider'></div>";
308 
309  // Stuff to feed SpecialSearch::saveNamespaces()
310  $user = $this->specialSearch->getUser();
311  $remember = '';
312  if ( $user->isLoggedIn() ) {
313  $remember = $divider . Xml::checkLabel(
314  $this->specialSearch->msg( 'powersearch-remember' )->text(),
315  'nsRemember',
316  'mw-search-powersearch-remember',
317  false,
318  // The token goes here rather than in a hidden field so it
319  // is only sent when necessary (not every form submission)
320  [ 'value' => $user->getEditToken(
321  'searchnamespace',
322  $this->specialSearch->getRequest()
323  ) ]
324  );
325  }
326 
327  return "<fieldset id='mw-searchoptions'>" .
328  "<legend>" . $this->specialSearch->msg( 'powersearch-legend' )->escaped() . '</legend>' .
329  "<h4>" . $this->specialSearch->msg( 'powersearch-ns' )->parse() . '</h4>' .
330  // Handled by JavaScript if available
331  '<div id="mw-search-togglebox">' .
332  '<label>' . $this->specialSearch->msg( 'powersearch-togglelabel' )->escaped() . '</label>' .
333  '<input type="button" id="mw-search-toggleall" value="' .
334  $this->specialSearch->msg( 'powersearch-toggleall' )->escaped() . '"/>' .
335  '<input type="button" id="mw-search-togglenone" value="' .
336  $this->specialSearch->msg( 'powersearch-togglenone' )->escaped() . '"/>' .
337  '</div>' .
338  $divider .
339  implode(
340  $divider,
341  $showSections
342  ) .
343  $hidden .
344  $remember .
345  "</fieldset>";
346  }
347 
352  protected function getHookContainer() {
353  return $this->hookContainer;
354  }
355 
362  protected function getHookRunner() {
363  return $this->hookRunner;
364  }
365 }
MediaWiki\Search\SearchWidgets\SearchFormWidget
Definition: SearchFormWidget.php:14
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:149
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:37
MediaWiki\Search\SearchWidgets\SearchFormWidget\$hookRunner
HookRunner $hookRunner
Definition: SearchFormWidget.php:24
NS_FILE
const NS_FILE
Definition: Defines.php:75
MediaWiki\Search\SearchWidgets\SearchFormWidget\startsWithImage
startsWithImage( $term)
Check if query starts with image: prefix.
Definition: SearchFormWidget.php:196
MediaWiki\Search\SearchWidgets\SearchFormWidget\$profiles
array $profiles
Definition: SearchFormWidget.php:20
Xml\openElement
static openElement( $element, $attribs=null)
This opens an XML element.
Definition: Xml.php:108
MediaWiki\Search\SearchWidgets\SearchFormWidget\getHookRunner
getHookRunner()
Definition: SearchFormWidget.php:362
MediaWiki\MediaWikiServices\getInstance
static getInstance()
Returns the global default instance of the top level service locator.
Definition: MediaWikiServices.php:180
MediaWiki\Search\SearchWidgets\SearchFormWidget\$specialSearch
SpecialSearch $specialSearch
Definition: SearchFormWidget.php:16
wfScript
wfScript( $script='index')
Get the path to a specified script file, respecting file extensions; this is a wrapper around $wgScri...
Definition: GlobalFunctions.php:2530
Xml\element
static element( $element, $attribs=null, $contents='', $allowShortTag=true)
Format an XML element with given attributes and, optionally, text content.
Definition: Xml.php:41
MediaWiki\Widget\SearchInputWidget
Search input widget.
Definition: SearchInputWidget.php:11
Html\hidden
static hidden( $name, $value, array $attribs=[])
Convenience function to produce an input element with type=hidden.
Definition: Html.php:802
MediaWiki\Search\SearchWidgets\SearchFormWidget\makeSearchLink
makeSearchLink( $term, $label, $tooltip, array $params=[])
Make a search link with some target namespaces.
Definition: SearchFormWidget.php:213
MediaWiki\Search\SearchWidgets\SearchFormWidget\optionsHtml
optionsHtml( $term, $isPowerSearch, $profile)
Generates HTML for advanced options available with the currently selected search profile.
Definition: SearchFormWidget.php:238
MediaWiki\Search\SearchWidgets\SearchFormWidget\shortDialogHtml
shortDialogHtml( $profile, $term, $numResults, $totalResults, $offset, array $options=[])
Definition: SearchFormWidget.php:98
Xml\tags
static tags( $element, $attribs, $contents)
Same as Xml::element(), but does not escape contents.
Definition: Xml.php:130
SpecialSearch
implements Special:Search - Run text & title search and display the output
Definition: SpecialSearch.php:38
MediaWiki\Search\SearchWidgets\SearchFormWidget\getHookContainer
getHookContainer()
Definition: SearchFormWidget.php:352
MediaWiki\Search\SearchWidgets
Definition: BasicSearchResultSetWidget.php:3
MediaWiki\Search\SearchWidgets\SearchFormWidget\powerSearchBox
powerSearchBox( $term, array $opts)
Definition: SearchFormWidget.php:259
SearchEngineConfig
Configuration handling class for SearchEngine.
Definition: SearchEngineConfig.php:12
MediaWiki\HookContainer\HookContainer
HookContainer class.
Definition: HookContainer.php:44
MediaWiki\HookContainer\HookRunner
This class provides an implementation of the core hook interfaces, forwarding hook calls to HookConta...
Definition: HookRunner.php:563
MediaWiki\Search\SearchWidgets\SearchFormWidget\profileTabsHtml
profileTabsHtml( $profile, $term)
Generates HTML for the list of available search profiles.
Definition: SearchFormWidget.php:162
MediaWiki\Search\SearchWidgets\SearchFormWidget\$hookContainer
$hookContainer
Definition: SearchFormWidget.php:22
Xml
Module of static functions for generating XML.
Definition: Xml.php:28
MediaWiki\Search\SearchWidgets\SearchFormWidget\render
render( $profile, $term, $numResults, $totalResults, $offset, $isPowerSearch, array $options=[])
Definition: SearchFormWidget.php:55
MediaWiki\Search\SearchWidgets\SearchFormWidget\$searchConfig
SearchEngineConfig $searchConfig
Definition: SearchFormWidget.php:18
Xml\checkLabel
static checkLabel( $label, $name, $id, $checked=false, $attribs=[])
Convenience function to build an HTML checkbox with a label.
Definition: Xml.php:423
MediaWiki\Search\SearchWidgets\SearchFormWidget\__construct
__construct(SpecialSearch $specialSearch, SearchEngineConfig $searchConfig, HookContainer $hookContainer, array $profiles)
Definition: SearchFormWidget.php:32
Html
This class is a collection of static functions that serve two purposes:
Definition: Html.php:49