| 1 |
<?php |
<?php |
| 2 |
/* $Id: search404.module,v 1.13.2.11 2008/12/19 09:11:25 zyxware Exp $ */ |
/* $Id: search404.module,v 1.13.2.9 2008/07/28 09:57:21 zyxware Exp $ */ |
| 3 |
|
|
| 4 |
|
/* @file |
| 5 |
|
* The search404 module files, does all the searching |
| 6 |
|
* when a 404 occurs |
| 7 |
|
*/ |
| 8 |
|
|
| 9 |
/** |
/** |
| 10 |
* Implementation of hook_menu(). |
* Implementation of hook_menu(). |
| 11 |
*/ |
*/ |
| 12 |
function search404_menu($may_cache) { |
function search404_menu($may_cache) { |
| 13 |
$items = array(); |
$items = array(); |
|
|
|
| 14 |
if ($may_cache) { |
if ($may_cache) { |
| 15 |
$items[] = array('path' => 'search404', |
$items[] = array('path' => 'search404', |
| 16 |
'title' => t('Page not found'), 'access' => true, |
'title' => t('Page not found'), 'access' => TRUE, |
| 17 |
'callback' => 'search404_page', 'type' => MENU_CALLBACK); |
'callback' => 'search404_page', 'type' => MENU_LOCAL_TASK); |
| 18 |
$items[] = array( |
$items[] = array( |
| 19 |
'path' => 'admin/settings/search404', |
'path' => 'admin/settings/search404', |
| 20 |
'title' => t('Search 404 settings'), |
'title' => t('Search 404 settings'), |
| 40 |
$extensions = preg_split('/\s+/', variable_get('search404_ignore_query', 'gif jpg jpeg bmp png')); |
$extensions = preg_split('/\s+/', variable_get('search404_ignore_query', 'gif jpg jpeg bmp png')); |
| 41 |
$extensions = trim(implode('|', $extensions)); |
$extensions = trim(implode('|', $extensions)); |
| 42 |
if (!empty($extensions) && preg_match("/\.($extensions)$/", $_REQUEST['destination'])) { |
if (!empty($extensions) && preg_match("/\.($extensions)$/", $_REQUEST['destination'])) { |
| 43 |
return false; |
return FALSE; |
| 44 |
} |
} |
| 45 |
$keys = $_REQUEST['destination'] ? $_REQUEST['destination'] : $_REQUEST['q']; |
$keys = $_REQUEST['destination']; |
| 46 |
$regex_filter = variable_get('search404_regex', ''); |
$misc_var = variable_get('search404_regex', ''); |
| 47 |
$keys_array[] = $keys; |
if (!empty($misc_var)) { |
| 48 |
if (!empty($regex_filter)) { |
$keys = preg_grep($misc_var, $keys); |
| 49 |
$keys = preg_replace("/".$regex_filter."/", '', $keys); |
$keys = $keys[0]; |
| 50 |
} |
} |
| 51 |
|
|
| 52 |
// Ingore certain extensions from query |
// Ingore certain extensions from query |
| 53 |
$extensions = preg_split('/\s+/', variable_get('search404_ignore_extensions', 'htm html php')); |
$extensions = preg_split('/\s+/', variable_get('search404_ignore_extensions', 'htm html php')); |
| 54 |
$extensions = trim(implode('|', $extensions)); |
$extensions = trim(implode('|', $extensions)); |
| 55 |
if (!empty($extensions)) { |
if (!empty($extensions)) { |
| 56 |
$keys = preg_replace("/\.($extensions)$/", '', $keys); |
$keys = preg_replace("/\.($extensions)$/", '', $keys); |
| 57 |
} |
} |
| 58 |
|
|
| 59 |
$keys = preg_split('/['. PREG_CLASS_SEARCH_EXCLUDE .']+/u', $keys); |
$keys = preg_split('/['. PREG_CLASS_SEARCH_EXCLUDE .']+/u', $keys); |
| 63 |
foreach ($keys as $a => $b) { |
foreach ($keys as $a => $b) { |
| 64 |
$keys[$a] = check_plain($b); |
$keys[$a] = check_plain($b); |
| 65 |
} |
} |
| 66 |
$modifier = variable_get('search404_use_or', false) ? ' OR ' : ' '; |
$modifier = variable_get('search404_use_or', FALSE) ? ' OR ' : ' '; |
| 67 |
$keys = trim(implode($modifier, $keys)); |
$keys = trim(implode($modifier, $keys)); |
| 68 |
return $keys; |
return $keys; |
| 69 |
} |
} |
| 70 |
|
|
| 71 |
/** |
/** |
| 72 |
* Detect search from search engine |
* Detect search from search engine (BETA) |
| 73 |
* WARNING: This function can potentially return dangerous |
* WARNING: This function can potentially return dangerous |
| 74 |
* potential SQL inject/XSS |
* potential SQL inject/XSS |
| 75 |
* data. Return must be sanatized before use. |
* data. Return must be sanatized before use. |
| 79 |
'altavista' => 'q', |
'altavista' => 'q', |
| 80 |
'aol' => 'query', |
'aol' => 'query', |
| 81 |
'google' => 'q', |
'google' => 'q', |
| 82 |
'bing' => 'q', |
'live' => 'q', |
| 83 |
'lycos' => 'query', |
'lycos' => 'query', |
| 84 |
|
'msn' => 'q', |
| 85 |
'yahoo' => 'p', |
'yahoo' => 'p', |
| 86 |
); |
); |
| 87 |
$parsed_url = parse_url($_SERVER['HTTP_REFERER']); |
$parsed_url = parse_url($_SERVER['HTTP_REFERER']);drupal_set_message('Parsed url :'. $parsed_url); |
| 88 |
$remote_host = $parsed_url['host']; |
$remote_host = $parsed_url['host'];drupal_set_message('Remote host :'. $remote_host); |
| 89 |
$query_string = $parsed_url['query']; |
$query_string = $parsed_url['query'];drupal_set_message('Query string :'. $query_string); |
| 90 |
parse_str($query_string, $query); |
parse_str($query_string, $query); |
| 91 |
|
|
| 92 |
if (!$parsed_url === false && !empty($remote_host) && !empty($query_string) && count($query)) { |
if (!$parsed_url === FALSE && !empty($remote_host) && !empty($query_string) && count($query)) { |
| 93 |
foreach ($engines as $host => $key) { |
foreach ($engines as $host => $key) { |
| 94 |
if (strpos($remote_host, $host) !== false && array_key_exists($key, $query)) { |
if (strpos($remote_host, $host) !== FALSE && array_key_exists($key, $query)) { |
| 95 |
return trim($query[$key]); |
return trim($query[$key]); |
| 96 |
} |
} |
| 97 |
} |
} |
| 98 |
} |
} |
| 99 |
|
|
| 100 |
return false; |
return FALSE; |
| 101 |
} |
} |
| 102 |
|
|
| 103 |
/** |
/** |
| 111 |
|
|
| 112 |
if (module_exists('search') && user_access('search content')) { |
if (module_exists('search') && user_access('search content')) { |
| 113 |
$keys = ""; |
$keys = ""; |
| 114 |
// if apachesolr_search is installed use apachesolr_search instead default node search |
if (variable_get('search404_use_search_engine', FALSE)) { |
|
$type_search = (module_exists('apachesolr_search')) ? 'apachesolr_search' : 'node'; |
|
|
if (variable_get('search404_use_search_engine', false)) { |
|
| 115 |
$keys = search404_search_engine_query(); |
$keys = search404_search_engine_query(); |
| 116 |
} |
} |
| 117 |
if (!$keys) { |
if (!$keys) { |
| 119 |
} |
} |
| 120 |
if ($keys) { |
if ($keys) { |
| 121 |
// TODO: watchdog? |
// TODO: watchdog? |
| 122 |
$results = module_invoke($type_search, 'search', 'search', $keys); |
$results = module_invoke('node', 'search', 'search', $keys); |
| 123 |
if (isset($results) && is_array($results) && count($results) == 1 && variable_get('search404_jump', false)) { |
if (isset($results) && is_array($results) && count($results) == 1 && variable_get('search404_jump', FALSE)) { |
| 124 |
// First, check to see if there is exactly 1 result |
// First, check to see if there is exactly 1 result |
| 125 |
drupal_set_message(t('The page you requested does not exist. A search for %keys resulted in this page.', array('%keys' => check_plain($keys))), 'status'); |
drupal_set_message(t('The page you requested does not exist. A search for %keys resulted in this page.', array('%keys' => check_plain($keys))), 'status'); |
| 126 |
// overwrite $_REQUEST['destination'] because it is set by drupal_not_found() |
// overwrite $_REQUEST['destination'] because it is set by drupal_not_found() |
| 127 |
$_REQUEST['destination'] = 'node/'. $results[0]['node']->nid; |
$_REQUEST['destination'] = 'node/'. $results[0]['node']->nid; |
| 128 |
drupal_goto(); |
drupal_goto(); |
| 129 |
} |
} |
| 130 |
elseif (isset($results) && is_array($results) && count($results) > 1 && variable_get('search404_first', false)) { |
elseif (isset($results) && is_array($results) && count($results) > 1 && variable_get('search404_first', FALSE)) { |
| 131 |
drupal_set_message(t('The page you requested does not exist. A search for %keys resulted in this page.', array('%keys' => check_plain($keys))), 'status'); |
drupal_set_message(t('The page you requested does not exist. A search for %keys resulted in this page.', array('%keys' => check_plain($keys))), 'status'); |
| 132 |
// overwrite $_REQUEST['destination'] because it is set by drupal_not_found() |
// overwrite $_REQUEST['destination'] because it is set by drupal_not_found() |
| 133 |
$_REQUEST['destination'] = 'node/'. $results[0]['node']->nid; |
$_REQUEST['destination'] = 'node/'. $results[0]['node']->nid; |
| 141 |
$oldgetq = $_GET['q']; |
$oldgetq = $_GET['q']; |
| 142 |
$olddestination = $_REQUEST['destination']; |
$olddestination = $_REQUEST['destination']; |
| 143 |
unset($_REQUEST['destination']); |
unset($_REQUEST['destination']); |
| 144 |
$_GET['q'] = "search/$type_search/$keys"; |
$_GET['q'] = "search/node/$keys"; |
| 145 |
$results = theme('search_page', $results, 'node'); |
$results = theme('search_page', $results, 'node'); |
| 146 |
$_GET['q'] = $oldgetq; |
$_GET['q'] = $oldgetq; |
| 147 |
$_REQUEST['destination'] = $olddestination; |
$_REQUEST['destination'] = $olddestination; |
| 148 |
// END OF EVIL HAXX! |
// END OF EVIL HAXX! |
| 149 |
} |
} |
| 150 |
else { |
else { |
|
|
|
| 151 |
$results = search_help('search#noresults'); |
$results = search_help('search#noresults'); |
| 152 |
} |
} |
| 153 |
$results = theme('box', t('Search results'), $results); |
$results = theme('box', t('Search results'), $results); |
| 157 |
$output .= drupal_get_form('search_form', NULL, $keys, 'node'); |
$output .= drupal_get_form('search_form', NULL, $keys, 'node'); |
| 158 |
$output .= $results; |
$output .= $results; |
| 159 |
} |
} |
| 160 |
/* |
|
| 161 |
* Start EVIL HAXX 2 |
return $output; |
|
* This was done to display blocks left and right of page, if the option is set from Search404 |
|
|
* Settings Page. |
|
|
*/ |
|
|
if (variable_get('search404_block_show', false)) { |
|
|
print theme('page', $output); |
|
|
drupal_page_footer(); |
|
|
unset($output); |
|
|
exit (0); |
|
|
} |
|
|
else { |
|
|
return $output; |
|
|
} |
|
|
//End of EVIL HAXX 2 |
|
| 162 |
} |
} |
| 163 |
|
|
| 164 |
/** |
/** |
| 168 |
$form['search404_jump'] = array( |
$form['search404_jump'] = array( |
| 169 |
'#type' => 'checkbox', |
'#type' => 'checkbox', |
| 170 |
'#title' => t('Jump directly to the search result when there is only one result.'), |
'#title' => t('Jump directly to the search result when there is only one result.'), |
| 171 |
'#default_value' => variable_get('search404_jump', false), |
'#default_value' => variable_get('search404_jump', FALSE), |
| 172 |
); |
); |
| 173 |
$form['search404_first'] = array( |
$form['search404_first'] = array( |
| 174 |
'#type' => 'checkbox', |
'#type' => 'checkbox', |
| 175 |
'#title' => t('Jump directly to the first search result when there are multiple results.'), |
'#title' => t('Jump directly to the first search result when there are multiple results.'), |
| 176 |
'#default_value' => variable_get('search404_first', false), |
'#default_value' => variable_get('search404_first', FALSE), |
|
); |
|
|
//Added for displaying blocks for 404 searches |
|
|
$form['search404_block_show'] = array( |
|
|
'#type' => 'checkbox', |
|
|
'#title' => t('Show Left and Right blocks in Page when a 404 Search occurs'), |
|
|
'#default_value' => variable_get('search404_block_show', false), |
|
| 177 |
); |
); |
| 178 |
$form['advanced'] = array( |
$form['advanced'] = array( |
| 179 |
'#type' => 'fieldset', |
'#type' => 'fieldset', |
| 180 |
'#title' => t('Advanced settings'), |
'#title' => t('Advanced settings'), |
| 181 |
//'#description' => t("WARNING. Some of these settings can mess up stuff, don't touch unless you know what you are doing."), |
'#description' => t("WARNING. Some of these settings can mess up stuff, don't touch unless you know what you are doing."), |
| 182 |
'#collapsible' => TRUE, |
'#collapsible' => TRUE, |
| 183 |
'#collapsed' => TRUE, |
'#collapsed' => TRUE, |
| 184 |
); |
); |
| 185 |
$form['advanced']['search404_use_or'] = array( |
$form['advanced']['search404_use_or'] = array( |
| 186 |
'#type' => 'checkbox', |
'#type' => 'checkbox', |
| 187 |
'#title' => t('Use OR between keywords when searching.'), |
'#title' => t('Use OR between keywords when searching.'), |
| 188 |
'#default_value' => variable_get('search404_use_or', false), |
'#default_value' => variable_get('search404_use_or', FALSE), |
| 189 |
); |
); |
| 190 |
$form['advanced']['search404_use_search_engine'] = array( |
$form['advanced']['search404_use_search_engine'] = array( |
| 191 |
'#type' => 'checkbox', |
'#type' => 'checkbox', |
| 192 |
'#title' => t('Use auto-detection of keywords from search engine referer.'), |
'#title' => t('Use auto-detection of keywords from search engine referer. BETA! Not for production sites, use at your own risk.'), |
| 193 |
'#description' => t('This feature will conduct a search based on the query string got from a search engine if the URL of the search result points to a 404 page in the current website. Currently supported search engines: Google, Yahoo, Altavista, Lycos, Bing and AOL'), |
'#default_value' => variable_get('search404_use_search_engine', FALSE), |
|
'#default_value' => variable_get('search404_use_search_engine', false), |
|
| 194 |
); |
); |
| 195 |
$form['advanced']['search404_ignore'] = array( |
$form['advanced']['search404_ignore'] = array( |
| 196 |
'#type' => 'textfield', |
'#type' => 'textfield', |
| 201 |
$form['advanced']['search404_ignore_extensions'] = array( |
$form['advanced']['search404_ignore_extensions'] = array( |
| 202 |
'#type' => 'textfield', |
'#type' => 'textfield', |
| 203 |
'#title' => t('Extensions to ignore'), |
'#title' => t('Extensions to ignore'), |
| 204 |
'#description' => t('These extensions will be ignored from the search query, e.g.: http://www.example.com/invalid/page.php will only search for "invalid page". Separate extensions with a space, e.g.: "htm html php". Do not include leading dot.'), |
'#description' => t('These extensions will be ignored from query. Separate extensions with a space, e.g.: "htm html php". Do not include leading dot.'), |
| 205 |
'#default_value' => variable_get('search404_ignore_extensions', 'htm html php'), |
'#default_value' => variable_get('search404_ignore_extensions', 'htm html php'), |
| 206 |
); |
); |
| 207 |
$form['advanced']['search404_ignore_query'] = array( |
$form['advanced']['search404_ignore_query'] = array( |
| 212 |
); |
); |
| 213 |
$form['advanced']['search404_regex'] = array( |
$form['advanced']['search404_regex'] = array( |
| 214 |
'#type' => 'textfield', |
'#type' => 'textfield', |
| 215 |
'#title' => t('PCRE filter'), |
'#title' => t('PCRE REGEX'), |
| 216 |
'#description' => t('This regular expression will be applied to filter all queries. The parts of the path that match the expression will be EXCLUDED from the search. You do NOT have to enclose the regex in forward slashes when defining the PCRE. e.g.: use "[foo]bar" instead of "/[foo]bar/". On how to use a PCRE Regex please refer <a href="http://php.net/pcre">PCRE pages in the PHP Manual</a>.'), |
'#description' => t('This regex will applied to all queries. It uses the code:<p>%code</p>Look directly at the source code to understand underlying syntax. See also <a href="http://php.net/pcre">PCRE pages in the PHP Manual</a>.', array('%code' => "\$keys = preg_grep(variable_get('search404_regex'), \$keys);\n\$keys = \$keys[0];", '%function' => 'search404_get_keys()')), |
| 217 |
'#default_value' => variable_get('search404_regex',''), |
'#default_value' => variable_get('search404_regex', ''), |
| 218 |
); |
); |
| 219 |
|
|
| 220 |
return system_settings_form($form); |
return system_settings_form($form); |