<?php

/**
 * This file copyright (C) 2010 Barry Hunter (sphinx@barryhunter.co.uk)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

# Version 0.1 - First release (very basic and not fully functional)
# Version 0.2 - Made the Configuration section usuable
# Version 0.3 - (withdrawn - had broken implementation)
# Version 0.4 - Added support for highlighted excerpts/snippets body in the results

# For more examples see: http://www.nearby.org.uk/sphinx/search-example.php
# (for example paging, facetting etc) 

######################
# Change this settings to match your setup...

$CONF = array();

$CONF['sphinx_host'] = 'localhost';
$CONF['sphinx_port'] = 9312//this demo uses the SphinxAPI interface

$CONF['mysql_host'] = "localhost";
$CONF['mysql_username'] = "user";
$CONF['mysql_password'] = "password";
$CONF['mysql_database'] = "data";

$CONF['sphinx_index'] = "yourindex"// can also be a list of indexes, "main, delta"

#can use 'excerpt' to highlight using the query, or 'asis' to show description as is.
$CONF['body'] = 'excerpt';

#the link for the title (only $id) placeholder supported
$CONF['link_format'] = '/page.php?page_id=$id';

#Change this to FALSE on a live site!
$CONF['debug'] = TRUE;

######################
#mysql query to fetch results, needs `id`, `title` and `body` columns in the final result.
#$ids is replaced by the list of ids
#this query can be as arbitary complex as required - but mysql has be able to run it quickly
#don't include a order by (but if use GROUP BY, put ORDER BY NULL)
#TIP can also do :: CONCAT(description,' Category:',category) AS body :: for exmaple

$CONF['mysql_query'] = '
SELECT page_id AS id, title AS title, description AS body
FROM your_table
WHERE page_id IN ($ids)
'
;

#might need to put in path to your file
if (!empty($_GET['q'])) require("sphinxapi.php");

######################
# change the look and feel

?>
<style type="text/css">
form#search {
    background-color:silver:
    padding:10px;
}
ul.results {
    border:1px solid silver;
}
.results li {
    font-size:0.9em;
}
.results li a {
    font-weight:bold;
    font-size:1.2em;
}
</style>
<?php

##################################################################
##################################################################
#
# Nothing below should need changing
#  but of course this is only a basic demo, can customise it to your needs
#

$q = isset($_GET['q'])?$_GET['q']:'';

$q preg_replace('/ OR /',' | ',$q);

$q preg_replace('/[^\w~\|\(\)\^\$\?"\/=-]+/',' ',trim(strtolower($q)));

?>
    <form action="?" method="get" id="search">
        Search: <input name="q" type="text" value="<? echo htmlentities($q); ?>"/>
        <input type="submit" value="Search"/>
    </form>
<?php

if (!empty($q)) {
    
$qo $q;
    if (
strlen($qo) > 64) {
        
$qo '--complex query--';
    }
    
    if (
1) {
        
$mode SPH_MATCH_ALL;
        if (
strpos($q,'~') === 0) {
            
$q preg_replace('/^\~/','',$q);
            if (
substr_count($q,' ') > 1//over 2 words
                
$mode SPH_MATCH_ANY;
        } elseif (
preg_match('/[\|\(\)\^\$\?"\/=-]/',$q)) {
            
$mode SPH_MATCH_EXTENDED;
        }
        
        
$cl = new SphinxClient();
        
$cl->SetServer($CONF['sphinx_host'], $CONF['sphinx_port']);
        
$cl->SetSortMode(SPH_SORT_EXTENDED"@relevance DESC, @id DESC");
        
$cl->SetMatchMode($mode);
        
$cl->SetLimits(0,25); //humber of results
        
        
$res $cl->Query($q$CONF['sphinx_index']);
        
        
// --------------
        
        
if (empty($res)) {
            print 
"Query failed: -- please try again later.\n";
            if (
$CONF['debug'] && $cl->GetLastError())
                print 
"<br/>Error: ".$cl->GetLastError()."\n\n";
            return;
        } else {
            if (
$CONF['debug'] && $cl->GetLastWarning())
                print 
"<br/>WARNING: ".$cl->GetLastWarning()."\n\n";
            
$query_info "Query '".htmlentities($qo)."' retrieved ".count($res['matches'])." of $res[total_found] matches in $res[time] sec.\n";
        }
        
        if (
is_array($res["matches"])) {
            
$ids array_keys($res["matches"]);
        } else {
            print 
"<pre class=\"results\">No Results for '".htmlentities($qo)."'</pre>";
        }
    }
    
    if (!empty(
$ids)) {
        
$db mysql_connect($CONF['mysql_host'],$CONF['mysql_username'],$CONF['mysql_password']) or die("ERROR: unable to connect to database");
        
mysql_select_db($CONF['mysql_database'], $db) or die("ERROR: unable to select database");
        
        
$sql str_replace('$ids',implode(',',$ids),$CONF['mysql_query']);
        
$result mysql_query($sql) or die($CONF['debug']?("ERROR: mysql query failed: ".mysql_error()):"ERROR: Please try later");
        
        if (
mysql_num_rows($result) > 0) {
            
$rows = array();
            while (
$row mysql_fetch_array($result,MYSQL_ASSOC)) {
                
$rows[$row['id']] = $row;
            }
            if (
$CONF['body'] == 'excerpt') {
                
$docs = array();
                foreach (
$ids as $c => $id) {
                    
$docs[$c] = strip_tags($rows[$id]['body']);
                }
                
$reply $cl->BuildExcerpts($docs$CONF['sphinx_index'], $q);
            }
            
            print 
"<ol class=\"results\">";
            foreach (
$ids as $c => $id) {
                
$row $rows[$id];
                
                
$link htmlentities(str_replace('$id',$row['id'],$CONF['link_format']));
                print 
"<li><a href=\"$link\">".htmlentities($row['title'])."</a><br/>";
                
                if (
$CONF['body'] == 'excerpt' && !empty($reply[$c]))
                    print 
htmlentities($reply[$c])."</li>";
                else
                    print 
htmlentities($row['body'])."</li>";
            }
            print 
"</ol><pre class=\"results\">$query_info</pre>";
        } else {
            print 
"<pre class=\"results\">Unable to get results at this time, please try later</pre>";
        }
    }
}