r96397 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r96396‎ | r96397 | r96398 >
Date:02:16, 7 September 2011
Author:svemir
Status:resolved (Comments)
Tags:
Comment:
Removing files and globals that will not be needed in version 0.8
SphinxMWSeach is now the default mode of operation
Use 127.0.0.1 instead of localhost by default (for Windows users)
Modified paths:
  • /trunk/extensions/SphinxSearch/SphinxSearch.js (deleted) (history)
  • /trunk/extensions/SphinxSearch/SphinxSearch.php (modified) (history)
  • /trunk/extensions/SphinxSearch/SphinxSearch_body.php (deleted) (history)

Diff [purge]

Index: trunk/extensions/SphinxSearch/SphinxSearch_body.php
@@ -1,872 +0,0 @@
2 -<?php
3 -
4 -/**
5 - * Class file for the SphinxSearch extension
6 - *
7 - * http://www.mediawiki.org/wiki/Extension:SphinxSearch
8 - *
9 - * Released under GNU General Public License (see http://www.fsf.org/licenses/gpl.html)
10 - *
11 - * @file
12 - * @ingroup Extensions
13 - * @author Svemir Brkic <svemir@deveblog.com> and Paul Grinberg
14 - */
15 -
16 -class SphinxSearch extends SpecialPage {
17 -
18 - var $search_term = ''; // what are we looking for
19 - var $namespaces = array(); // namespaces to search
20 - var $categories = array(); // categories to include
21 - var $exc_categories = array(); // categories to exclude
22 - var $page = 1; // results page we are on
23 -
24 - /**
25 - * Build a set of next/previous links for a given title
26 - *
27 - * @param Title $title
28 - * @return string
29 - */
30 - function __construct() {
31 - global $wgDisableInternalSearch, $wgAutoloadClasses;
32 -
33 - if ( $wgDisableInternalSearch ) {
34 - parent::__construct( 'Search' );
35 - } else {
36 - parent::__construct( 'SphinxSearch' );
37 - }
38 -
39 -
40 -
41 - return true;
42 - }
43 -
44 - /**
45 - * Determine which namespaces may be included in a search
46 - *
47 - * @return array
48 - */
49 - function searchableNamespaces() {
50 - $namespaces = SearchEngine::searchableNamespaces();
51 -
52 - wfRunHooks( 'SphinxSearchFilterSearchableNamespaces', array( &$namespaces ) );
53 -
54 - return $namespaces;
55 - }
56 -
57 - /**
58 - * Determine which categories may be included in a search
59 - *
60 - * @return array
61 - */
62 - function searchableCategories() {
63 - global $wgSphinxTopSearchableCategory;
64 -
65 - if ( $wgSphinxTopSearchableCategory ) {
66 - $categories = self::getChildrenCategories( $wgSphinxTopSearchableCategory );
67 - } else {
68 - $categories = array();
69 - }
70 -
71 - wfRunHooks( 'SphinxSearchGetSearchableCategories', array( &$categories ) );
72 -
73 - return $categories;
74 - }
75 -
76 - /**
77 - * Determine sub-categories of a given category
78 - *
79 - * @param string $parent
80 - * @return array
81 - */
82 - function getChildrenCategories( $parent ) {
83 - global $wgMemc, $wgDBname;
84 -
85 - $categories = null;
86 - if ( is_object( $wgMemc ) ) {
87 - $cache_key = $wgDBname . ':sphinx_cats:' . md5( $parent );
88 - $categories = $wgMemc->get( $cache_key );
89 - }
90 -
91 - if ( !is_array( $categories ) ) {
92 - $categories = array();
93 - $dbr = wfGetDB( DB_SLAVE );
94 - $res = $dbr->select(
95 - array( 'categorylinks', 'page' ),
96 - array( 'cl_from', 'cl_sortkey', 'page_title' ),
97 - array( '1',
98 - 'cl_from = page_id',
99 - 'cl_to' => $parent,
100 - 'page_namespace' => NS_CATEGORY ),
101 - __METHOD__,
102 - array( 'ORDER BY' => 'cl_sortkey' )
103 - );
104 - while ( $x = $dbr->fetchObject ( $res ) ) {
105 - $categories[$x->cl_from] = $x->cl_sortkey;
106 - }
107 - if ( $cache_key ) {
108 - # cache query results for a day
109 - $wgMemc->set( $cache_key, $categories, 86400 );
110 - }
111 - $dbr->freeResult( $res );
112 - }
113 - return $categories;
114 - }
115 -
116 - /**
117 - * $wgAjaxExportList callback - create a category filter sub-menu
118 - *
119 - * @param string $parent_id
120 - * @return string
121 - */
122 - function ajaxGetCategoryChildren( $parent_id ) {
123 -
124 - $title = Title::newFromID( $parent_id );
125 -
126 - if ( !$title ) {
127 - return false;
128 - }
129 -
130 - # Retrieve page_touched for the category
131 - $dbkey = $title->getDBkey();
132 - $dbr = wfGetDB( DB_SLAVE );
133 - $touched = $dbr->selectField(
134 - 'page', 'page_touched',
135 - array(
136 - 'page_namespace' => NS_CATEGORY,
137 - 'page_title' => $dbkey,
138 - ),
139 - __METHOD__
140 - );
141 -
142 - $response = new AjaxResponse();
143 -
144 - if ( $response->checkLastModified( $touched ) ) {
145 - return $response;
146 - }
147 -
148 - $categories = self::getChildrenCategories( $dbkey );
149 -
150 - $html = self::getCategoryCheckboxes( $categories, $parent_id );
151 -
152 - $response->addText( $html );
153 -
154 - return $response;
155 - }
156 -
157 - /**
158 - * Main execution function
159 - *
160 - * @param string $par Parameters passed to the page
161 - */
162 - function execute( $par ) {
163 - global $wgRequest, $wgOut, $wgUser, $wgSphinxMatchAll, $wgSphinxSearch_index_list;
164 -
165 - # extract the options from the GET query
166 - $term = $wgRequest->getText( 'search', $par );
167 - if ( $term === '' ) {
168 - $term = $wgRequest->getText( 'sphinxsearch', $par );
169 - }
170 - # see if we want to go the title directly
171 - # this logic is actually reversed (if we are not doing a search,
172 - # thn try to go to title directly). This is needed because IE has a
173 - # different behavior when the <ENTER> button is pressed in a form -
174 - # it does not send the name of the default button!
175 - if ( !$wgRequest->getVal( 'fulltext' ) ) {
176 - $this->goResult( $term );
177 - }
178 -
179 - $this->setHeaders();
180 - $wgOut->setPagetitle( wfMsg( 'sphinxsearch' ) );
181 -
182 - $this->namespaces = array();
183 - $all_namespaces = self::searchableNamespaces();
184 - foreach ( $all_namespaces as $ns => $name ) {
185 - if ( $wgRequest->getCheck( "ns{$ns}" ) ) {
186 - $this->namespaces[] = $ns;
187 - }
188 - }
189 - if ( !count( $this->namespaces ) ) {
190 - foreach ( $all_namespaces as $ns => $name ) {
191 - if ( $wgUser->getOption( 'searchNs' . $ns ) ) {
192 - $this->namespaces[] = $ns;
193 - }
194 - }
195 - }
196 -
197 - $this->categories = $wgRequest->getIntArray( "cat", array() );
198 - $this->exc_categories = $wgRequest->getIntArray( "exc", array() );
199 -
200 - $this->page = $wgRequest->getInt( 'page', 1 );
201 - $wgSphinxMatchAll = $wgRequest->getInt( 'match_all', intval( $wgSphinxMatchAll ) );
202 - $match_titles_only = ( $wgRequest->getInt( 'match_titles' ) == 1 );
203 -
204 - # do the actual search
205 - $found = 0;
206 - $cl = $this->prepareSphinxClient( $term, $match_titles_only );
207 - if ( $cl ) {
208 - $res = $cl->Query(
209 - addcslashes( $this->search_term, '/()[]"!' ),
210 - $wgSphinxSearch_index_list
211 - );
212 - if ( $res === false ) {
213 - $wgOut->addWikiText( wfMsg( 'sphinxSearchFailed', $cl->GetLastError() ) . "\n" );
214 - } else {
215 - $found = $this->wfSphinxDisplayResults( $term, $res, $cl );
216 - }
217 - } else {
218 - $wgOut->addWikiText( wfMsg( 'sphinxClientFailed' ) . "\n" );
219 - }
220 -
221 - # prepare for the next search
222 - if ( $found ) {
223 - $this->createNextPageBar( $found, $term );
224 - }
225 -
226 - $this->createNewSearchForm( $term );
227 - }
228 -
229 - /**
230 - * If an exact title match can be found, jump straight ahead to it.
231 - *
232 - * @param string $term
233 - */
234 - function goResult( $term ) {
235 - global $wgOut, $wgGoToEdit;
236 -
237 - # Try to go to page as entered.
238 - $t = Title::newFromText( $term );
239 -
240 - # If the string cannot be used to create a title
241 - if ( is_null( $t ) ) {
242 - return;
243 - }
244 -
245 - # If there's an exact or very near match, jump right there.
246 - $t = SearchEngine::getNearMatch( $term );
247 - wfRunHooks( 'SphinxSearchGetNearMatch', array( &$term, &$t ) );
248 - if ( !is_null( $t ) ) {
249 - $wgOut->redirect( $t->getFullURL() );
250 - return;
251 - }
252 -
253 - # No match, generate an edit URL
254 - $t = Title::newFromText( $term );
255 - if ( !is_null( $t ) ) {
256 - # If the feature is enabled, go straight to the edit page
257 - if ( $wgGoToEdit ) {
258 - $wgOut->redirect( $t->getFullURL( 'action=edit' ) );
259 - return;
260 - }
261 - }
262 -
263 - $wgOut->addWikiText( wfMsg( 'searchmenu-new', wfEscapeWikiText( $term ) ) );
264 - }
265 -
266 - /**
267 - * Set the maximum number of results to return
268 - * and how many to skip before returning the first.
269 - *
270 - * @param int $limit
271 - * @param int $offset
272 - * @access public
273 - */
274 - function setLimitOffset( $limit, $offset = 0 ) {
275 - global $wgSphinxSearch_matches;
276 -
277 - $wgSphinxSearch_matches = intval( $limit );
278 -
279 - if ( $offset > 0 && $limit > 0 ) {
280 - $this->page = 1 + intval( $offset / $limit );
281 - }
282 - }
283 -
284 - /**
285 - * Set which namespaces the search should include.
286 - * Give an array of namespace index numbers.
287 - *
288 - * @param array $namespaces
289 - * @access public
290 - */
291 - function setNamespaces( $namespaces ) {
292 - $this->namespaces = $namespaces;
293 - }
294 -
295 - /**
296 - * Perform a full text search query and return a result set.
297 - *
298 - * @param string $term - Raw search term
299 - * @return SphinxSearchResultSet
300 - * @access public
301 - */
302 - function searchText( $term, $titles_only = false ) {
303 - global $wgSphinxSearch_index_list;
304 -
305 - $cl = $this->prepareSphinxClient( $term, $titles_only );
306 - if ( $cl ) {
307 - $res = $cl->Query(
308 - addcslashes( $this->search_term, '/()[]"!' ),
309 - $wgSphinxSearch_index_list
310 - );
311 - } else {
312 - $res = false;
313 - }
314 -
315 - if ( $res === false ) {
316 - return null;
317 - } else {
318 - return new SphinxSearchResultSet( $term, $res, $cl );
319 - }
320 - }
321 -
322 - /**
323 - * Perform a title-only search query and return a result set.
324 - *
325 - * @param string $term - Raw search term
326 - * @return SphinxSearchResultSet
327 - * @access public
328 - */
329 - function searchTitle( $term ) {
330 - return $this->searchText( $term, true );
331 - }
332 -
333 - /**
334 - * Search for "$term"
335 - * Display the results of the search one page at a time.
336 - * Returns the number of matches.
337 - */
338 - function prepareSphinxClient( $term, $match_titles_only = false ) {
339 - global $wgSphinxSearch_sortmode, $wgSphinxSearch_sortby, $wgSphinxSearch_host,
340 - $wgSphinxSearch_port, $wgSphinxSearch_index_weights, $wgSphinxSearch_index,
341 - $wgSphinxSearch_matches, $wgSphinxSearch_mode, $wgSphinxSearch_weights,
342 - $wgSphinxMatchAll, $wgSphinxSearch_maxmatches, $wgSphinxSearch_cutoff;
343 -
344 - # don't do anything for blank searches
345 - if ( trim( $term ) === '' ) {
346 - return false;
347 - }
348 -
349 - wfRunHooks( 'SphinxSearchBeforeResults', array(
350 - &$term,
351 - &$this->page,
352 - &$this->namespaces,
353 - &$this->categories,
354 - &$this->exc_categories
355 - ) );
356 -
357 - if ( $wgSphinxSearch_mode == SPH_MATCH_EXTENDED && $wgSphinxMatchAll != '1' ) {
358 - # make OR the default in extended mode
359 - $this->search_term = preg_replace( '/[\s_\-&]+/', '|', trim( $term ) );
360 - } else {
361 - $this->search_term = $term;
362 - }
363 -
364 - $cl = new SphinxClient();
365 -
366 - # setup the options for searching
367 - if ( isset( $wgSphinxSearch_host ) && isset( $wgSphinxSearch_port ) ) {
368 - $cl->SetServer( $wgSphinxSearch_host, $wgSphinxSearch_port );
369 - }
370 - if ( count( $wgSphinxSearch_weights ) ) {
371 - if ( is_string( key( $wgSphinxSearch_weights ) ) ) {
372 - $cl->SetFieldWeights( $wgSphinxSearch_weights );
373 - } else {
374 - $cl->SetWeights( $wgSphinxSearch_weights );
375 - }
376 - }
377 - if ( is_array( $wgSphinxSearch_index_weights ) ) {
378 - $cl->SetIndexWeights( $wgSphinxSearch_index_weights );
379 - }
380 - if ( isset( $wgSphinxSearch_mode ) ) {
381 - $cl->SetMatchMode( $wgSphinxSearch_mode );
382 - }
383 - if ( count( $this->namespaces ) ) {
384 - $cl->SetFilter( 'page_namespace', $this->namespaces );
385 - }
386 -
387 - if ( count( $this->categories ) ) {
388 - $cl->SetFilter( 'category', $this->categories );
389 - }
390 -
391 - if ( count( $this->exc_categories ) ) {
392 - $cl->SetFilter( 'category', $this->exc_categories, true );
393 - }
394 -
395 - $cl->SetSortMode( $wgSphinxSearch_sortmode, $wgSphinxSearch_sortby );
396 - $cl->SetLimits(
397 - ( $this->page - 1 ) * $wgSphinxSearch_matches,
398 - $wgSphinxSearch_matches,
399 - $wgSphinxSearch_maxmatches,
400 - $wgSphinxSearch_cutoff
401 - );
402 -
403 - if ( $match_titles_only ) {
404 - $this->search_term = '@page_title ' . $this->search_term;
405 - }
406 -
407 - wfRunHooks( 'SphinxSearchBeforeQuery', array( &$this->search_term, &$cl ) );
408 -
409 - return $cl;
410 - }
411 -
412 - function wfSphinxDisplayResults( $term, $res, $cl ) {
413 -
414 - global $wgOut, $wgSphinxSuggestMode, $wgSphinxSearch_matches,
415 - $wgSphinxSearch_index, $wgSphinxSearch_maxmatches;
416 -
417 - if ($cl->GetLastWarning()) {
418 - $wgOut->addWikiText( wfMsg( 'sphinxSearchWarning', $cl->GetLastWarning() ) . "\n\n");
419 - }
420 - $found = $res['total_found'];
421 -
422 - if ( $wgSphinxSuggestMode ) {
423 - $didyoumean = $this->spell();
424 - if ( $didyoumean ) {
425 - $wgOut->addhtml( wfMsg( 'sphinxSearchDidYouMean' ) .
426 - " <b><a href='" .
427 - $this->getActionURL( $didyoumean, $this->namespaces ) .
428 - "1'>" . $didyoumean . '</a></b>'
429 - );
430 - }
431 - }
432 -
433 - $from = min(
434 - ( ( $this->page - 1 ) * $wgSphinxSearch_matches ) + 1,
435 - $res['total']
436 - );
437 - $to = min(
438 - $this->page * $wgSphinxSearch_matches,
439 - $res['total']
440 - );
441 - $wgOut->addWikiText( wfMsgExt( 'sphinxSearchPreamble', 'parsemag',
442 - $from, $to, $res['total'], $term, $res['time'] )
443 - );
444 -
445 - if ( is_array( $res["words"] ) ) {
446 - $warn = false;
447 - foreach ( $res["words"] as $word => $info ) {
448 - $wgOut->addWikiText(
449 - wfMsgExt( 'sphinxSearchStats', 'parsemag', $word, $info['hits'], $info['docs'] )
450 - );
451 - if ( ( $info['docs'] < $wgSphinxSearch_maxmatches ) && ( $info['docs'] > $res['total'] ) ) {
452 - $warn = true;
453 - }
454 - }
455 - if ( $warn ) {
456 - $wgOut->addWikiText( wfMsg( 'sphinxSearchStatsInfo' ) );
457 - } else {
458 - $wgOut->addWikiText( "\n" );
459 - }
460 - }
461 - $start_time = microtime( true );
462 -
463 - if ( isset( $res["matches"] ) && is_array( $res["matches"] ) ) {
464 - $wgOut->addWikiText( "----" );
465 - $dbr = wfGetDB( DB_SLAVE );
466 - $excerpts_opt = array(
467 - "before_match" => "<span style='color:red'>",
468 - "after_match" => "</span>",
469 - "chunk_separator" => " ... ",
470 - "limit" => 400,
471 - "around" => 15
472 - );
473 - foreach ( $res["matches"] as $doc => $docinfo ) {
474 - $page_content = $dbr->selectField(
475 - 'text', 'old_text',
476 - array(
477 - 'old_id' => $docinfo['attrs']['old_id']
478 - ),
479 - __METHOD__
480 - );
481 - if ( $page_content ) {
482 - $title_obj = Title::newFromID( $doc );
483 - if ( is_object( $title_obj ) ) {
484 - $wiki_title = $title_obj->getPrefixedText();
485 - $wiki_path = $title_obj->getPrefixedDBkey();
486 - $wgOut->addWikiText( "* <span style='font-size:110%;'>[[:$wiki_path|$wiki_title]]</span>" );
487 -
488 - # uncomment this line to see the weights etc. as HTML comments in the source of the page
489 - # $wgOut->addHTML("<!-- page_id: ".$doc."\ninfo: ".print_r($docinfo, true)." -->");
490 -
491 - $excerpts = $cl->BuildExcerpts(
492 - array( $page_content ),
493 - $wgSphinxSearch_index,
494 - $term,
495 - $excerpts_opt
496 - );
497 - if ( !is_array( $excerpts ) ) {
498 - $excerpts = array( wfMsg( 'sphinxSearchWarning', $cl->GetLastError() ) );
499 - }
500 - foreach ( $excerpts as $entry ) {
501 - # add excerpt to output, removing some wiki markup
502 - $entry = preg_replace( '/([\[\]\{\}\*\#\|\!]+|==+)/',
503 - ' ',
504 - strip_tags( $entry, '<span><br>' )
505 - );
506 - $wgOut->addHTML( "<div style='margin: 0.2em 1em 1em 1em;'>$entry</div>\n" );
507 - }
508 - }
509 - }
510 - }
511 - $time = number_format( microtime( true ) - $start_time, 3);
512 - $wgOut->addWikiText( wfMsg( 'sphinxSearchEpilogue', $time ) );
513 - }
514 -
515 - wfRunHooks( 'SphinxSearchAfterResults', array( $term, $this->page ) );
516 -
517 - return $found;
518 - }
519 -
520 - function getActionURL( $term ) {
521 - global $wgDisableInternalSearch, $wgSphinxMatchAll, $wgRequest;
522 -
523 - $search_title = ( $wgDisableInternalSearch ? 'Search' : 'SphinxSearch' );
524 - $titleObj = SpecialPage::getTitleFor( $search_title );
525 - $qry = $titleObj->getLocalUrl();
526 - $searchField = strtolower( $search_title );
527 - $term = urlencode( $term );
528 - $qry .= ( strpos( $qry, '?' ) === false ? '?' : '&amp;' ) .
529 - $searchField . "={$term}&amp;fulltext=" .
530 - wfMsg( 'sphinxSearchButton' ) . "&amp;";
531 - if ( $wgSphinxMatchAll == '1' ) {
532 - $qry .= "match_all=1&amp;";
533 - }
534 - if ( $wgRequest->getInt( 'match_titles' ) ) {
535 - $qry .= "match_titles=1&amp;";
536 - }
537 - foreach ( $this->namespaces as $ns ) {
538 - $qry .= "ns{$ns}=1&amp;";
539 - }
540 - foreach ( $this->categories as $c ) {
541 - $qry .= "cat[]={$c}&amp;";
542 - }
543 - foreach ( $this->exc_categories as $c ) {
544 - $qry .= "exc[]={$c}&amp;";
545 - }
546 - $qry .= "page=";
547 -
548 - return $qry;
549 - }
550 -
551 - function createNextPageBar( $found, $term ) {
552 - global $wgOut, $wgSphinxSearch_matches;
553 -
554 - $qry = $this->getActionURL( $term );
555 -
556 - $display_pages = 10;
557 - $max_page = ceil( $found / $wgSphinxSearch_matches );
558 - $center_page = floor( ( $this->page + $display_pages ) / 2 );
559 - $first_page = $center_page - $display_pages / 2;
560 - if ( $first_page < 1 ) {
561 - $first_page = 1;
562 - }
563 - $last_page = $first_page + $display_pages - 1;
564 - if ( $last_page > $max_page ) {
565 - $last_page = $max_page;
566 - }
567 - if ( $first_page != $last_page ) {
568 - $wgOut->addWikiText( "----" );
569 - $wgOut->addHTML( "<center>
570 - <table border='0' cellpadding='0' width='1%' cellspacing='0'>
571 - <tr align='center' valign='top'>
572 - <td valign='bottom' nowrap='1'>" . wfMsg( 'sphinxResultPage' ) . "</td>" );
573 -
574 - if ( $first_page > 1 ) {
575 - $prev_page = "<td>&#160;<a href='{$qry}";
576 - $prev_page .= ( $this->page - 1 ) . "'>" . wfMsg( 'sphinxPreviousPage' ) . "</a>&#160;</td>";
577 - $wgOut->addHTML( $prev_page );
578 - }
579 - for ( $i = $first_page; $i < $this->page; $i++ ) {
580 - $wgOut->addHTML( "<td>&#160;<a href='{$qry}{$i}'>{$i}</a>&#160;</td>" );
581 - }
582 - $wgOut->addHTML( "<td>&#160;<b>{$this->page}</b>&#160;</td>" );
583 - for ( $i = $this->page + 1; $i <= $last_page; $i++ ) {
584 - $wgOut->addHTML( "<td>&#160;<a href='{$qry}{$i}'>{$i}</a>&#160;</td>" );
585 - }
586 - if ( $last_page < $max_page ) {
587 - $next_page = "<td>&#160;<a href='{$qry}";
588 - $next_page .= ( $this->page + 1 ) . "'>" . wfMsg( 'sphinxNextPage' ) . "</a>&#160;</td>";
589 - $wgOut->addHTML( $next_page );
590 - }
591 -
592 - $wgOut->addHTML( "</tr></table></center>" );
593 - }
594 - }
595 -
596 - function createNewSearchForm( $term ) {
597 - global $wgOut, $wgDisableInternalSearch, $wgSphinxSearch_mode, $wgSphinxMatchAll,
598 - $wgUseExcludes, $wgUseAjax, $wgJsMimeType, $wgScriptPath,
599 - $wgSphinxSearchExtPath, $wgSphinxSearchJSPath, $wgRequest;
600 -
601 - $search_title = ( $wgDisableInternalSearch ? 'Search' : 'SphinxSearch' );
602 - $titleObj = SpecialPage::getTitleFor( $search_title );
603 - $kiAction = $titleObj->getLocalUrl();
604 - $searchField = strtolower( $search_title );
605 - $wgOut->addHTML( "<form action='$kiAction' method='GET'>
606 - <input type='hidden' name='title' value='" . $titleObj->getPrefixedText() . "'>
607 - <input type='text' name='$searchField' maxlength='100' value='$term'>
608 - <input type='submit' name='fulltext' value='" . wfMsg( 'sphinxSearchButton' ) . "'>" );
609 -
610 - $wgOut->addHTML( "<div style='margin:0.5em 0 0.5em 0;'>" );
611 - if ( $wgSphinxSearch_mode == SPH_MATCH_EXTENDED ) {
612 - $wgOut->addHTML( "<input type='radio' name='match_all' value='0' " .
613 - ( $wgSphinxMatchAll ? "" : "checked='checked'" ) . " />" .
614 - wfMsg( 'sphinxMatchAny' ) .
615 - " <input type='radio' name='match_all' value='1' " .
616 - ( $wgSphinxMatchAll ? "checked='checked'" : "" ) . " />" .
617 - wfMsg( 'sphinxMatchAll' )
618 - );
619 - }
620 - $wgOut->addHTML( " &#160; <input type='checkbox' name='match_titles' value='1' " .
621 - ( $wgRequest->getInt( 'match_titles' ) ? "checked='checked'" : "" ) . ">" .
622 - wfMsg( 'sphinxMatchTitles' ) . "</div>"
623 - );
624 - # get user settings for which namespaces to search
625 - $wgOut->addHTML( "<div style='width:30%; border:1px #eee solid; padding:4px; margin-right:1px; float:left;'>" );
626 - $wgOut->addHTML( wfMsg( 'sphinxSearchInNamespaces' ) . '<br />' );
627 - $all_namespaces = self::searchableNamespaces();
628 - foreach ( $all_namespaces as $ns => $name ) {
629 - $checked = in_array( $ns, $this->namespaces ) ? ' checked="checked"' : '';
630 - $name = str_replace( '_', ' ', $name );
631 - if ( '' == $name ) {
632 - $name = wfMsg( 'blanknamespace' );
633 - }
634 - $wgOut->addHTML( "<label><input type='checkbox' value='1' name='ns$ns'$checked />$name</label><br />" );
635 - }
636 -
637 - $all_categories = self::searchableCategories();
638 - if ( is_array( $all_categories ) && count( $all_categories ) ) {
639 - $cat_parents = $wgRequest->getIntArray( "catp", array() );
640 - $wgOut->addScript( Skin::makeVariablesScript( array(
641 - 'sphinxLoadingMsg' => wfMsg( 'sphinxLoading' ),
642 - 'wgSphinxSearchExtPath' => ( $wgSphinxSearchJSPath ? $wgSphinxSearchJSPath : $wgSphinxSearchExtPath )
643 - ) ) );
644 - $wgOut->addScript(
645 - "<script type='{$wgJsMimeType}' src='" .
646 - ( $wgSphinxSearchJSPath ? $wgSphinxSearchJSPath : $wgSphinxSearchExtPath ) .
647 - "/SphinxSearch.js?2'></script>\n"
648 - );
649 - $wgOut->addHTML( "</div>
650 - <div style='width:30%; border:1px #eee solid; padding:4px; margin-right:1px; float:left;'>"
651 - );
652 - $wgOut->addHTML( wfMsg('sphinxSearchInCategories') );
653 - if ( $wgUseExcludes ) {
654 - $wgOut->addHTML("<div style='float:right; font-size:80%;'>exclude</div>");
655 - }
656 - $wgOut->addHTML('<br />');
657 - $wgOut->addHTML( $this->getCategoryCheckboxes( $all_categories, '', $cat_parents ) );
658 - }
659 - $wgOut->addHTML( "</div></form><br clear='both' />" );
660 -
661 - # Put a Sphinx label for this search
662 - $wgOut->addHTML( "<div style='text-align:center'>" .
663 - wfMsg( 'sphinxPowered', "<a href='http://www.sphinxsearch.com/'>Sphinx</a>" ) .
664 - "</div>"
665 - );
666 - }
667 -
668 - function getCategoryCheckboxes( $all_categories, $parent_id, $cat_parents = array() ) {
669 - global $wgUseAjax, $wgRequest, $wgUseExcludes;
670 -
671 - $html = '';
672 -
673 - foreach ( $all_categories as $cat => $name ) {
674 - $input_attrs = '';
675 - if ( $this && in_array( $cat, $this->categories ) ) {
676 - $input_attrs .= ' checked="checked"';
677 - }
678 - $name = str_replace( '_', ' ', $name );
679 - if ( '' == $name ) {
680 - $name = wfMsg( 'blanknamespace' );
681 - }
682 - $children = '';
683 - if ( isset( $cat_parents['_' . $cat] ) && ( $input_attrs || $cat_parents['_' . $cat] > 0 ) ) {
684 - $title = Title::newFromID( $cat );
685 - $children_cats = self::getChildrenCategories( $title->getDBkey() );
686 - if ( count( $children_cats ) ) {
687 - if ( $this ) {
688 - $children = $this->getCategoryCheckboxes( $children_cats, $cat, $cat_parents );
689 - } else {
690 - $children = self::getCategoryCheckboxes( $children_cats, $cat, $cat_parents );
691 - }
692 - }
693 - }
694 - if ( $wgUseAjax ) {
695 - $input_attrs .= " onmouseup='sphinxShowCats(this)'";
696 - }
697 - $html .= "<label><input type='checkbox' id='{$parent_id}_$cat' value='$cat' name='cat[]'$input_attrs />$name</label>";
698 - if ( $wgUseExcludes ) {
699 - $input_attrs = '';
700 - if ( $this && in_array( $cat, $this->exc_categories ) ) {
701 - $input_attrs .= ' checked="checked"';
702 - }
703 - if ( $wgUseAjax ) {
704 - $input_attrs .= " onmouseup='sphinxShowCats(this)'";
705 - }
706 - $html .= "<input type='checkbox' id='exc_{$parent_id}_$cat' value='$cat' name='exc[]'$input_attrs style='float:right' />";
707 - }
708 - $html .= "<div id='cat{$cat}_children'>$children</div>\n";
709 - }
710 - if ( $parent_id && $html ) {
711 - $html = "<input type='hidden' name='catp[_$parent_id]' value='" .
712 - intval( $cat_parents['_' . $parent_id] ) .
713 - "' /><div style='margin-left:10px; margin-bottom:4px; padding-left:8px; border-left:1px dashed #ccc; border-bottom:1px solid #ccc;'>" .
714 - $html . "</div>";
715 - }
716 - return $html;
717 - }
718 -
719 - function spell() {
720 - $string = str_replace( '"', '', $this->search_term );
721 - $words = preg_split( '/(\s+|\|)/', $string, -1, PREG_SPLIT_NO_EMPTY );
722 - if ( function_exists( 'pspell_check' ) ) {
723 - $suggestion = $this->builtin_spell($words);
724 - } else {
725 - $suggestion = $this->nonnative_spell($words);
726 - }
727 - return $suggestion;
728 - }
729 -
730 - function builtin_spell($words) {
731 - global $wgUser, $wgSphinxSearchPersonalDictionary, $wgSphinxSearchPspellDictionaryDir;
732 -
733 - $ret = '';
734 - $suggestion_needed = false;
735 - foreach ( $words as $word ) {
736 - $pspell_config = pspell_config_create(
737 - $wgUser->getDefaultOption( 'language' ),
738 - $wgUser->getDefaultOption( 'variant' )
739 - );
740 - if ( $wgSphinxSearchPspellDictionaryDir ) {
741 - pspell_config_data_dir( $pspell_config, $wgSphinxSearchPspellDictionaryDir );
742 - pspell_config_dict_dir( $pspell_config, $wgSphinxSearchPspellDictionaryDir );
743 - }
744 - pspell_config_mode( $pspell_config, PSPELL_FAST | PSPELL_RUN_TOGETHER );
745 - if ( $wgSphinxSearchPersonalDictionary ) {
746 - pspell_config_personal( $pspell_config, $wgSphinxSearchPersonalDictionary );
747 - }
748 - $pspell_link = pspell_new_config( $pspell_config );
749 -
750 - if ( !$pspell_link ) {
751 - return wfMsg( 'sphinxPspellError' );
752 - }
753 - if ( !pspell_check( $pspell_link, $word ) ) {
754 - $suggestions = pspell_suggest( $pspell_link, $word );
755 - if ( count( $suggestions ) ) {
756 - $guess = array_shift($suggestions);
757 - } else {
758 - $guess = '';
759 - }
760 - if ( !$guess || (strtolower( $word ) == strtolower( $guess )) ) {
761 - $ret .= "$word ";
762 - } else {
763 - $ret .= "$guess ";
764 - $suggestion_needed = true;
765 - }
766 - } else {
767 - $ret .= "$word ";
768 - }
769 - }
770 -
771 - return ( $suggestion_needed ? trim( $ret ) : '' );
772 - }
773 -
774 - function nonnative_spell($words) {
775 - global $wgUser, $wgSphinxSearchPersonalDictionary, $wgSphinxSearchAspellPath;
776 -
777 - // aspell will only return mis-spelled words, so remember all here
778 - $word_suggestions = array();
779 - foreach ( $words as $word ) {
780 - $word_suggestions[$word] = $word;
781 - }
782 -
783 - // prepare the system call with optional dictionary
784 - $aspellcommand = 'echo ' . escapeshellarg( join( ' ', $words ) ) .
785 - ' | ' . escapeshellarg( $wgSphinxSearchAspellPath ) .
786 - ' -a --ignore-accents --ignore-case';
787 - if ( $wgUser ) {
788 - $aspellcommand .= ' --lang=' . $wgUser->getDefaultOption( 'language' );
789 - }
790 - if ( $wgSphinxSearchPersonalDictionary ) {
791 - $aspellcommand .= ' --home-dir=' . dirname( $wgSphinxSearchPersonalDictionary );
792 - $aspellcommand .= ' -p ' . basename( $wgSphinxSearchPersonalDictionary );
793 - }
794 -
795 - // run aspell
796 - $shell_return = shell_exec( $aspellcommand );
797 -
798 - // parse return line by line
799 - $returnarray = explode( "\n", $shell_return );
800 - $suggestion_needed = false;
801 - foreach ( $returnarray as $key => $value ) {
802 - // lines with suggestions start with &
803 - if ( substr( $value, 0, 1 ) == "&" ) {
804 - $correction = explode( " ", $value );
805 - $word = $correction[1];
806 - $suggestions = substr( $value, strpos( $value, ":" ) + 2 );
807 - $suggestions = explode( ", ", $suggestions );
808 - if (count($suggestions)) {
809 - $guess = array_shift($suggestions);
810 - if ( strtolower( $word ) != strtolower( $guess ) ) {
811 - $word_suggestions[$word] = $guess;
812 - $suggestion_needed = true;
813 - }
814 - }
815 - }
816 - }
817 -
818 - return ( $suggestion_needed ? join( ' ', $word_suggestions ) : '' );
819 - }
820 -
821 -}
822 -
823 -/**
824 - * @ingroup Search
825 - */
826 -class SphinxSearchResultSet extends SearchResultSet {
827 - var $mNdx = 0;
828 -
829 - function __construct( $term, $rs, $cl ) {
830 - global $wgSphinxSearch_index;
831 -
832 - $this->mResultSet = array();
833 - if ( is_array( $rs ) && is_array( $rs['matches'] ) ) {
834 - $dbr = wfGetDB( DB_SLAVE );
835 - foreach ( $rs['matches'] as $id => $docinfo ) {
836 - $res = $dbr->select(
837 - 'page',
838 - array( 'page_id', 'page_title', 'page_namespace' ),
839 - array( 'page_id' => $id ),
840 - __METHOD__,
841 - array()
842 - );
843 - if ( $dbr->numRows( $res ) > 0 ) {
844 - $this->mResultSet[] = $dbr->fetchObject( $res );
845 - }
846 - }
847 - }
848 - $this->mNdx = 0;
849 - $this->mTerms = $term;
850 - }
851 -
852 - function termMatches() {
853 - return $this->mTerms;
854 - }
855 -
856 - function numRows() {
857 - return count( $this->mResultSet );
858 - }
859 -
860 - function next() {
861 - if ( isset( $this->mResultSet[$this->mNdx] ) ) {
862 - $row = $this->mResultSet[$this->mNdx];
863 - ++$this->mNdx;
864 - return new SearchResult( $row );
865 - } else {
866 - return false;
867 - }
868 - }
869 -
870 - function free() {
871 - unset( $this->mResultSet );
872 - }
873 -}
Index: trunk/extensions/SphinxSearch/SphinxSearch.js
@@ -1,54 +0,0 @@
2 -function sphinxShowCats(input) {
3 -
4 - var parent_id = input.id.substring(0, input.id.indexOf('_'));
5 - var delta = (input.checked ? -1 : 1);
6 - var parent_fld = input.form['catp[_' + parent_id + ']'];
7 - var seen_parents = [];
8 - seen_parents[parent_id] = true;
9 - var cnt = input.form.elements.length;
10 -
11 - while (parent_fld) {
12 - var parent_cnt = parseInt(parent_fld.value);
13 - if (isNaN(parent_cnt)) {
14 - parent_cnt = 0;
15 - }
16 - parent_fld.value = parent_cnt + delta;
17 - parent_fld = null;
18 - for (var i = 0; i < cnt; i++) {
19 - var el = input.form.elements[i];
20 - if (el.name.indexOf('catp') == 0) {
21 - var grandparent_id = el.name.replace(/[^\d]+/g, '');
22 - if (seen_parents[grandparent_id]) {
23 - continue;
24 - }
25 - if (document.getElementById(grandparent_id + '_' + parent_id)) {
26 - parent_fld = input.form['catp[_' + grandparent_id + ']'];
27 - seen_parents[grandparent_id] = true;
28 - }
29 - }
30 - }
31 - }
32 -
33 - if (input.checked) {
34 - return;
35 - }
36 -
37 - var div = document.getElementById('cat' + input.value + '_children');
38 - if (div.innerHTML.length > 10) {
39 - return;
40 - }
41 -
42 - injectSpinner( input, 'sphinxsearch' );
43 -
44 - function f( request ) {
45 - var result = request.responseText;
46 -
47 - if (request.status != 200) {
48 - result = "<div class='error'> " + request.status + " " + request.statusText + ": " + result + "</div>";
49 - }
50 - removeSpinner( 'sphinxsearch' );
51 - div.innerHTML = result;
52 - }
53 -
54 - sajax_do_call( "SphinxSearch::ajaxGetCategoryChildren", [input.value] , f );
55 -}
\ No newline at end of file
Index: trunk/extensions/SphinxSearch/SphinxSearch.php
@@ -11,7 +11,7 @@
1212
1313 $wgExtensionCredits['specialpage'][] = array(
1414 'path' => __FILE__,
15 - 'version' => '0.7.2',
 15+ 'version' => '0.8.0',
1616 'name' => 'SphinxSearch',
1717 'author' => array( 'Svemir Brkic', 'Paul Grinberg' ),
1818 'email' => 'svemir at deveblog dot com, gri6507 at yahoo dot com',
@@ -26,20 +26,16 @@
2727 # To completely disable the default search and replace it with SphinxSearch,
2828 # set this BEFORE including SphinxSearch.php in LocalSettings.php
2929 # $wgSearchType = 'SphinxSearch';
 30+
 31+# prior to version 0.8.0 there was a SphinxSearch search type
 32+if ( $wgSearchType == 'SphinxSearch' ) {
 33+ $wgSearchType == 'SphinxMWSearch';
 34+}
 35+
3036 # To use the new approach (added in 0.7.2) set it to SphinxMWSearch
3137 if ( $wgSearchType == 'SphinxMWSearch' ) {
3238 $wgAutoloadClasses['SphinxMWSearch'] = $dir . 'SphinxMWSearch.php';
33 -} else {
34 - $wgAutoloadClasses['SphinxSearch'] = $dir . 'SphinxSearch_body.php';
35 - if ( $wgSearchType == 'SphinxSearch' ) {
36 - $wgDisableInternalSearch = true;
37 - $wgDisableSearchUpdate = true;
38 - $wgSpecialPages['Search'] = 'SphinxSearch';
39 - $wgDisableSearchUpdate = true;
40 - } else {
41 - $wgExtensionAliasesFiles['SphinxSearch'] = $dir . 'SphinxSearch.alias.php';
42 - $wgSpecialPages['SphinxSearch'] = 'SphinxSearch';
43 - }
 39+ $wgDisableSearchUpdate = true;
4440 }
4541
4642 # this assumes you have copied sphinxapi.php from your Sphinx
@@ -50,7 +46,7 @@
5147 }
5248
5349 # Host and port on which searchd deamon is running
54 -$wgSphinxSearch_host = 'localhost';
 50+$wgSphinxSearch_host = '127.0.0.1';
5551 $wgSphinxSearch_port = 9312;
5652
5753 # Main sphinx.conf index to search
@@ -76,38 +72,9 @@
7773 $wgSphinxSearch_sortmode = SPH_SORT_RELEVANCE;
7874 $wgSphinxSearch_sortby = '';
7975
80 -if ( $wgSearchType == 'SphinxMWSearch' ) {
81 - # Following settings apply only in the new search model
 76+# Set to true to use MW's default search snippets and highlighting
 77+$wgSphinxSearchMWHighlighter = false;
8278
83 - # Set to true to use MW's default search snippets and highlighting
84 - $wgSphinxSearchMWHighlighter = false;
85 -} else {
86 - # Following settings apply only in the old search model
87 -
88 - # By default, search will return articles that match any of the words in the search
89 - # To change that to require all words to match by default, set the following to true
90 - $wgSphinxMatchAll = false;
91 -
92 - # Number of matches to display at once
93 - $wgSphinxSearch_matches = 10;
94 -
95 - # To enable hierarchical category search, specify the top category of your hierarchy
96 - $wgSphinxTopSearchableCategory = '';
97 -
98 - # This will fetch sub-categories as parent categories are checked
99 - # Requires $wgUseAjax to be true
100 - $wgAjaxExportList[] = 'SphinxSearch::ajaxGetCategoryChildren';
101 -
102 - # Allow excluding selected categories when filtering
103 - $wgUseExcludes = false;
104 -
105 - # Web-accessible path to the extension's folder
106 - $wgSphinxSearchExtPath = $wgScriptPath . '/extensions/SphinxSearch';
107 -
108 - # Web-accessible path to the folder with SphinxSearch.js file (if different from $wgSphinxSearchExtPath)
109 - $wgSphinxSearchJSPath = '';
110 -}
111 -
11279 # #########################################################
11380 # Use Aspell to suggest possible misspellings. This can be provided via
11481 # PHP pspell module (http://www.php.net/manual/en/ref.pspell.php)

Follow-up revisions

RevisionCommit summaryAuthorDate
r96413remove unused alias file...svemir11:14, 7 September 2011

Comments

#Comment by Nikerabbit (talk | contribs)   08:15, 7 September 2011
-$wgExtensionAliasesFiles['SphinxSearch'] = $dir . 'SphinxSearch.alias.php';

You didn't remove alias file.

$wgAutoloadClasses['SphinxMWSearch'] = $dir . 'SphinxMWSearch.php';

This line should be outside the if condition.

Why SphinxMWSearch suddenly gets $wgDisableSearchUpdate = true;?

There are also i18n messages in the i18n.php which are no longer used. You should check what messages are still needed and remove the rest.

#Comment by Svemir Brkic (talk | contribs)   11:19, 7 September 2011

Thanks! I made the first two changes in r96413.

$wgDisableSearchUpdate was true for SphinxSearch as well - sphinxsearch index currently has to be updated via cron job. Real-time updates are still a work in progress.

As for removing i18n messages, I am still making some changes and wanted to do that all at once. When I do, should I remove only the English entry, or should I remove each deleted entry from all languages (last time I tried messing with that file someone got mad at me...)

#Comment by Svemir Brkic (talk | contribs)   13:04, 8 September 2011

Unused i18n messages removed in r96561 (some of the remaining ones are not used right now, but will be used again soon.)

#Comment by 😂 (talk | contribs)   20:38, 8 September 2011

Issues raised here have been resolved, marking as such.

Status & tagging log