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 17 private $_titlePriority = 20; 18 private $_bodyPriority = 5; 19 private $_categoriesPriority = 10; 20 21 public function __construct($host, $port, $index) 22 { 23 $this->_sphinx = new SphinxClient(); 24 $this->_sphinx->SetServer($host, $port); 25 $this->_sphinx->SetMatchMode(SPH_MATCH_EXTENDED2); 26 27 $this->_index = $index; 28 } 29 30 public function search($keywords, $categories, $start, $resultsPerPage = 10) 31 { 32 $this->_sphinx->SetFieldWeights(array('categories' => $this->_categoriesPriority, 'title' => $this->_titlePriority, 'body' => $this->_bodyPriority)); 33 34 $this->_sphinx->SetLimits($start, $resultsPerPage+100); 35 $query = ''; 36 if (!empty($keywords) && empty($categories)){ 37 $starCategory = $this->starQuery($keywords); 38 $query = "@(body,title) {$keywords} | @categories {$starCategory}"; 39 } else { 40 $starCategory = $this->starQuery($categories); 41 $query = "@(body,title,categories) {$keywords} @categories ".$starCategory; 42 } 43 $this->_query = $query; 44 $res = $this->_sphinx->Query($query, $this->_index); 45 $this->_result = $res; 46 47 if (empty($res['matches'])) { 48 return false; 49 } 50 51 $pageMapper = new PageMapper(); 52 53 $pagesIdsAll = $pageMapper->getByCrc(array_keys($res['matches'])); 54 $this->_offset = 0; 55 $counter = 0; 56 foreach($pagesIdsAll as $id => $pageData){ 57 $this->_offset++; 58 if(auth_quickaclcheck($pageData['page']) >= AUTH_READ){ 59 $counter++; 60 $pagesIds[$id] = $pageData; 61 if ($counter == $resultsPerPage){ 62 break; 63 } 64 } 65 } 66 if (empty($pagesIds)){ 67 return false; 68 } 69 70 $pagesList = array(); 71 $body = array(); 72 $titleText = array(); 73 $category = array(); 74 foreach ($pagesIds as $crc => $data){ 75 if (!empty($data['hid'])){ 76 $bodyHtml = p_render('xhtml',p_get_instructions(getSectionByTitleLevel($data['page'], $data['title'], true)),$info); 77 } else { 78 $bodyHtml = p_wiki_xhtml($data['page']); 79 } 80 $body[$crc] = strip_tags($bodyHtml); 81 $titleText[$crc] = strip_tags($data['title_text']); 82 $category[$crc] = $data['page']; 83 } 84 85 $starQuery = $this->starQuery($keywords); 86 $bodyExcerpt = $this->getExcerpt($body, $starQuery); 87 $titleTextExcerpt = $this->getExcerpt($titleText, $starQuery); 88 $i = 0; 89 $results = array(); 90 foreach($body as $crc => $notused){ 91 $results[$crc] = array( 92 'page' => $pagesIds[$crc]['page'], 93 'bodyExcerpt' => $bodyExcerpt[$i], 94 'titleTextExcerpt' => $titleTextExcerpt[$i], 95 'hid' => $pagesIds[$crc]['hid'], 96 'title' => $pagesIds[$crc]['title'], 97 'title_text' => $pagesIds[$crc]['title_text'] 98 ); 99 $i++; 100 } 101 return $results; 102 } 103 104 public function getOffset() 105 { 106 return $this->_offset; 107 } 108 109 public function getError() 110 { 111 return $this->_sphinx->GetLastError(); 112 } 113 114 public function getTotalFound() 115 { 116 return !empty($this->_result['total_found'])?$this->_result['total_found'] : 0; 117 } 118 119 public function getExcerpt($data, $query) 120 { 121 return $this->_sphinx->BuildExcerpts($data, $this->_index, $query, 122 array( 123 'limit' => $this->_snippetSize, 124 'around' => $this->_aroundKeyword, 125 'weight_order' => 1, 126 'sp' => 1 127 ) 128 ); 129 } 130 131 public function starQuery($query) 132 { 133 $words = explode(" ", $query); 134 $starQuery = ''; 135 foreach($words as $word){ 136 $starQuery .= "*".$word."* "; 137 } 138 return $starQuery; 139 } 140 141 public function getQuery() 142 { 143 return $this->_query; 144 } 145 146 public function setSnippetSize($symbols = 256) 147 { 148 $this->_snippetSize = $symbols; 149 } 150 151 public function setArroundWordsCount($words = 5) 152 { 153 $this->_aroundKeyword = $words; 154 } 155 156 public function setTitlePriority($priority) 157 { 158 $this->_titlePriority = $priority; 159 } 160 161 public function setBodyPriority($priority) 162 { 163 $this->_bodyPriority = $priority; 164 } 165 166 public function setCategoriesPriority($priority) 167 { 168 $this->_categoriesPriority = $priority; 169 } 170} 171