api.sphinxsearch.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. <?php
  2. /**
  3. * Sphinx database abstraction layer
  4. */
  5. class SphinxDB {
  6. /**
  7. * Placeholder for db link
  8. *
  9. * @var object
  10. */
  11. protected $db = '';
  12. /**
  13. * Contains name of db driver is correct extension exists
  14. *
  15. * @var string
  16. */
  17. protected $dbDriver = 'none';
  18. /**
  19. * Contains global configuration
  20. *
  21. * @var array
  22. */
  23. protected $altCfg = array();
  24. /**
  25. * Contains list of indexes to search in
  26. *
  27. * @var string
  28. */
  29. protected $searchIndexes = 'ip,mac,realname,login,fulladdress,mobile,phone';
  30. /**
  31. * Contains additional sorting parameters
  32. *
  33. * @var string
  34. */
  35. protected $queryOptions = ' ';
  36. /**
  37. * Limit number of search results
  38. */
  39. const SEARCHLIMIT = 100;
  40. public function __construct() {
  41. $this->LoadAlter();
  42. $this->dbConnect();
  43. }
  44. /**
  45. * load alter.ini config
  46. *
  47. * @return void
  48. */
  49. protected function LoadAlter() {
  50. global $ubillingConfig;
  51. $this->altCfg = $ubillingConfig->getAlter();
  52. }
  53. /**
  54. * Connect to Sphinx DB if possible and needed extenstions are loaded
  55. *
  56. * @return boolean or object
  57. */
  58. protected function dbConnect() {
  59. $params = array(
  60. 'SPHINX_SEARCH_HOST',
  61. 'SPHINX_SEARCH_SQL_PORT',
  62. 'SPHINX_SEARCH_USER',
  63. 'SPHINX_SEARCH_PASSWORD',
  64. 'SPHINX_SEARCH_DB'
  65. );
  66. foreach ($params as $param) {
  67. if (!isset($this->altCfg[$param])) {
  68. return false;
  69. }
  70. }
  71. $host = $this->altCfg['SPHINX_SEARCH_HOST'];
  72. $port = $this->altCfg['SPHINX_SEARCH_SQL_PORT'];
  73. $user = $this->altCfg['SPHINX_SEARCH_USER'];
  74. $password = $this->altCfg['SPHINX_SEARCH_PASSWORD'];
  75. $db = $this->altCfg['SPHINX_SEARCH_DB'];
  76. if (!extension_loaded('mysql')) {
  77. $this->db = new mysqli($host, $user, $password, $db, $port);
  78. if ($this->db->connect_error) {
  79. die('Connection error (' . $this->db->connect_errno . ') ' . $this->db->connect_error);
  80. }
  81. $this->dbDriver = 'mysqli';
  82. return true;
  83. } else {
  84. $this->db = mysql_connect($host . ':' . $port, $user, $password);
  85. if (empty($this->db)) {
  86. die('Unable to connect to database server!');
  87. }
  88. $this->dbDriver = 'legacy';
  89. return true;
  90. }
  91. }
  92. /**
  93. * Query search in our fulltextsearch engine
  94. *
  95. * @param string $searchString
  96. * @return json array
  97. */
  98. public function searchQuery($searchString) {
  99. $search = array();
  100. if (isset($this->altCfg['SPHINX_SEARCH_INDEXES'])) {
  101. $this->searchIndexes = $this->altCfg['SPHINX_SEARCH_INDEXES'];
  102. }
  103. if (isset($this->altCfg['SPHINX_SEARCH_SORT'])) {
  104. $this->queryOptions .= $this->altCfg['SPHINX_SEARCH_SORT'];
  105. }
  106. if (isset($this->altCfg['SPHINX_SEARCH_LIMIT'])) {
  107. $this->queryOptions .= ' LIMIT ' . $this->altCfg['SPHINX_SEARCH_LIMIT'];
  108. } else {
  109. $this->queryOptions .= ' LIMIT ' . self::SEARCHLIMIT;
  110. }
  111. if (!empty($searchString)) {
  112. if ($this->dbDriver == 'none') {
  113. return $search;
  114. }
  115. $query = "SELECT * FROM " . $this->searchIndexes . " WHERE MATCH ('" . $searchString . "') " . $this->queryOptions;
  116. if ($this->dbDriver == 'mysqli') {
  117. if ($result = $this->db->query($query, MYSQLI_USE_RESULT)) {
  118. while ($row = $result->fetch_assoc()) {
  119. $search[] = $row;
  120. }
  121. }
  122. }
  123. if ($this->dbDriver == 'legacy') {
  124. $queried = mysql_query($query, $this->db);
  125. while ($row = mysql_fetch_assoc($queried)) {
  126. $search[] = $row;
  127. }
  128. }
  129. $search = json_encode($search);
  130. return $search;
  131. }
  132. }
  133. }
  134. /**
  135. * Sphinx user-search implementation
  136. */
  137. class SphinxSearch {
  138. /**
  139. * Placeholder for Sphinx DB connection
  140. *
  141. * @var object
  142. */
  143. protected $db = '';
  144. public function __construct($searchString = '') {
  145. $this->db = new SphinxDB;
  146. if (!empty($searchString)) {
  147. $this->returnSearchResult($searchString);
  148. }
  149. }
  150. /**
  151. * Escape unwanted characters
  152. *
  153. * @param string $string
  154. * @return string
  155. */
  156. protected function escapeString($string) {
  157. $from = array('\\', '(', ')', '|', '-', '!', '@', '~', '"', '&', '/', '^', '$', '=', '<');
  158. $to = array('\\\\', '\\\(', '\\\)', '\\\|', '\\\-', '\\\!', '\\\@', '\\\~', '\\\"', '\\\&', '\\\/', '\\\^', '\\\$', '\\\=', '\\\<');
  159. return str_replace($from, $to, $string);
  160. }
  161. /**
  162. * Send our string info search query and return json result.
  163. *
  164. * @param string $searchString
  165. * @return json array
  166. */
  167. protected function returnSearchResult($searchString) {
  168. $escapedSearchString = $this->escapeString($searchString);
  169. die($this->db->searchQuery($escapedSearchString));
  170. }
  171. }