Project

General

Profile

1
<?php
2
/**
3
 *
4
 * @category        frontend
5
 * @package         search
6
 * @author          yan Djurovich, WebsiteBaker Project
7
 * @copyright       2009-2012, WebsiteBaker Org. e.V.
8
 * @link			http://www.websitebaker2.org/
9
 * @license         http://www.gnu.org/licenses/gpl.html
10
 * @platform        WebsiteBaker 2.8.x
11
 * @requirements    PHP 5.2.2 and higher
12
 * @version         $Id: search.php 2088 2014-01-19 21:18:18Z darkviper $
13
 * @filesource		$HeadURL: svn://isteam.dynxs.de/wb-archiv/branches/2.8.x/wb/search/search.php $
14
 * @lastmodified    $Date: 2014-01-19 22:18:18 +0100 (Sun, 19 Jan 2014) $
15
 *
16
 */
17

    
18
/* -------------------------------------------------------- */
19
// Must include code to stop this file being accessed directly
20
if(!defined('WB_PATH')) {
21
	require_once(dirname(dirname(__FILE__)).'/framework/globalExceptionHandler.php');
22
	throw new IllegalFileException();
23
}
24
/* -------------------------------------------------------- */
25

    
26
// Check if search is enabled
27
if(SHOW_SEARCH != true) {
28
	echo $TEXT['SEARCH'].' '.$TEXT['DISABLED'];
29
	return;
30
}
31

    
32
// Include the WB functions file
33
require_once(WB_PATH.'/framework/functions.php');
34
$oDb = WbDatabase::getInstance();
35
// Get search settings
36
$table=TABLE_PREFIX.'search';
37
// set default values if needed
38
$aSettings = array( 'search_module_order'   => 'wysiwyg',
39
                    'search_max_excerpt'    => 15,
40
                    'cfg_show_description'  => true,
41
                    'cfg_search_description'=> true,
42
                    'cfg_search_keywords'   => true,
43
                    'cfg_enable_old_search' => true,
44
                    'cfg_enable_flush'      => true,
45
                    'search_time_limit'     => 0
46
                  );
47
$sql = 'SELECT `name`, `value` FROM `'.$oDb->TablePrefix.'search`';
48
$oSearchSettings = $oDb->doQuery($sql);
49
while ($aSettingsRecord = $oSearchSettings->fetchRow(MYSQL_ASSOC)) {
50
// read settings and sanitize it
51
    switch ($aSettingsRecord['name']) {
52
        case 'header':
53
        case 'footer':
54
        case 'results_header':
55
        case 'results_footer':
56
        case 'results_loop':
57
        case 'no_results':
58
            $aSettings['fetch_'.$aSettingsRecord['name']] = $aSettingsRecord['value'];
59
            break;
60
        case 'module_order':
61
            $aSettings['search_module_order'] = ( $aSettingsRecord['value']
62
                                                  ? $aSettingsRecord['value']
63
                                                  : 'wysiwyg'
64
                                                );
65
            break;
66
        case 'max_excerpt':
67
            $aSettings['search_max_excerpt'] = ( intval($aSettingsRecord['value'])
68
                                                 ? intval($aSettingsRecord['value'])
69
                                                 : $aSettings['search_max_excerpt']
70
                                               );
71
            break;
72
        case 'cfg_show_description':
73
        case 'cfg_search_description':
74
        case 'cfg_search_keywords':
75
        case 'cfg_enable_old_search':
76
        case 'cfg_enable_flush':
77
            $aSettings[$aSettingsRecord['name']] = (filter_var( $aSettingsRecord['value'],
78
                                                                FILTER_VALIDATE_BOOLEAN,
79
                                                                FILTER_NULL_ON_FAILURE
80
                                                              ) !== false);
81
            break;
82
        case 'time_limit':
83
            $aSettings['search_time_limit'] = ( intval($aSettingsRecord['value']) < 0
84
                                                ? 0
85
                                                : intval($aSettingsRecord['value'])
86
                                              );
87
            break;
88
        default:
89
            break;
90
    }
91
}
92

    
93
// search-module-extension: get helper-functions
94
require_once(WB_PATH.'/search/search_modext.php');
95
// search-module-extension: Get "search.php" for each module, if present
96
// looks in modules/module/ and modules/module_searchext/
97
$search_funcs = array();$search_funcs['__before'] = array();$search_funcs['__after'] = array();
98
$query = $database->query("SELECT DISTINCT directory FROM ".TABLE_PREFIX."addons WHERE type = 'module' AND directory NOT LIKE '%_searchext'");
99
if($query->numRows() > 0) {
100
	while($module = $query->fetchRow()) {
101
		$file = WB_PATH.'/modules/'.$module['directory'].'/search.php';
102
		if(!file_exists($file)) {
103
			$file = WB_PATH.'/modules/'.$module['directory'].'_searchext/search.php';
104
			if(!file_exists($file)) {
105
				$file='';
106
			}
107
		}
108
		if($file!='') {
109
			include_once($file);
110
			if(function_exists($module['directory']."_search")) {
111
				$search_funcs[$module['directory']] = $module['directory']."_search";
112
			}
113
			if(function_exists($module['directory']."_search_before")) {
114
				$search_funcs['__before'][] = $module['directory']."_search_before";
115
			}
116
			if(function_exists($module['directory']."_search_after")) {
117
				$search_funcs['__after'][] = $module['directory']."_search_after";
118
			}
119
		}
120
	}
121
}
122

    
123
// Get list of usernames and display names
124
$query = $database->query("SELECT user_id,username,display_name FROM ".TABLE_PREFIX."users");
125
$users = array('0' => array('display_name' => $TEXT['UNKNOWN'], 'username' => strtolower($TEXT['UNKNOWN'])));
126
if($query->numRows() > 0) {
127
	while($user = $query->fetchRow()) {
128
		$users[$user['user_id']] = array('display_name' => $user['display_name'], 'username' => $user['username']);
129
	}
130
}
131

    
132
// Get search language, used for special umlaut handling (DE: ß=ss, ...)
133
$search_lang = '';
134
if(isset($_REQUEST['search_lang'])) {
135
	$search_lang = $_REQUEST['search_lang'];
136
	if(!preg_match('~^[A-Z]{2}$~', $search_lang))
137
		$search_lang = LANGUAGE;
138
} else {
139
	$search_lang = LANGUAGE;
140
}
141

    
142
// Get the path to search into. Normally left blank
143
// ATTN: since wb2.7.1 the path is evaluated as SQL: LIKE "/path%" - which will find "/path.php", "/path/info.php", ...; But not "/de/path.php"
144
// Add a '%' in front of each path to get SQL: LIKE "%/path%"
145
/* possible values:
146
 * - a single path: "/en/" - search only pages whose link contains 'path' ("/en/machinery/bender-x09")
147
 * - a single path not to search into: "-/help" - search all, exclude /help...
148
 * - a bunch of alternative pathes: "/en/,%/machinery/,/docs/" - alternatives paths, seperated by comma
149
 * - a bunch of paths to exclude: "-/about,%/info,/jp/,/light" - search all, exclude these.
150
 * These different styles can't be mixed.
151
 */
152
// ATTN: in wb2.7.0 "/en/" matched all links with "/en/" somewhere in the link: "/info/en/intro.php", "/en/info.php", ...
153
// since wb2.7.1 "/en/" matches only links _starting_  with "/en/": "/en/intro/info.php"
154
// use "%/en/" (or "%/en/, %/info", ...) to get the old behavior
155
$search_path_SQL = '';
156
$search_path = '';
157
// solve $_REQUEST['search_path' to be string
158
if(isset($_REQUEST['search_path']) && is_array($_REQUEST['search_path'])) {
159
    $_REQUEST['search_path'] = implode(",", $_REQUEST['search_path']);
160
}
161
if(isset($_REQUEST['search_path'])) {
162
	$search_path = addslashes(htmlspecialchars(strip_tags($wb->strip_slashes($_REQUEST['search_path'])), ENT_QUOTES));
163
	if(!preg_match('~^%?[-a-zA-Z0-9_,/ ]+$~', $search_path))
164
		$search_path = '';
165
	if($search_path != '') {
166
		$search_path_SQL = 'AND ( ';
167
		$not = '';
168
		$op = 'OR';
169
		if($search_path[0] == '-') {
170
			$not = 'NOT';
171
			$op = 'AND';
172
			$paths = explode(',', substr($search_path, 1) );
173
		} else {
174
			$paths = explode(',',$search_path);
175
		}
176
		$i=0;
177
		foreach($paths as $p) {
178
			if($i++ > 0) {
179
				$search_path_SQL .= ' $op';
180
			}
181
			$search_path_SQL .= " link $not LIKE '".$p."%'";
182
		}
183
		$search_path_SQL .= ' )';
184
	}
185
}
186

    
187
// use page_languages?
188
if(PAGE_LANGUAGES) {
189
	$table = TABLE_PREFIX."pages";
190
	$search_language_SQL_t = "AND $table.`language` = '".LANGUAGE."'";
191
	$search_language_SQL = "AND `language` = '".LANGUAGE."'";
192
} else {
193
	$search_language_SQL_t = '';
194
	$search_language_SQL = '';
195
}
196

    
197
// Get the search type
198
$match = '';
199
if(isset($_REQUEST['match'])) {
200
	if($_REQUEST['match']=='any') $match = 'any';
201
	elseif($_REQUEST['match']=='all') $match = 'all';
202
	elseif($_REQUEST['match']=='exact') $match = 'exact';
203
	else $match = 'all';
204
} else {
205
	$match = 'all';
206
}
207

    
208
// Get search string
209
$search_normal_string = '';
210
$search_entities_string = ''; // for SQL's LIKE
211
$search_display_string = ''; // for displaying
212
$search_url_string = ''; // for $_GET -- ATTN: unquoted! Will become urldecoded later
213
$string = '';
214
if(isset($_REQUEST['string'])) {
215
	if($match!='exact') { // $string will be cleaned below
216
		$string=str_replace(',', '', trim($_REQUEST['string']) );
217
	} else {
218
		$string=trim($_REQUEST['string']);
219
	}
220
    // redo possible magic quotes
221
    $string = $wb->strip_slashes($string);
222
    $string = preg_replace('/\s+/', ' ', $string);
223
//    $string = trim($string);
224
	// remove some bad chars
225
	$string = str_replace ( array('[[',']]'),'', $string);
226
	$string = preg_replace('/(^|\s+)[|.]+(?=\s+|$)/', '', $string);
227
	$search_display_string = htmlspecialchars($string);
228
	// convert string to utf-8
229
	$string = entities_to_umlauts($string, 'UTF-8');
230
	$search_url_string = $string;
231
	$search_entities_string = addslashes(htmlentities($string, ENT_COMPAT, 'UTF-8'));
232
	// mySQL needs four backslashes to match one in LIKE comparisons)
233
	$search_entities_string = str_replace('\\\\', '\\\\\\\\', $search_entities_string);
234
	$string = preg_quote($string);
235
	// quote ' " and /  -we need quoted / for regex
236
	$search_normal_string = str_replace(array('\'','"','/'), array('\\\'','\"','\/'), $string);
237
}
238
// make arrays from the search_..._strings above
239
if($match == 'exact')
240
	$search_url_array[] = $search_url_string;
241
else
242
	$search_url_array = explode(' ', $search_url_string);
243
$search_normal_array = array();
244
$search_entities_array = array();
245
if($match == 'exact') {
246
	$search_normal_array[]=$search_normal_string;
247
	$search_entities_array[]=$search_entities_string;
248
} else {
249
	$exploded_string = explode(' ', $search_normal_string);
250
	// Make sure there is no blank values in the array
251
	foreach($exploded_string AS $each_exploded_string) {
252
		if($each_exploded_string != '') {
253
			$search_normal_array[] = $each_exploded_string;
254
		}
255
	}
256
	$exploded_string = explode(' ', $search_entities_string);
257
	// Make sure there is no blank values in the array
258
	foreach($exploded_string AS $each_exploded_string) {
259
		if($each_exploded_string != '') {
260
			$search_entities_array[] = $each_exploded_string;
261
		}
262
	}
263
}
264
// make an extra copy of search_normal_array for use in regex
265
$search_words = array();
266
require_once(WB_PATH.'/search/search_convert.php');
267
global $search_table_umlauts_local;
268
require_once(WB_PATH.'/search/search_convert_ul.php');
269
global $search_table_ul_umlauts;
270
foreach($search_normal_array AS $str) {
271
	$str = strtr($str, $search_table_umlauts_local);
272
	$str = strtr($str, $search_table_ul_umlauts);
273
	$search_words[] = $str;
274
}
275

    
276
// Work-out what to do (match all words, any words, or do exact match), and do relevant with query settings
277
$all_checked = '';
278
$any_checked = '';
279
$exact_checked = '';
280
if ($match == 'any') {
281
	$any_checked = ' checked="checked"';
282
	$logical_operator = ' OR';
283
} elseif($match == 'all') {
284
	$all_checked = ' checked="checked"';
285
	$logical_operator = ' AND';
286
} else {
287
	$exact_checked = ' checked="checked"';
288
}
289

    
290
// Replace vars in search settings with values
291
$vars = array('[SEARCH_STRING]', '[WB_URL]', '[PAGE_EXTENSION]', '[TEXT_RESULTS_FOR]');
292
$values = array($search_display_string, WB_URL, PAGE_EXTENSION, $TEXT['RESULTS_FOR']);
293
$search_footer = str_replace($vars, $values, ($aSettings['fetch_footer']));
294
$search_results_header = str_replace($vars, $values, ($aSettings['fetch_results_header']));
295
$search_results_footer = str_replace($vars, $values, ($aSettings['fetch_results_footer']));
296

    
297
// Do extra vars/values replacement
298
$vars = array('[SEARCH_STRING]', '[WB_URL]', '[PAGE_EXTENSION]', '[TEXT_SEARCH]', '[TEXT_ALL_WORDS]', '[TEXT_ANY_WORDS]', '[TEXT_EXACT_MATCH]', '[TEXT_MATCH]', '[TEXT_MATCHING]', '[ALL_CHECKED]', '[ANY_CHECKED]', '[EXACT_CHECKED]', '[REFERRER_ID]', '[SEARCH_PATH]');
299
$values = array($search_display_string, WB_URL, PAGE_EXTENSION, $TEXT['SEARCH'], $TEXT['ALL_WORDS'], $TEXT['ANY_WORDS'], $TEXT['EXACT_MATCH'], $TEXT['MATCH'], $TEXT['MATCHING'], $all_checked, $any_checked, $exact_checked, REFERRER_ID, $search_path);
300
$search_header = str_replace($vars, $values, ($aSettings['fetch_header']));
301
$vars = array('[TEXT_NO_RESULTS]');
302
$values = array($TEXT['NO_RESULTS']);
303
$search_no_results = str_replace($vars, $values, ($aSettings['fetch_no_results']));
304

    
305
/*
306
 * Start of output
307
 */
308

    
309
// Show search header
310
echo $search_header;
311
// Show search results_header
312
echo $search_results_header;
313

    
314
// Work-out if the user has already entered their details or not
315
if($search_normal_string != '') {
316

    
317
	// Get modules
318
	$table = TABLE_PREFIX."sections";
319
	$get_modules = $database->query("SELECT DISTINCT module FROM $table WHERE module != '' ");
320
	$modules = array();
321
	if($get_modules->numRows() > 0) {
322
		while($module = $get_modules->fetchRow()) {
323
			$modules[] = $module['module'];
324
		}
325
	}
326
	// sort module search-order
327
	// get the modules from $aSettings['search_module_order'] first ...
328
	$sorted_modules = array();
329
	$m = count($modules);
330
	$search_modules = explode(',', $aSettings['search_module_order']);
331
	foreach($search_modules AS $item) {
332
		$item = trim($item);
333
		for($i=0; $i < $m; $i++) {
334
			if(isset($modules[$i]) && $modules[$i] == $item) {
335
				$sorted_modules[] = $modules[$i];
336
				unset($modules[$i]);
337
				break;
338
			}
339
		}
340
	}
341
	// ... then add the rest
342
	foreach($modules AS $item) {
343
		$sorted_modules[] = $item;
344
	}
345

    
346

    
347
	// Use the module's search-extensions.
348
	// This is somewhat slower than the orginial method.
349
	// call $search_funcs['__before'] first
350
	$search_func_vars = array(
351
		'database' => $database, // database-handle
352
		'page_id' => 0,
353
		'section_id' => 0,
354
		'page_title' => '',
355
		'page_menu_title' => '',
356
		'page_description' => '',
357
		'page_keywords' => '',
358
		'page_link' => '',
359
		'page_modified_when' => 0,
360
		'page_modified_by' => 0,
361
		'users' => $users, // array of known user-id/user-name
362
		'search_words' => $search_words, // array of strings, prepared for regex
363
		'search_match' => $match, // match-type
364
		'search_url_array' => $search_url_array, // array of strings from the original search-string. ATTN: strings are not quoted!
365
		'search_entities_array' => $search_entities_array, // entities
366
		'results_loop_string' => $aSettings['fetch_results_loop'],
367
		'default_max_excerpt' => $aSettings['search_max_excerpt'],
368
		'time_limit' => $aSettings['search_time_limit'], // time-limit in secs
369
		'search_path' => $search_path // see docu
370
	);
371
	foreach($search_funcs['__before'] as $func) {
372
		$uf_res = call_user_func($func, $search_func_vars);
373
	}
374
	// now call module-based $search_funcs[]
375
	$seen_pages = array(); // seen pages per module.
376
	$pages_listed = array(); // seen pages.
377
	if($aSettings['search_max_excerpt']!=0) { // skip this search if $aSettings['search_max_excerpt']==0
378
		foreach($sorted_modules AS $module_name) {
379
			$start_time = time();	// get start-time to check time-limit; not very accurate, but ok
380
			$seen_pages[$module_name] = array();
381
			if(!isset($search_funcs[$module_name])) {
382
				continue; // there is no search_func for this module
383
			}
384
			// get each section for $module_name
385
			$table_s = TABLE_PREFIX."sections";
386
			$table_p = TABLE_PREFIX."pages";
387
			$sections_query = $database->query("
388
				SELECT s.section_id, s.page_id, s.module, s.publ_start, s.publ_end,
389
							 p.page_title, p.menu_title, p.link, p.description, p.keywords, p.modified_when, p.modified_by,
390
							 p.visibility, p.viewing_groups, p.viewing_users
391
				FROM $table_s AS s INNER JOIN $table_p AS p ON s.page_id = p.page_id
392
				WHERE s.module = '$module_name' AND p.visibility NOT IN ('none','deleted') AND p.searching = '1' $search_path_SQL $search_language_SQL
393
				ORDER BY s.page_id, s.position ASC
394
			");
395
			if($sections_query->numRows() > 0) {
396
				while($res = $sections_query->fetchRow()) {
397
					// check if time-limit is exceeded for this module
398
					if($aSettings['search_time_limit'] > 0 && (time()-$start_time > $aSettings['search_time_limit'])) {
399
						break;
400
					}
401
					// Only show this section if it is not "out of publication-date"
402
					$now = time();
403
					if( !( $now<$res['publ_end'] && ($now>$res['publ_start'] || $res['publ_start']==0) ||
404
						$now>$res['publ_start'] && $res['publ_end']==0) ) {
405
						continue;
406
					}
407
					$search_func_vars = array(
408
						'database' => $database,
409
						'page_id' => $res['page_id'],
410
						'section_id' => $res['section_id'],
411
						'page_title' => $res['page_title'],
412
						'page_menu_title' => $res['menu_title'],
413
						'page_description' => ($aSettings['cfg_show_description']?$res['description']:""),
414
						'page_keywords' => $res['keywords'],
415
						'page_link' => $res['link'],
416
						'page_modified_when' => $res['modified_when'],
417
						'page_modified_by' => $res['modified_by'],
418
						'users' => $users,
419
						'search_words' => $search_words, // needed for preg_match
420
						'search_match' => $match,
421
						'search_url_array' => $search_url_array, // needed for url-string only
422
						'search_entities_array' => $search_entities_array, // entities
423
						'results_loop_string' => $aSettings['fetch_results_loop'],
424
						'default_max_excerpt' => $aSettings['search_max_excerpt'],
425
						'enable_flush' => $aSettings['cfg_enable_flush'],
426
						'time_limit' => $aSettings['search_time_limit'] // time-limit in secs
427
					);
428
					// Only show this page if we are allowed to see it
429
					if($admin->page_is_visible($res) == false) {
430
						if($res['visibility'] == 'registered') { // don't show excerpt
431
							$search_func_vars['default_max_excerpt'] = 0;
432
							$search_func_vars['page_description'] = $TEXT['REGISTERED'];
433
						} else { // private
434
							continue;
435
						}
436
					}
437
					$uf_res = call_user_func($search_funcs[$module_name], $search_func_vars);
438
					if($uf_res) {
439
						$pages_listed[$res['page_id']] = true;
440
						$seen_pages[$module_name][$res['page_id']] = true;
441
					} else {
442
						$seen_pages[$module_name][$res['page_id']] = true;
443
					}
444
				}
445
			}
446
		}
447
	}
448
	// now call $search_funcs['__after']
449
	$search_func_vars = array(
450
		'database' => $database, // database-handle
451
		'page_id' => 0,
452
		'section_id' => 0,
453
		'page_title' => '',
454
		'page_menu_title' => '',
455
		'page_description' => '',
456
		'page_keywords' => '',
457
		'page_link' => '',
458
		'page_modified_when' => 0,
459
		'page_modified_by' => 0,
460
		'users' => $users, // array of known user-id/user-name
461
		'search_words' => $search_words, // array of strings, prepared for regex
462
		'search_match' => $match, // match-type
463
		'search_url_array' => $search_url_array, // array of strings from the original search-string. ATTN: strings are not quoted!
464
		'search_entities_array' => $search_entities_array, // entities
465
		'results_loop_string' => $aSettings['fetch_results_loop'],
466
		'default_max_excerpt' => $aSettings['search_max_excerpt'],
467
		'time_limit' => $aSettings['search_time_limit'], // time-limit in secs
468
		'search_path' => $search_path // see docu
469
	);
470
	foreach($search_funcs['__after'] as $func) {
471
		$uf_res = call_user_func($func, $search_func_vars);
472
	}
473

    
474

    
475
	// Search page details only, such as description, keywords, etc, but only of unseen pages.
476
	$max_excerpt_num = 0; // we don't want excerpt here
477
	$divider = ".";
478
	$table = TABLE_PREFIX."pages";
479
	$query_pages = $database->query("
480
		SELECT page_id, page_title, menu_title, link, description, keywords, modified_when, modified_by,
481
		       visibility, viewing_groups, viewing_users
482
		FROM $table
483
		WHERE visibility NOT IN ('none','deleted') AND searching = '1' $search_path_SQL $search_language_SQL
484
	");
485
	if($query_pages->numRows() > 0) {
486
		while($page = $query_pages->fetchRow()) {
487
			if (isset($pages_listed[$page['page_id']])) {
488
				continue;
489
			}
490
			$func_vars = array(
491
				'database' => $database,
492
				'page_id' => $page['page_id'],
493
				'page_title' => $page['page_title'],
494
				'page_menu_title' => $page['menu_title'],
495
				'page_description' => ($aSettings['cfg_show_description']?$page['description']:""),
496
				'page_keywords' => $page['keywords'],
497
				'page_link' => $page['link'],
498
				'page_modified_when' => $page['modified_when'],
499
				'page_modified_by' => $page['modified_by'],
500
				'users' => $users,
501
				'search_words' => $search_words, // needed for preg_match_all
502
				'search_match' => $match,
503
				'search_url_array' => $search_url_array, // needed for url-string only
504
				'search_entities_array' => $search_entities_array, // entities
505
				'results_loop_string' => $aSettings['fetch_results_loop'],
506
				'default_max_excerpt' => $max_excerpt_num,
507
				'enable_flush' => $aSettings['cfg_enable_flush']
508
			);
509
			// Only show this page if we are allowed to see it
510
			if($admin->page_is_visible($page) == false) {
511
				if($page['visibility'] != 'registered') {
512
					continue;
513
				} else { // page: registered, user: access denied
514
					$func_vars['page_description'] = $TEXT['REGISTERED'];
515
				}
516
			}
517
			if($admin->page_is_active($page) == false) {
518
				continue;
519
			}
520
			$text = $func_vars['page_title'].$divider
521
				.$func_vars['page_menu_title'].$divider
522
				.($aSettings['cfg_search_description']?$func_vars['page_description']:"").$divider
523
				.($aSettings['cfg_search_keywords']?$func_vars['page_keywords']:"").$divider;
524
			$mod_vars = array(
525
				'page_link' => $func_vars['page_link'],
526
				'page_link_target' => "",
527
				'page_title' => $func_vars['page_title'],
528
				'page_description' => $func_vars['page_description'],
529
				'page_modified_when' => $func_vars['page_modified_when'],
530
				'page_modified_by' => $func_vars['page_modified_by'],
531
				'text' => $text,
532
				'max_excerpt_num' => $func_vars['default_max_excerpt']
533
			);
534
			if(print_excerpt2($mod_vars, $func_vars)) {
535
				$pages_listed[$page['page_id']] = true;
536
			}
537
		}
538
	}
539

    
540
	// Now use the old method for pages not displayed by the new method above
541
	// in case someone has old modules without search.php.
542

    
543
	// Get modules
544
	$table_search = TABLE_PREFIX."search";
545
	$table_sections = TABLE_PREFIX."sections";
546
	$get_modules = $database->query("
547
		SELECT DISTINCT s.value, s.extra
548
		FROM $table_search AS s INNER JOIN $table_sections AS sec
549
			ON s.value = sec.module
550
		WHERE s.name = 'module'
551
	");
552
	$modules = array();
553
	if($get_modules->numRows() > 0) {
554
		while($module = $get_modules->fetchRow()) {
555
			$modules[] = $module; // $modules in an array of arrays
556
		}
557
	}
558
	// sort module search-order
559
	// get the modules from $aSettings['search_module_order'] first ...
560
	$sorted_modules = array();
561
	$m = count($modules);
562
	$search_modules = explode(',', $aSettings['search_module_order']);
563
	foreach($search_modules AS $item) {
564
		$item = trim($item);
565
		for($i=0; $i < $m; $i++) {
566
			if(isset($modules[$i]) && $modules[$i]['value'] == $item) {
567
				$sorted_modules[] = $modules[$i];
568
				unset($modules[$i]);
569
				break;
570
			}
571
		}
572
	}
573
	// ... then add the rest
574
	foreach($modules AS $item) {
575
		$sorted_modules[] = $item;
576
	}
577

    
578
	if($aSettings['cfg_enable_old_search']) { // this is the old (wb <= 2.6.7) search-function
579
		$search_path_SQL = str_replace(' link ', ' '.TABLE_PREFIX.'pages.link ', $search_path_SQL);
580
		foreach($sorted_modules AS $module) {
581
			if(isset($seen_pages[$module['value']]) && count($seen_pages[$module['value']])>0) // skip modules handled by new search-func
582
				continue;
583
			$query_start = '';
584
			$query_body = '';
585
			$query_end = '';
586
			$prepared_query = '';
587
			// Get module name
588
			$module_name = $module['value'];
589
			if(!isset($seen_pages[$module_name])) {
590
				$seen_pages[$module_name]=array();
591
			}
592
			// skip module 'code' - it doesn't make sense to search in a code section
593
			if($module_name=="code")
594
				continue;
595
			// Get fields to use for title, link, etc.
596
			$fields = unserialize($module['extra']);
597
			// Get query start
598
			$get_query_start = $database->query("SELECT value FROM ".TABLE_PREFIX."search WHERE name = 'query_start' AND extra = '$module_name' LIMIT 1");
599
			if($get_query_start->numRows() > 0) {
600
				// Fetch query start
601
				$fetch_query_start = $get_query_start->fetchRow();
602
				// Prepare query start for execution by replacing {TP} with the TABLE_PREFIX
603
				$query_start = str_replace('[TP]', TABLE_PREFIX, ($fetch_query_start['value']));
604
			}
605
			// Get query end
606
			$get_query_end = $database->query("SELECT value FROM ".TABLE_PREFIX."search WHERE name = 'query_end' AND extra = '$module_name' LIMIT 1");
607
			if($get_query_end->numRows() > 0) {
608
				// Fetch query end
609
				$fetch_query_end = $get_query_end->fetchRow();
610
				// Set query end
611
				$query_end = ($fetch_query_end['value']);
612
			}
613
			// Get query body
614
			$get_query_body = $database->query("SELECT value FROM ".TABLE_PREFIX."search WHERE name = 'query_body' AND extra = '$module_name' LIMIT 1");
615
			if($get_query_body->numRows() > 0) {
616
				// Fetch query body
617
				$fetch_query_body = $get_query_body->fetchRow();
618
				// Prepare query body for execution by replacing {STRING} with the correct one
619
				$query_body = str_replace(array('[TP]','[O]','[W]'), array(TABLE_PREFIX,'LIKE','%'), ($fetch_query_body['value']));
620
				// Loop through query body for each string, then combine with start and end
621
				$prepared_query = $query_start." ( ( ( ";
622
				$count = 0;
623
				foreach($search_normal_array AS $string) {
624
					if($count != 0) {
625
						$prepared_query .= " ) ".$logical_operator." ( ";
626
					}
627
					$prepared_query .= str_replace('[STRING]', $string, $query_body);
628
					$count = $count+1;
629
				}
630
				$count=0;
631
				$prepared_query .= ' ) ) OR ( ( ';
632
				foreach($search_entities_array AS $string) {
633
					if($count != 0) {
634
						$prepared_query .= " ) ".$logical_operator." ( ";
635
					}
636
					$prepared_query .= str_replace('[STRING]', $string, $query_body);
637
					$count = $count+1;
638
				}
639
				$prepared_query .= " ) ) ) ".$query_end;
640
				// Execute query
641
				$page_query = $database->query($prepared_query." ".$search_path_SQL." ".$search_language_SQL_t);
642
				if(!$page_query) continue; // on error, skip the rest of the current loop iteration
643
				// Loop through queried items
644
				if($page_query->numRows() > 0) {
645
					while($page = $page_query->fetchRow()) {
646
						// Only show this page if it hasn't already been listed
647
						if(isset($seen_pages[$module_name][$page['page_id']]) || isset($pages_listed[$page['page_id']])) {
648
							continue;
649
						}
650

    
651
						// don't list pages with visibility == none|deleted and check if user is allowed to see the page
652
						$p_table = TABLE_PREFIX."pages";
653
						$viewquery = $database->query("
654
							SELECT visibility, viewing_groups, viewing_users
655
							FROM $p_table
656
							WHERE page_id='{$page['page_id']}'
657
						");
658
						$visibility = 'none'; $viewing_groups="" ; $viewing_users="";
659
						if($viewquery->numRows() > 0) {
660
							if($res = $viewquery->fetchRow()) {
661
								$visibility = $res['visibility'];
662
								$viewing_groups = $res['viewing_groups'];
663
								$viewing_users = $res['viewing_users'];
664
								if($visibility == 'deleted' || $visibility == 'none') {
665
									continue;
666
								}
667
								if($visibility == 'private') {
668
									if($admin->page_is_visible(array(
669
										'page_id'=>$page[$fields['page_id']],
670
										'visibility' =>$visibility,
671
										'viewing_groups'=>$viewing_groups,
672
										'viewing_users'=>$viewing_users
673
									)) == false) {
674
										continue;
675
									}
676
								}
677
								if($admin->page_is_active(array('page_id'=>$page[$fields['page_id']]))==false) {
678
									continue;
679
								}
680
							}
681
						}
682

    
683
						// Get page link
684
						$link = page_link($page['link']);
685
						// Add search string for highlighting
686
						if ($match!='exact') {
687
							$sstring = implode(" ", $search_normal_array);
688
							$link = $link."?searchresult=1&amp;sstring=".urlencode($sstring);
689
						} else {
690
							$sstring = str_replace(" ", "_",$search_normal_array[0]);
691
							$link = $link."?searchresult=2&amp;sstring=".urlencode($sstring);
692
						}
693
						// Set vars to be replaced by values
694
						if(!isset($page['description'])) { $page['description'] = ""; }
695
						if(!isset($page['modified_when'])) { $page['modified_when'] = 0; }
696
						if(!isset($page['modified_by'])) { $page['modified_by'] = 0; }
697
						$vars = array('[LINK]', '[TITLE]', '[DESCRIPTION]', '[USERNAME]','[DISPLAY_NAME]','[DATE]','[TIME]','[TEXT_LAST_UPDATED_BY]','[TEXT_ON]','[EXCERPT]');
698
						if($page['modified_when'] > 0) {
699
							$date = gmdate(DATE_FORMAT, $page['modified_when']+TIMEZONE);
700
							$time = gmdate(TIME_FORMAT, $page['modified_when']+TIMEZONE);
701
						} else {
702
							$date = $TEXT['UNKNOWN'].' '.$TEXT['DATE'];
703
							$time = $TEXT['UNKNOWN'].' '.$TEXT['TIME'];
704
						}
705
						$excerpt="";
706
						if($aSettings['cfg_show_description'] == 0) {
707
							$page['description'] = "";
708
						}
709
						$values = array($link, $page['page_title'], $page['description'], $users[$page['modified_by']]['username'], $users[$page['modified_by']]['display_name'], $date, $time, $TEXT['LAST_UPDATED_BY'], strtolower($TEXT['ON']), $excerpt);
710
						// Show loop code with vars replaced by values
711
						echo str_replace($vars, $values, ($aSettings['fetch_results_loop']));
712
						// Say that this page has been listed
713
						$seen_pages[$module_name][$page['page_id']] = true;
714
						$pages_listed[$page['page_id']] = true;
715
					}
716
				}
717
			}
718
		}
719
	}
720

    
721
	// Say no items found if we should
722
	if(count($pages_listed) == 0) {
723
		echo $search_no_results;
724
	}
725
} else {
726
	echo $search_no_results;
727
}
728

    
729
// Show search results_footer
730
echo $search_results_footer;
731
// Show search footer
732
echo $search_footer;
(2-2/5)