52 $sql =
"create table dataface__index (
53 index_id int(11) not null auto_increment,
54 `table` varchar(64) not null,
55 record_id varchar(255) not null,
56 record_url varchar(255) not null,
57 record_title varchar(255) not null,
58 record_description text,
59 `lang` varchar(2) not null,
60 `searchable_text` text,
61 fulltext index `searchable_text_index` (`searchable_text`),
62 unique key `record_key` (`record_id`,`lang`),
63 primary key (`index_id`))";
64 $res = mysql_query($sql, df_db());
67 trigger_error(mysql_error(df_db()), E_USER_ERROR);
86 if ( is_array(
$app->_conf[
'languages']) ){
87 import(
'Dataface/IO.php');
89 foreach ( array_keys(
$app->_conf[
'languages']) as $lang){
90 if ( $lang ==
$app->_conf[
'lang'] ){
94 $io->read($record->getId(), $record);
101 if ( !isset($lang) ) $lang =
$app->_conf[
'lang'];
103 $del =& $record->_table->getDelegate();
104 if ( isset($del) and method_exists($del,
'getSearchableText') ){
105 $searchable_text = $del->getSearchableText($record);
106 if ( !is_string($searchable_text) ){
115 $fields = $record->_table->getCharFields(
true);
116 $searchable_text = implode(
', ', $record->strvals(
$fields));
120 replace into dataface__index
121 (`record_id`,`table`,`record_url`,`record_title`,`record_description`,`lang`,`searchable_text`)
124 '".addslashes($record->getId()).
"',
125 '".addslashes($record->_table->tablename).
"',
126 '".addslashes($record->getPublicLink()).
"',
127 '".addslashes($record->getTitle()).
"',
128 '".addslashes(strip_tags($record->getDescription())).
"',
129 '".addslashes($lang).
"',
130 '".addslashes($searchable_text).
"'
132 if ( !@mysql_query($sql, df_db()) ){
134 if ( !mysql_query($sql, df_db()) ){
135 trigger_error(mysql_error(df_db()), E_USER_ERROR);
144 for ( $start = 0; $start >= 0; $start +=100 ){
147 $records = df_get_records_array($query[
'-table'], $query, $start, 100,
false);
148 if ( !$records or (count($records) == 0) or
PEAR::isError($records) )
return true;
150 foreach ($records as $record){
160 $sql =
"delete from dataface__index";
161 if ( !mysql_query($sql, df_db()) ){
170 $sql =
"optimize table dataface__index";
171 if ( !mysql_query($sql, df_db()) ){
173 $sql =
"optimize table dataface__index";
174 mysql_query($sql, df_db());
182 $indexableTables = @
$app->_conf[
'_index'];
183 if ( !is_array($indexableTables) ){
184 $indexableTables = array();
187 if ( @$indexableTables[
'__default__'] ){
195 if ( isset(
$table->_atts[
'__index__']) and
$table->_atts[
'__index__'] == 0){
210 if ( strlen($a) < strlen($b) )
return 1;
211 else if ( strlen($b) < strlen($a) )
return -1;
220 function find($query, $returnMetadata=
false, $lang=null){
222 if ( !$lang ) $lang =
'en';
224 $select =
"select record_id,`table`,record_url,record_title,record_description, `searchable_text`, `lang`,match(searchable_text) against ('".addslashes($query[
'-search']).
"') as `relevance`";
228 where `lang`='".addslashes($lang).
"' and
229 match(searchable_text)
230 against ('".addslashes($query[
'-search']).
"')";
233 $countsql =
"select count(record_id), `table` as num ".$sql.
" group by `table`";
235 if ( isset($query[
'-table']) ){
236 $sql .=
" and `table` = '".addslashes($query[
'-table']).
"'";
241 if ( !isset($query[
'-limit']) ){
242 $query[
'-limit'] = 30;
247 if ( !isset($query[
'-skip']) ){
250 $skip = intval($query[
'-skip']);
251 $limit = intval($query[
'-limit']);
252 $sql .=
" limit $skip, $limit";
255 $res = @mysql_query($sql, df_db());
258 $res = mysql_query($sql, df_db());
260 trigger_error(mysql_error(df_db()), E_USER_ERROR);
266 $words = explode(
' ', str_replace(
'"',
'', $query[
'-search']));
267 if ( preg_match_all(
'/"([^"]+)"/', $query[
'-search'], $matches, PREG_PATTERN_ORDER) ){
268 foreach ($matches[1] as $m){
272 $numWords = count($words);
273 if ( $numWords > 1 ){
274 $words2 = array(implode(
' ', $words));
275 for ( $i=0; $i<$numWords; $i++){
276 for ( $j=$i; $j<$numWords; $j++){
279 for ( $k=$i; $k<=$j; $k++ ){
282 $words2[] = implode(
' ', $temp);
288 usort($words, array($this,
'_cmp_words_by_length'));
290 while ( $row = mysql_fetch_assoc($res) ){
291 $st = strip_tags($row[
'searchable_text']);
294 unset($row[
'searchable_text']);
297 foreach ($phrases as $p){
298 if ( preg_match_all(
'/.{0,50}'.preg_quote($p,
'/').
'.{0,50}/', $st, $matches, PREG_PATTERN_ORDER) ){
300 foreach ($matches[0] as $m){
302 if ( count($summary) > 5 )
break;
309 foreach ($words as $p){
310 if ( !trim($p) )
continue;
311 if ( preg_match_all(
'/.{0,50}'.preg_quote($p,
'/').
'.{0,50}/', $st, $matches, PREG_PATTERN_ORDER) ){
312 foreach ($matches[0] as $m){
314 if ( count($summary) > 5 )
break;
320 $row[
'record_description'] =
'...' .implode(
' ... ', $summary).
' ...';
326 @mysql_free_result($res);
327 if ( $returnMetadata ){
329 $res = @mysql_query($countsql, df_db());
330 if ( !$res ) trigger_error(mysql_error(df_db()), E_USER_ERROR);
333 $tables_matches = array();
335 while ($row = mysql_fetch_row($res) ){
337 $label = @
$app->_conf[
'table_labels'][$row[1]];
338 if ( !$label ) $label = @
$app->tables[$row[1]];
339 if ( !$label ) $label = $row[1];
340 $tables_matches[ $row[1] ] = array(
'found'=>$row[0],
'label'=>$label);
341 $total_found += intval($row[0]);
342 if ( !@$query[
'-table'] or $query[
'-table'] == $row[1] )$found += intval($row[0]);
344 @mysql_free_result($res);
347 $meta[
'found'] = $found;
348 $meta[
'skip'] = $query[
'-skip'];
349 $meta[
'limit'] = $query[
'-limit'];
350 $meta[
'start'] = $query[
'-skip'];
351 $meta[
'end'] = min($meta[
'start']+$meta[
'limit'], $meta[
'found']);
352 $meta[
'tables'] = $tables_matches;
353 $meta[
'table'] = $query[
'-table'];
354 $meta[
'table_objects'] =& $table_objects;
355 $meta[
'total_found'] = $total_found;
356 return array(
'results'=>
$out,
'metadata'=>@$meta);