plugins/SpecialSearch.php
changeset 218 e0ec986c0af3
parent 181 9237767a23ae
child 221 956263992d48
equal deleted inserted replaced
217:5bcdee999015 218:e0ec986c0af3
    50 }
    50 }
    51 
    51 
    52 function page_Special_Search()
    52 function page_Special_Search()
    53 {
    53 {
    54   global $db, $session, $paths, $template, $plugins; // Common objects
    54   global $db, $session, $paths, $template, $plugins; // Common objects
    55   if(!$q = $paths->getParam(0)) $q = ( isset($_GET['q']) ) ? $_GET['q'] : false;
    55   global $aggressive_optimize_html;
       
    56   $aggressive_optimize_html = false;
       
    57   
       
    58   if ( !$q = $paths->getParam(0) )
       
    59     $q = ( isset($_GET['q']) ) ? $_GET['q'] : '';
       
    60   
    56   if(isset($_GET['words_any']))
    61   if(isset($_GET['words_any']))
    57   {
    62   {
    58     $q = '';
    63     $q = '';
    59     if(!empty($_GET['words_any']))
    64     if(!empty($_GET['words_any']))
    60     {
    65     {
    83       $q .= implode(' ', $req) . ' ';
    88       $q .= implode(' ', $req) . ' ';
    84     }
    89     }
    85   }
    90   }
    86   $q = trim($q);
    91   $q = trim($q);
    87   
    92   
    88   if ( !empty($q) && !isset($_GET['search']) )
    93   $template->header();
       
    94   
       
    95   $qin = ( isset($q) ) ? str_replace('"', '\"', htmlspecialchars($q)) : '';
       
    96   $search_form = '<form action="' . makeUrlNS('Special', 'Search') . '">
       
    97   <input type="text" tabindex="1" name="q" size="50" value="' . $qin . '" />&nbsp;<input tabindex="2" type="submit" value="Search" />
       
    98   ' . ( $session->auth_level > USER_LEVEL_MEMBER ? '<input type="hidden" name="auth" value="' . $session->sid_super . '" />' : '' ) . '
       
    99   </form>';
       
   100   
       
   101   if ( !empty($q) )
    89   {
   102   {
    90     list($pid, $ns) = RenderMan::strToPageID($q);
   103     $search_start = microtime_float();
    91     $pid = sanitize_page_id($pid);
   104     
    92     $key = $paths->nslist[$ns] . $pid;
   105     $results = perform_search($q, $warn, ( isset($_GET['match_case']) ));
    93     if ( isPage($key) )
   106     $warn = array_unique($warn);
    94     {
   107     
    95       redirect(makeUrl($key), 'Results', 'found page', 0);
   108     if ( file_exists( ENANO_ROOT . '/themes/' . $template->theme . '/search-result.tpl' ) )
    96     }
   109     {
    97   }
   110       $parser = $template->makeParser('search-result.tpl');
    98   
   111     }
    99   $template->header();
   112     else
   100   if(!empty($q))
   113     {
   101   {
   114       $tpl_code = <<<LONGSTRING
   102     // See if any pages directly match the title
   115       
   103     
   116       <!-- Start search result -->
   104     if ( strlen($q) >= 4 )
   117       
   105     {
   118       <div class="search-result">
   106       for ( $i = 0; $i < count ( $paths->pages ) / 2; $i++ )
   119         <p>
   107       {
   120          <h3><a href="{RESULT_URL}"><span class="search-result-annotation">{PAGE_NOTE}</span>{PAGE_TITLE}</a></h3>
   108         $pg =& $paths->pages[$i];
   121           {PAGE_TEXT}
   109         $q_lc = strtolower( str_replace(' ', '_', $q) );
   122           <span class="search-result-url">{PAGE_URL}</span> - 
   110         $q_tl = strtolower( str_replace('_', ' ', $q) );
   123           <!-- BEGINNOT special_page --><span class="search-result-info">{PAGE_LENGTH} {PAGE_LENGTH_UNIT}</span> -<!-- END special_page --> 
   111         $p_lc = strtolower($pg['urlname']);
   124           <span class="search-result-info">Relevance: {RELEVANCE_SCORE}%</span>
   112         $p_tl = strtolower($pg['name']);
   125         </p>
   113         if ( strstr($p_tl, $q_tl) || strstr($p_lc, $q_lc) && $pg['visible'] == 1 )
   126       </div>
   114         {
   127       
   115           echo '<div class="usermessage">Perhaps you were looking for <b><a href="' . makeUrl($pg['urlname'], false, true) . '">' . htmlspecialchars($pg['name']) . '</a></b>?</div>';
   128       <!-- Finish search result -->
   116           break;
   129       
   117         }
   130 LONGSTRING;
   118       }
   131       $parser = $template->makeParserText($tpl_code);
   119     }
   132     }
       
   133     foreach ( $results as $i => $_ )
       
   134     {
       
   135       $result =& $results[$i];
       
   136       $result['page_text'] = str_replace(array('<highlight>', '</highlight>'), array('<span class="highlight">', '</span>'), $result['page_text']);
       
   137       if ( !empty($result['page_text']) )
       
   138         $result['page_text'] .= '<br />';
       
   139       $result['page_name'] = str_replace(array('<highlight>', '</highlight>'), array('<span class="highlight">', '</span>'), $result['page_name']);
       
   140       if ( $result['page_length'] >= 1048576 )
       
   141       {
       
   142         $result['page_length'] = round($result['page_length'] / 1048576, 1);
       
   143         $length_unit = 'MB';
       
   144       }
       
   145       else if ( $result['page_length'] >= 1024 )
       
   146       {
       
   147         $result['page_length'] = round($result['page_length'] / 1024, 1);
       
   148         $length_unit = 'KB';
       
   149       }
       
   150       else
       
   151       {
       
   152         $length_unit = 'bytes';
       
   153       }
       
   154       $url = makeUrlComplete($result['namespace'], $result['page_id']);
       
   155       $url = preg_replace('/\?.+$/', '', $url);
       
   156       $parser->assign_vars(array(
       
   157          'PAGE_TITLE' => $result['page_name'],
       
   158          'PAGE_TEXT' => $result['page_text'],
       
   159          'PAGE_LENGTH' => $result['page_length'],
       
   160          'RELEVANCE_SCORE' => $result['score'],
       
   161          'RESULT_URL' => makeUrlNS($result['namespace'], $result['page_id'], false, true),
       
   162          'PAGE_LENGTH_UNIT' => $length_unit,
       
   163          'PAGE_URL' => $url,
       
   164          'PAGE_NOTE' => ( isset($result['page_note']) ? $result['page_note'] . ' ' : '' )
       
   165         ));
       
   166       $has_content = ( $result['namespace'] == 'Special' );
       
   167       
       
   168       $code = $plugins->setHook('search_global_results');
       
   169       foreach ( $code as $cmd )
       
   170       {
       
   171         eval($cmd);
       
   172       }
       
   173       
       
   174       $parser->assign_bool(array(
       
   175           'special_page' => $has_content
       
   176         ));
       
   177       $result = $parser->run();
       
   178     }
       
   179     unset($result);
       
   180     
       
   181     $per_page = 10;
       
   182     $start = ( isset($_GET['start']) ? intval($_GET['start']) : 0 );
       
   183     $start_string = $start + 1;
       
   184     $per_string = $start_string + $per_page - 1;
       
   185     $num_results = count($results);
       
   186     if ( $per_string > $num_results )
       
   187       $per_string = $num_results;
       
   188     
       
   189     $search_time = microtime_float() - $search_start;
       
   190     $search_time = round($search_time, 3);
       
   191     
       
   192     $q_trim = ( strlen($q) > 30 ) ? substr($q, 0, 27) . '...' : $q;
       
   193     $q_trim = htmlspecialchars($q_trim);
       
   194     
       
   195     $result_string = ( count($results) > 0 ) ? "Results <b>$start_string</b> - <b>$per_string</b> of about <b>$num_results</b> for <b>" . $q_trim . "</b> in {$search_time}s." : 'No results.';
       
   196     
       
   197     echo '<div class="search-hibar">
       
   198             <div style="float: right;">
       
   199               ' . $result_string . '
       
   200             </div>
       
   201             <b>Site search</b>
       
   202           </div>
       
   203           <div class="search-lobar">
       
   204             ' . $search_form . '
       
   205           </div>';
   120           
   206           
   121     switch(SEARCH_MODE)
   207     if ( count($warn) > 0 )
   122     {
   208     {
   123       
   209       echo '<div class="warning-box" style="margin: 10px 0 0 0;">';
   124       case "FULLTEXT":
   210       echo '<b>Some problems were encountered during your search.</b><br />
   125         if ( isset($_GET['offset']) )
   211             There was a problem with your search query, and as a result there may be a reduced number of search results.';
   126         {
   212       echo '<ul><li>' . implode('</li><li>', $warn) . '</li></ul>';
   127           $offset = intval($_GET['offset']);
   213       echo '</div>';
   128         }
   214     }
   129         else
   215   
   130         {
   216     if ( count($results) > 0 )
   131           $offset = 0;
   217     {
   132         }
   218       $html = paginate_array(
   133         $sql = $db->sql_query('SELECT search_id FROM '.table_prefix.'search_cache WHERE query=\''.$db->escape($q).'\';');
   219           $results,
   134         if(!$sql)
   220           count($results),
   135         {
   221           makeUrlNS('Special', 'Search', 'q=' . str_replace('%', '%%', htmlspecialchars(urlencode($q))) . '&start=%s'),
   136           $db->_die('Error scanning search query cache');
   222           $start,
   137         }
   223           $per_page
   138         if($db->numrows() > 0)
   224         );
   139         {
   225       echo $html;
   140           $row = $db->fetchrow();
   226     }
   141           $db->free_result();
   227     else
   142           search_fetch_fulltext_results(intval($row['search_id']), $offset);
   228     {
   143         }
   229       // No results for the search
   144         else
   230       echo '<h3 style="font-weight: normal;">Your search for <b>"' . htmlspecialchars($q) . '"</b> didn\'t turn up any results.</h3>';
   145         {
   231       echo '<p>There are a few things you can try:</p>';
   146           // Perform search
   232       echo '<ul>
   147           
   233               <li>Were you looking for a specific Special page? Special pages are not searchable. You may want to see a <a href="' . makeUrlNS('Special', 'SpecialPages') . '">list of special pages</a>.</li>
   148           $search = new MySQL_Fulltext_Search();
   234               <li>If you have the appropriate permissions, you can <a href="' . makeUrl($q) . '#do:edit">start the ' . htmlspecialchars($q) . ' page</a>.</li>
   149           
   235               <li>Try using fewer keywords. You can get broader results if you remove quotes from your search query.</li>
   150           // Parse the query
   236               <li>Did your search trigger any warnings? Sometimes a search can be cancelled if there aren\'t any terms in a search query that are 4 characters or greater in length.</li>
   151           $parse = new Searcher();
   237             </ul>';
   152           $query = $parse->parseQuery($q);
   238     }
   153           unset($parse);
       
   154           
       
   155           // Send query to MySQL
       
   156           $sql = $search->search($q);
       
   157           $results = Array();
       
   158           if ( $row = $db->fetchrow($sql) )
       
   159           {
       
   160             do {
       
   161               $results[] = $row;
       
   162             } while ( $row = $db->fetchrow($sql) );
       
   163           }
       
   164           else
       
   165           {
       
   166             // echo '<div class="warning-box">No pages that matched your search criteria could be found.</div>';
       
   167           }
       
   168           $texts = Array();
       
   169           foreach ( $results as $result )
       
   170           {
       
   171             $texts[] = render_fulltext_result($result, $query);
       
   172           }
       
   173           
       
   174           // Store the result in the search cache...if someone makes the same query later we can skip searching and rendering
       
   175           // This cache is cleared when an affected page is saved.
       
   176           
       
   177           $results = serialize($texts);
       
   178           
       
   179           $sql = $db->sql_query('INSERT INTO '.table_prefix.'search_cache(search_time,query,results) VALUES('.time().', \''.$db->escape($q).'\', \''.$db->escape($results).'\');');
       
   180           if($sql)
       
   181           {
       
   182             search_render_fulltext_results(unserialize($results), $offset, $q);
       
   183           }
       
   184           else
       
   185           {
       
   186             $db->_die('Error inserting search into cache');
       
   187           }
       
   188           
       
   189         }
       
   190         break;
       
   191 
       
   192       case "BUILTIN":
       
   193         $titles = $paths->makeTitleSearcher(isset($_GET['match_case']));
       
   194         if ( isset($_GET['offset']) )
       
   195         {
       
   196           $offset = intval($_GET['offset']);
       
   197         }
       
   198         else
       
   199         {
       
   200           $offset = 0;
       
   201         }
       
   202         $sql = $db->sql_query('SELECT search_id FROM '.table_prefix.'search_cache WHERE query=\''.$db->escape($q).'\';');
       
   203         if(!$sql)
       
   204         {
       
   205           $db->_die('Error scanning search query cache');
       
   206         }
       
   207         if($db->numrows() > 0)
       
   208         {
       
   209           $row = $db->fetchrow();
       
   210           $db->free_result();
       
   211           search_show_results(intval($row['search_id']), $offset);
       
   212         }
       
   213         else
       
   214         {
       
   215           $titles->search($q, $paths->get_page_titles());
       
   216           $search = $paths->makeSearcher(isset($_GET['match_case']));
       
   217           $texts = $paths->fetch_page_search_resource();
       
   218           $search->searchMySQL($q, $texts);
       
   219           
       
   220           $results = Array();
       
   221           $results['text'] = $search->results;
       
   222           $results['page'] = $titles->results;
       
   223           $results['warn'] = $search->warnings;
       
   224           
       
   225           $results = serialize($results);
       
   226           
       
   227           $sql = $db->sql_query('INSERT INTO '.table_prefix.'search_cache(search_time,query,results) VALUES('.time().', \''.$db->escape($q).'\', \''.$db->escape($results).'\');');
       
   228           if($sql)
       
   229           {
       
   230             search_render_results(unserialize($results), $offset, $q);
       
   231           }
       
   232           else
       
   233           {
       
   234             $db->_die('Error inserting search into cache');
       
   235           }
       
   236         }
       
   237         break;
       
   238     }
       
   239     $code = $plugins->setHook('search_results'); // , Array('query'=>$q));
       
   240     foreach ( $code as $cmd )
       
   241     {
       
   242       eval($cmd);
       
   243     }
       
   244     ?>
       
   245     <form action="<?php echo makeUrl($paths->page); ?>" method="get">
       
   246       <p>
       
   247         <?php if ( $session->sid_super ): ?>
       
   248           <input type="hidden" name="auth" value="<?php echo $session->sid_super; ?>" />
       
   249         <?php endif; ?>
       
   250         <?php if ( urlSeparator == '&' ): ?>
       
   251           <input type="hidden" name="title" value="<?php echo $paths->nslist['Special'] . 'Search'; ?>" />
       
   252         <?php endif; ?>
       
   253         <input type="text" name="q" size="40" value="<?php echo htmlspecialchars( $q ); ?>" /> <input type="submit" value="Go" style="font-weight: bold;" /> <input name="search" type="submit" value="Search" />  <small><a href="<?php echo makeUrlNS('Special', 'Search'); ?>">Advanced Search</a></small>
       
   254       </p>
       
   255     </form>
       
   256     <?php
       
   257   }
   239   }
   258   else
   240   else
   259   {
   241   {
   260   ?>
   242     ?>
   261     <br />
       
   262     <form action="<?php echo makeUrl($paths->page); ?>" method="get">
   243     <form action="<?php echo makeUrl($paths->page); ?>" method="get">
   263       <?php if ( urlSeparator == '&' ): ?>
   244       <?php if ( urlSeparator == '&' ): ?>
   264         <input type="hidden" name="title" value="<?php echo $paths->nslist['Special'] . 'Search'; ?>" />
   245         <input type="hidden" name="title" value="<?php echo $paths->nslist['Special'] . 'Search'; ?>" />
   265       <?php endif; ?>
   246       <?php 
       
   247       echo ( $session->auth_level > USER_LEVEL_MEMBER ? '<input type="hidden" name="auth" value="' . $session->sid_super . '" />' : '' );
       
   248       endif; ?>
   266       <div class="tblholder">
   249       <div class="tblholder">
   267         <table border="0" style="width: 100%;" cellspacing="1" cellpadding="4">
   250         <table border="0" style="width: 100%;" cellspacing="1" cellpadding="4">
   268           <tr><th colspan="2">Advanced Search</th></tr>
   251           <tr><th colspan="2">Advanced Search</th></tr>
   269           <tr>
   252           <tr>
   270             <td class="row1">Search for pages with <b>any of these words</b>:</td>
   253             <td class="row1">Search for pages with <b>any of these words</b>:</td>
   296             </td>
   279             </td>
   297           </tr>
   280           </tr>
   298         </table>
   281         </table>
   299       </div>
   282       </div>
   300     </form>
   283     </form>
   301   <?php
   284     <?php
   302   }
   285   }
       
   286   
   303   $template->footer();
   287   $template->footer();
   304 }
   288 }
   305 
   289 
   306 function search_show_results($search_id, $start = 0)
       
   307 {
       
   308   global $db, $session, $paths, $template, $plugins; // Common objects
       
   309   $q = $db->sql_query('SELECT query,results,search_time FROM '.table_prefix.'search_cache WHERE search_id='.intval($search_id).';');
       
   310   if(!$q)
       
   311     return $db->get_error('Error selecting cached search results');
       
   312   $row = $db->fetchrow();
       
   313   $db->free_result();
       
   314   $results = unserialize($row['results']);
       
   315   search_render_results($results, $start, $row['query']);
       
   316 }
       
   317 
       
   318 function search_render_results($results, $start = 0, $q = '')
       
   319 {
       
   320   global $db, $session, $paths, $template, $plugins; // Common objects
       
   321   $nr1 = sizeof($results['page']);
       
   322   $nr2 = sizeof($results['text']);
       
   323   $nr  = ( $nr1 > $nr2 ) ? $nr1 : $nr2;
       
   324   $results['page'] = array_slice($results['page'], $start, SEARCH_RESULTS_PER_PAGE);
       
   325   $results['text'] = array_slice($results['text'], $start, SEARCH_RESULTS_PER_PAGE);
       
   326   
       
   327   // Pagination
       
   328   $pagination = '';
       
   329   if ( $nr1 > SEARCH_RESULTS_PER_PAGE || $nr2 > SEARCH_RESULTS_PER_PAGE )
       
   330   {
       
   331     $pagination .= '<div class="tblholder" style="padding: 0; display: table; margin: 0 0 0 auto; float: right;">
       
   332           <table border="0" style="width: 100%;" cellspacing="1" cellpadding="4">
       
   333           <tr>
       
   334           <th>Page:</th>';
       
   335     $num_pages = ceil($nr / SEARCH_RESULTS_PER_PAGE);
       
   336     $j = 0;
       
   337     for ( $i = 1; $i <= $num_pages; $i++ ) 
       
   338     {
       
   339       if ($j == $start)
       
   340         $pagination .= '<td class="row1"><b>' . $i . '</b></td>';
       
   341       else
       
   342         $pagination .= '<td class="row1"><a href="' . makeUrlNS('Special', 'Search', 'q=' . urlencode($q) . '&offset=' . $j, true) . '">' . $i . '</a></td>';
       
   343       $j = $j + SEARCH_RESULTS_PER_PAGE;
       
   344     }
       
   345     $pagination .= '</tr></table></div>';
       
   346   }
       
   347   
       
   348   echo $pagination;
       
   349   
       
   350   if ( $nr1 >= $start )
       
   351   {
       
   352     echo '<h3>Page title matches</h3>';
       
   353     if(count($results['page']) < 1)
       
   354     {
       
   355       echo '<div class="error-box">No pages with a title that matched your search criteria could be found.</div>';
       
   356     }
       
   357     else
       
   358     {
       
   359       echo '<p>';
       
   360       foreach($results['page'] as $page => $text)
       
   361       {
       
   362         echo '<a href="'.makeUrl($page).'">'.$paths->pages[$page]['name'].'</a><br />';
       
   363       }
       
   364       echo '</p>';
       
   365     }
       
   366   }
       
   367   if ( $nr2 >= $start )
       
   368   {
       
   369     echo '<h3>Page text matches</h3>';
       
   370     if(count($results['text']) < 1)
       
   371     {
       
   372       echo '<div class="error-box">No page text that matched your search criteria could be found.</div>';
       
   373     }
       
   374     else
       
   375     {
       
   376       foreach($results['text'] as $kpage => $text)
       
   377       {
       
   378         preg_match('#^ns=('.implode('|', array_keys($paths->nslist)).');pid=(.*?)$#i', $kpage, $matches);
       
   379         $page = $paths->nslist[$matches[1]] . $matches[2];
       
   380         echo '<p><span style="font-size: larger;"><a href="'.makeUrl($page).'">'.$paths->pages[$page]['name'].'</a></span><br />'.$text.'</p>';
       
   381       }
       
   382     }
       
   383   }
       
   384   if(count($results['warn']) > 0)
       
   385     echo '<div class="warning-box"><b>Your search may not include all results.</b><br />The following errors were encountered during the search:<br /><ul><li>'.implode('</li><li>', $results['warn']).'</li></ul></div>';
       
   386   echo $pagination;
       
   387 }
       
   388 
       
   389 function render_fulltext_result($result, $query)
       
   390 {
       
   391   global $db, $session, $paths, $template, $plugins; // Common objects
       
   392   preg_match('#^ns=('.implode('|', array_keys($paths->nslist)).');pid=(.*?)$#i', $result['page_identifier'], $matches);
       
   393   $page = $paths->nslist[$matches[1]] . $matches[2];
       
   394   //$score = round($result['score'] * 100, 1);
       
   395   $score = number_format($result['score'], 2);
       
   396   $char_length = $result['length'];
       
   397   $result_template = <<<TPLCODE
       
   398   <div class="search-result">
       
   399     <h3><a href="{HREF}">{TITLE}</a></h3>
       
   400     <p>{TEXT}</p>
       
   401     <p>
       
   402       <span class="search-result-info">{NAMESPACE} - Relevance score: {SCORE} ({LENGTH} bytes)</span>
       
   403     </p>
       
   404   </div>
       
   405 TPLCODE;
       
   406   $parser = $template->makeParserText($result_template);
       
   407   
       
   408   $pt =& $result['page_text'];
       
   409   $space_chars = Array("\t", "\n", "\r", " ");
       
   410   
       
   411   $words = array_merge($query['any'], $query['req']);
       
   412   $pt = htmlspecialchars($pt);
       
   413   $words2 = array();
       
   414   
       
   415   for ( $i = 0; $i < sizeof($words); $i++)
       
   416   {
       
   417     if(!empty($words[$i]))
       
   418       $words2[] = preg_quote($words[$i]);
       
   419   }
       
   420   
       
   421   $regex = '/(' . implode('|', $words2) . ')/i';
       
   422   $pt = preg_replace($regex, '<span class="search-term">\\1</span>', $pt);
       
   423   
       
   424   $title = preg_replace($regex, '<span class="title-search-term">\\1</span>', htmlspecialchars($paths->pages[$page]['name']));
       
   425   
       
   426   $cut_off = false;
       
   427   
       
   428   foreach ( $words as $word )
       
   429   {
       
   430     // Boldface searched words
       
   431     $ptlen = strlen($pt);
       
   432     for ( $i = 0; $i < $ptlen; $i++ )
       
   433     {
       
   434       $len = strlen($word);
       
   435       if ( strtolower(substr($pt, $i, $len)) == strtolower($word) )
       
   436       {
       
   437         $chunk1 = substr($pt, 0, $i);
       
   438         $chunk2 = substr($pt, $i, $len);
       
   439         $chunk3 = substr($pt, ( $i + $len ));
       
   440         $pt = $chunk1 . $chunk2 . $chunk3;
       
   441         $ptlen = strlen($pt);
       
   442         // Cut off text to 150 chars or so
       
   443         if ( !$cut_off )
       
   444         {
       
   445           $cut_off = true;
       
   446           if ( $i - 75 > 0 )
       
   447           {
       
   448             // Navigate backwards until a space character is found
       
   449             $chunk = substr($pt, 0, ( $i - 75 ));
       
   450             $final_chunk = $chunk;
       
   451             for ( $j = strlen($chunk); $j > 0; $j = $j - 1 )
       
   452             {
       
   453               if ( in_array($chunk{$j}, $space_chars) )
       
   454               {
       
   455                 $final_chunk = substr($chunk, $j + 1);
       
   456                 break;
       
   457               }
       
   458             }
       
   459             $mid_chunk = substr($pt, ( $i - 75 ), 75);
       
   460             
       
   461             $clipped = '...' . $final_chunk . $mid_chunk . $chunk2;
       
   462             
       
   463             $chunk = substr($pt, ( $i + strlen($chunk2) + 75 ));
       
   464             $final_chunk = $chunk;
       
   465             for ( $j = 0; $j < strlen($chunk); $j++ )
       
   466             {
       
   467               if ( in_array($chunk{$j}, $space_chars) )
       
   468               {
       
   469                 $final_chunk = substr($chunk, 0, $j);
       
   470                 break;
       
   471               }
       
   472             }
       
   473             
       
   474             $end_chunk = substr($pt, ( $i + strlen($chunk2) ), 75 );
       
   475             
       
   476             $clipped .= $end_chunk . $final_chunk . '...';
       
   477             
       
   478             $pt = $clipped;
       
   479           }
       
   480           else if ( strlen($pt) > 200 )
       
   481           {
       
   482             $mid_chunk = substr($pt, ( $i - 75 ), 75);
       
   483             
       
   484             $clipped = $chunk1 . $chunk2;
       
   485             
       
   486             $chunk = substr($pt, ( $i + strlen($chunk2) + 75 ));
       
   487             $final_chunk = $chunk;
       
   488             for ( $j = 0; $j < strlen($chunk); $j++ )
       
   489             {
       
   490               if ( in_array($chunk{$j}, $space_chars) )
       
   491               {
       
   492                 $final_chunk = substr($chunk, 0, $j);
       
   493                 break;
       
   494               }
       
   495             }
       
   496             
       
   497             $end_chunk = substr($pt, ( $i + strlen($chunk2) ), 75 );
       
   498             
       
   499             $clipped .= $end_chunk . $final_chunk . '...';
       
   500             
       
   501             $pt = $clipped;
       
   502             
       
   503           }
       
   504           break 2;
       
   505         }
       
   506       }
       
   507     }
       
   508     $cut_off = false;
       
   509   }
       
   510   
       
   511   $parser->assign_vars(Array(
       
   512       'TITLE' => $title,
       
   513       'TEXT' => $pt,
       
   514       'NAMESPACE' => $matches[1],
       
   515       'SCORE' => $score,
       
   516       'LENGTH' => $char_length,
       
   517       'HREF' => makeUrl($page)
       
   518     ));
       
   519   
       
   520   return $parser->run();
       
   521   
       
   522 }
       
   523 
       
   524 function search_fetch_fulltext_results($search_id, $offset = 0)
       
   525 {
       
   526   global $db, $session, $paths, $template, $plugins; // Common objects
       
   527   $q = $db->sql_query('SELECT query,results,search_time FROM '.table_prefix.'search_cache WHERE search_id='.intval($search_id).';');
       
   528   if(!$q)
       
   529     return $db->get_error('Error selecting cached search results');
       
   530   $row = $db->fetchrow();
       
   531   $db->free_result();
       
   532   $results = unserialize($row['results']);
       
   533   search_render_fulltext_results($results, $offset, $row['query']);
       
   534 }
       
   535 
       
   536 function search_render_fulltext_results($results, $offset = 0, $query)
       
   537 {
       
   538   $num_results = sizeof($results);
       
   539   $slice = array_slice($results, $offset, SEARCH_RESULTS_PER_PAGE);
       
   540   
       
   541   if ( $num_results < 1 )
       
   542   {
       
   543     echo '<div class="warning-box" style="margin-left: 0;">No page text that matched your search criteria could be found.</div>';
       
   544     return null;
       
   545   }
       
   546   
       
   547   $html = paginate_array($results, sizeof($results), makeUrlNS('Special', 'Search', 'q=' . urlencode($query) . '&offset=%s'), $offset, 10);
       
   548   echo $html . '<br />';
       
   549   
       
   550 }
       
   551 
       
   552 ?>
   290 ?>