1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
|
<?php
/**
* GForge Search Engine
*
* Portions Copyright 1999-2001 (c) VA Linux Systems
* The rest Copyright 2004 (c) Guillaume Smet / Open Wide
*
* http://gforge.org
*
* @version $Id: SearchQuery.class 5270 2006-02-05 17:12:19Z tperdue $
*/
class SearchQuery extends Error {
/**
* the operator between each part of the query. Can be AND or OR.
*
* @var string $operator
*/
var $operator;
/**
* Number of rows per page
*
* @var int $rowsPerPage
*/
var $rowsPerPage;
/**
* Number of rows we will display on the page
*
* @var int $rowsCount
*/
var $rowsCount = 0;
/**
* Number of rows returned by the query
*
* @var int $rowsTotalCount
*/
var $rowsTotalCount = 0;
/**
* Offset
*
* @var int $offset
*/
var $offset = 0;
/**
* Result handle
*
* @var resource $result
*/
var $result;
/**
* When search by id is enabled, the id to search for
*
* @var int $searchId
*/
var $searchId = false;
/**
* if we want to search for all the words or if only one is sufficient
*
* @var boolean $isExact
*/
var $isExact = false;
/**
* sections to search in
*
* @var array $sections
*/
var $sections = SEARCH__ALL_SECTIONS;
/**
* Constructor
*
* @param string $words words we are searching for
* @param int $offset offset
* @param boolean $isExact if we want to search for all the words or if only one is sufficient
* @param int $rowsPerPage number of rows per page
*/
function SearchQuery($words, $offset, $isExact, $rowsPerPage = SEARCH__DEFAULT_ROWS_PER_PAGE) {
$this->cleanSearchWords($words);
$this->rowsPerPage = $rowsPerPage;
$this->offset = $offset;
$this->isExact = $isExact;
$this->operator = $this->getOperator();
}
/**
* cleanSearchWords - clean the words we are searching for
*
* @param string $words words we are searching for
*/
function cleanSearchWords($words) {
$words = trim($words);
if(!$words) {
$this->setError('error_criteria_not_specified');
return;
}
if(is_numeric($words) && $this->implementsSearchById()) {
$this->searchId = (int) $words;
} else {
$words = htmlspecialchars($words);
$words = strtr($words, array('%' => '', '_' => ''));
$words = preg_replace("/[ \t]+/", ' ', $words);
if(strlen($words) < 3) {
$this->setError('error_search_minlength');
return;
}
$this->words = explode(' ', quotemeta($words));
}
}
/**
* executeQuery - execute the SQL query to get the results
*/
function executeQuery() {
global $sys_use_fti;
if($this->searchId) {
$query = $this->getSearchByIdQuery();
} else {
$query = $this->getQuery();
}
if ($sys_use_fti) {
db_query("select set_curcfg('default')");
}
$this->result = db_query(
$query,
$this->rowsPerPage + 1,
$this->offset,
SYS_DB_SEARCH
);
$this->rowsTotalCount = db_numrows($this->result);
$this->rowsCount = min($this->rowsPerPage, $this->rowsTotalCount);
}
/**
* getQuery - returns the sql query built to get the search results
* This is an abstract method. It _MUST_ be implemented in children classes.
*
* @return string sql query to execute
*/
function getQuery() {
return;
}
/**
* getIlikeCondition - build the ILIKE condition of the SQL query for a given field name
*
* @param string $fieldName name of the field in the ILIKE condition
* @return string the condition
*/
function getIlikeCondition($fieldName) {
return $fieldName." ILIKE '%" . implode("%' ".$this->operator." ".$fieldName." ILIKE '%", $this->words) ."%'";
}
/**
* getOperator - get the operator we have to use in ILIKE condition
*
* @return string AND if it is an exact search, OR otherwise
*/
function getOperator() {
if($this->isExact) {
return 'AND';
} else {
return 'OR';
}
}
/**
* implementsSearchById - check if the current object implements the search by id feature by having a getSearchByIdQuery method
*
* @return boolean true if our object implements search by id, false otherwise.
*/
function implementsSearchById() {
return method_exists($this, 'getSearchByIdQuery');
}
/**
* getResult - returns the result set
*
* @return resource result set
*/
function & getResult() {
return $this->result;
}
/**
* getRowsCount - returns number of rows for the current page
*
* @return int rows count for the current page
*/
function getRowsCount() {
return $this->rowsCount;
}
/**
* getRowsTotalCount - returns total number of rows
*
* @return int rows count
*/
function getRowsTotalCount() {
return $this->rowsTotalCount;
}
/**
* getOffset - returns the offset
*
* @return int offset
*/
function getOffset() {
return $this->offset;
}
/**
* getRowsPerPage - returns number of rows per page
*
* @return int number of rows per page
*/
function getRowsPerPage() {
return $this->rowsPerPage;
}
/**
* getWords - returns the array containing words we are searching for
*
* @return array words we are searching for
*/
function getWords() {
return $this->words;
}
/**
* setSections - set the sections list
*
* @param $sections mixed array of sections or SEARCH__ALL_SECTIONS
*/
function setSections($sections) {
if(is_array($sections)) {
//make a comma separated string from the sections array
foreach($sections as $key => $section)
$sections[$key] = '\''.$section.'\'';
$this->sections = implode(', ', $sections);
} else {
$this->sections = $sections;
}
}
/**
* getFormattedWords - get words formatted in order to be used in the FTI stored procedures
*
* @return string words we are searching for, separated by a pipe
*/
function getFormattedWords() {
if ($this->isExact) {
$words = implode('&', $this->words);
} else {
$words = implode('|', $this->words);
}
return $words;
}
}
?>
|