xref: /plugin/sphinxsearch-was/SphinxSearch.php (revision 70:5ac71b5ddd70)
1<?php
2/*
3 * To change this template, choose Tools | Templates
4 * and open the template in the editor.
5 */
6
7class SphinxSearch
8{
9    private $_sphinx = null;
10    private $_result = array();
11    private $_index = null;
12    private $_query = '';
13
14    private $_snippetSize = 256;
15    private $_aroundKeyword = 5;
16    private $_resultsPerPage = 10;
17
18    private $_titlePriority = 20;
19    private $_bodyPriority = 5;
20    private $_categoriesPriority = 10;
21
22    public function  __construct($host, $port, $index)
23    {
24        $this->_sphinx = new SphinxClient();
25        $this->_sphinx->SetServer($host, $port);
26        $this->_sphinx->SetMatchMode(SPH_MATCH_EXTENDED2);
27
28        $this->_index = $index;
29    }
30
31    public function setSearchAllQuery($keywords, $categories)
32    {
33        $starKeyword = $this->starQuery($keywords);
34        $this->_query = "(@categories $starKeyword) | (@(body,title) {$keywords})";
35    }
36
37    public function setSearchAllQueryWithCategoryFilter($keywords, $categories)
38    {
39        $starKeyword = $this->starQuery($keywords);
40        if(strpos($categories, "-") === 0){
41            $categories = '-"'.substr($categories, 1).'"';
42        }
43        $this->_query = "(@categories {$categories}) & ((@(body,title) {$keywords}) | (@categories {$starKeyword}))";
44    }
45
46    public function setSearchCategoryQuery($keywords, $categories)
47    {
48        $starKeyword = $this->starQuery($keywords);
49        $this->_query = "@categories {$categories} $starKeyword";
50    }
51
52    public function search($start, $resultsPerPage = 10)
53    {
54        $this->_resultsPerPage = $resultsPerPage;
55
56        $this->_sphinx->SetFieldWeights(array('categories' => $this->_categoriesPriority, 'title' => $this->_titlePriority, 'body' => $this->_bodyPriority));
57
58        $this->_sphinx->SetLimits($start, $resultsPerPage+100);
59
60        $res = $this->_sphinx->Query($this->_query, $this->_index);
61        $this->_result = $res;
62
63        if (empty($res['matches'])) {
64            return false;
65	}
66        return true;
67    }
68
69    public function getPages()
70    {
71        $pagesIdsAll = $this->getPagesIds();
72        $this->_offset = 0;
73        $counter = 0;
74        $tmpRes = array();
75        $pagesIds = array();
76        foreach($pagesIdsAll as $id => $pageData){
77            $this->_offset++;
78            if(auth_quickaclcheck($pageData['page']) >= AUTH_READ){
79                if(!isset($tmpRes[$pageData['page']])){
80                    $tmpRes[$pageData['page']] = 1;
81                    $counter++;
82                }
83                $pagesIds[$id] = $pageData;
84                if ($counter == $this->_resultsPerPage){
85                    break;
86                }
87            }
88        }
89        if (empty($pagesIds)){
90            return false;
91        }
92
93        $pagesList = array();
94        $body = array();
95        $titleText = array();
96        $category = array();
97        foreach ($pagesIds as $crc => $data){
98            if (!empty($data['hid'])){
99                $bodyHtml = p_render('xhtml',p_get_instructions(getSectionByTitleLevel($data['page'], $data['title'], true)),$info);
100            } else {
101                $bodyHtml = p_wiki_xhtml($data['page']);
102            }
103            $bodyHtml = preg_replace("#[\s]+?</li>#", "</li>;", $bodyHtml);
104            $bodyHtml = htmlspecialchars_decode($bodyHtml);
105            $body[$crc] = strip_tags($bodyHtml);
106            $titleText[$crc] = strip_tags($data['title_text']);
107            $category[$crc] = $data['page'];
108        }
109
110        $starQuery = $this->starQuery($keywords);
111        $bodyExcerpt = $this->getExcerpt($body, $starQuery);
112        $titleTextExcerpt = $this->getExcerpt($titleText, $starQuery);
113        $i = 0;
114        $results = array();
115        foreach($body as $crc => $notused){
116            $results[$crc] = array(
117                'page' => $pagesIds[$crc]['page'],
118                'bodyExcerpt' => $bodyExcerpt[$i],
119                'titleTextExcerpt' => $titleTextExcerpt[$i],
120                'hid' => $pagesIds[$crc]['hid'],
121                'title' => $pagesIds[$crc]['title'],
122                'title_text' => $pagesIds[$crc]['title_text']
123            );
124            $i++;
125        }
126        return $results;
127    }
128
129    public function getPagesIds()
130    {
131        $pageMapper = new PageMapper();
132
133        return $pageMapper->getByCrc(array_keys($this->_result['matches']));
134    }
135
136    public function getOffset()
137    {
138        return $this->_offset;
139    }
140
141    public function getError()
142    {
143        return $this->_sphinx->GetLastError();
144    }
145
146    public function getTotalFound()
147    {
148        return !empty($this->_result['total_found'])?$this->_result['total_found'] : 0;
149    }
150
151    public function getExcerpt($data, $query)
152    {
153        return $this->_sphinx->BuildExcerpts($data, $this->_index, $query,
154                    array(
155                        'limit' => $this->_snippetSize,
156                        'around' => $this->_aroundKeyword,
157                        'weight_order' => 1,
158                        'sp' => 1
159                    )
160                );
161    }
162
163    public function starQuery($query)
164    {
165        $query = $this->removeStars($query);
166        $words = explode(" ", $query);
167        foreach($words as $id => $word){
168            $words[$id] = "*".$word."*";
169        }
170        return implode(" ", $words);
171    }
172
173    public function removeStars($query)
174    {
175        $words = explode(" ", $query);
176        foreach($words as $id => $word){
177            $words[$id] = trim($word, "*");
178        }
179        return implode(" ", $words);
180    }
181
182    public function getQuery()
183    {
184        return $this->_query;
185    }
186
187    public function setSnippetSize($symbols = 256)
188    {
189        $this->_snippetSize = $symbols;
190    }
191
192    public function setArroundWordsCount($words = 5)
193    {
194        $this->_aroundKeyword = $words;
195    }
196
197    public function setTitlePriority($priority)
198    {
199        $this->_titlePriority = $priority;
200    }
201
202    public function setBodyPriority($priority)
203    {
204        $this->_bodyPriority = $priority;
205    }
206
207    public function setCategoriesPriority($priority)
208    {
209        $this->_categoriesPriority = $priority;
210    }
211}
212