/[drupal]/contributions/modules/search404/search404.module
ViewVC logotype

Contents of /contributions/modules/search404/search404.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.16 - (show annotations) (download) (as text)
Mon Jul 28 08:05:14 2008 UTC (16 months ago) by zyxware
Branch: MAIN
CVS Tags: HEAD
Branch point for: DRUPAL-7--1
Changes since 1.15: +7 -5 lines
File MIME type: text/x-php
Fixed the bugs reported on node #273357, #240579
1 <?php
2 /* $Id: search404.module,v 1.15 2008/03/04 12:14:30 zyxware Exp $ */
3 /**
4 * Implementation of hook_menu().
5 */
6 function search404_menu() {
7 $items = array();
8 $items['search404'] = array(
9 'title' => t('Page not found'),
10 'access callback' => TRUE,
11 'page callback' => 'search404_page',
12 'type' => MENU_LOCAL_TASK
13 );
14 $items['admin/settings/search404'] = array(
15 'title' => t('Search 404 settings'),
16 'description' => t('Administer search 404.'),
17 'page callback' => 'drupal_get_form',
18 'page arguments' => array('search404_settings'),
19 'access callback' => 'user_access',
20 'access arguments' => array('administer site configuration'),
21 'type' => MENU_NORMAL_ITEM,
22 );
23 return $items;
24 }
25
26 /**
27 * Replacement for search_get_keys
28 * WARNING: This function can potentially return dangerous
29 * potential SQL inject/XSS
30 * data. Return must be sanatized before use.
31 */
32 function search404_get_keys() {
33 // Abort query on certain extensions, e.g: gif jpg jpeg png
34 $extensions = preg_split('/\s+/', variable_get('search404_ignore_query', 'gif jpg jpeg bmp png'));
35 $extensions = trim(implode('|', $extensions));
36 if (!empty($extensions) && preg_match("/\.($extensions)$/", $_REQUEST['destination'])) {
37 return false;
38 }
39 $keys = $_REQUEST['destination'];
40 $misc_var = variable_get('search404_regex', '');
41 if (!empty($misc_var)) {
42 $keys = preg_grep($misc_var, $keys);
43 $keys = $keys[0];
44 }
45 // Ingore certain extensions from query
46 $extensions = preg_split('/\s+/', variable_get('search404_ignore_extensions', 'htm html php'));
47 $extensions = trim(implode('|', $extensions));
48 if (!empty($extensions)) {
49 $keys = preg_replace("/\.($extensions)$/", '', $keys);
50 }
51
52 $keys = preg_split('/['. PREG_CLASS_SEARCH_EXCLUDE .']+/u', $keys);
53
54 // Ignore certain words
55 $keys = array_diff($keys, explode(' ', variable_get('search404_ignore', 'and or the')));
56 //Sanitize the keys
57 foreach ($keys as $a => $b) {
58 $keys[$a] = check_plain($b);
59 }
60 $modifier = variable_get('search404_use_or', false) ? ' OR ' : ' ';
61 $keys = trim(implode($modifier, $keys));
62 return $keys;
63 }
64
65 /**
66 * Detect search from search engine (BETA)
67 */
68 function search404_search_engine_query() {
69 $engines = array(
70 'altavista' => 'q',
71 'aol' => 'query',
72 'google' => 'q',
73 'live' => 'q',
74 'lycos' => 'query',
75 'msn' => 'q',
76 'yahoo' => 'p',
77 );
78 $parsed_url = parse_url($_SERVER['HTTP_REFERER']);
79 $remote_host = $parsed_url['host'];
80 $query_string = $parsed_url['query'];
81 parse_str($query_string, $query);
82
83 if (!$parsed_url === false && !empty($remote_host) && !empty($query_string) && count($query)) {
84 foreach ($engines as $host => $key) {
85 if (strpos($remote_host, $host) !== false && array_key_exists($key, $query)) {
86 return trim($query[$key]);
87 }
88 }
89 }
90
91 return false;
92 }
93
94 /**
95 * Main search function.
96 * Started with: http://drupal.org/node/12668
97 * Updated to be more similar to search_view
98 * Beware of messy code
99 */
100 function search404_page() {
101 $output = '<p>'. t('The page you requested was not found.') .'</p>';
102 if (module_exists('search') && user_access('search content')) {
103 $keys = "";
104 if (variable_get('search404_use_search_engine', false)) {
105 $keys = search404_search_engine_query();
106 }
107 if (!$keys) {
108 $keys = search404_get_keys();
109 }
110 if ($keys) {
111 // TODO: watchdog?
112 $results = module_invoke('node', 'search', 'search', $keys);
113 if (isset($results) && is_array($results) && count($results) == 1 && variable_get('search404_jump', false)) {
114 // First, check to see if there is exactly 1 result
115 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');
116 // overwrite $_REQUEST['destination'] because it is set by drupal_not_found()
117 $_REQUEST['destination'] = 'node/'. $results[0]['node']->nid;
118 drupal_goto();
119 }
120 elseif (isset($results) && is_array($results) && count($results) > 1 && variable_get('search404_first', false)) {
121 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');
122 // overwrite $_REQUEST['destination'] because it is set by drupal_not_found()
123 $_REQUEST['destination'] = 'node/'. $results[0]['node']->nid;
124 drupal_goto();
125 }
126 else {
127 drupal_set_message(t('The page you requested does not exist. For your convenience, a search was performed using the query %keys.', array('%keys' => check_plain($keys))), 'error');
128 if (isset($results) && is_array($results) && count($results) > 0) {drupal_set_message('Inside Else1');
129 drupal_add_css(drupal_get_path('module', 'search') .'/search.css', 'module', 'all', FALSE);
130 // EVIL HAXX!
131 $oldgetq = $_GET['q'];
132 $olddestination = $_REQUEST['destination'];
133 unset($_REQUEST['destination']);
134 $_GET['q'] = "search/node/$keys";
135 $results = theme('search_results', $results, 'node');
136 $_GET['q'] = $oldgetq;
137 $_REQUEST['destination'] = $olddestination;
138 // END OF EVIL HAXX!
139 }
140 else {
141 $results = search_help('search#noresults', drupal_help_arg());
142 }
143 $results = theme('box', t('Search results'), $results);
144 }
145 }
146 // Construct the search form.
147 $output .= drupal_get_form('search_form', NULL, $keys, 'node');
148 $output .= $results;
149 }
150 return $output;
151 }
152
153 /**
154 * Search404 administration settings
155 */
156 function search404_settings() {
157 $form['search404_jump'] = array(
158 '#type' => 'checkbox',
159 '#title' => t('Jump directly to the search result when there is only one result.'),
160 '#default_value' => variable_get('search404_jump', false),
161 );
162 $form['search404_first'] = array(
163 '#type' => 'checkbox',
164 '#title' => t('Jump directly to the first search result when there are multiple results.'),
165 '#default_value' => variable_get('search404_first', false),
166 );
167 $form['advanced'] = array(
168 '#type' => 'fieldset',
169 '#title' => t('Advanced settings'),
170 '#description' => t("WARNING. Some of these settings can mess up stuff, don't touch unless you know what you are
171 doing."),
172 '#collapsible' => TRUE,
173 '#collapsed' => TRUE,
174 );
175 $form['advanced']['search404_use_or'] = array(
176 '#type' => 'checkbox',
177 '#title' => t('Use OR between keywords when searching.'),
178 '#default_value' => variable_get('search404_use_or', false),
179 );
180 $form['advanced']['search404_use_search_engine'] = array(
181 '#type' => 'checkbox',
182 '#title' => t('Use auto-detection of keywords from search engine referer. BETA! Not for production sites, use at your own risk.'),
183 '#default_value' => variable_get('search404_use_search_engine', false),
184 );
185 $form['advanced']['search404_ignore'] = array(
186 '#type' => 'textfield',
187 '#title' => t('Words to ignore'),
188 '#description' => t('These words will be ignored from query. Separate words with a space, e.g.: "and or the".'),
189 '#default_value' => variable_get('search404_ignore', 'and or the'),
190 );
191 $form['advanced']['search404_ignore_extensions'] = array(
192 '#type' => 'textfield',
193 '#title' => t('Extensions to ignore'),
194 '#description' => t('These extensions will be ignored from query. Separate extensions with a space, e.g.: "htm html php". Do not include leading dot.'),
195 '#default_value' => variable_get('search404_ignore_extensions', 'htm html php'),
196 );
197 $form['advanced']['search404_ignore_query'] = array(
198 '#type' => 'textfield',
199 '#title' => t('Extensions to abort search'),
200 '#description' => t('A search will not be performed for a query ending in the following extensions. Separate extensions with a space, e.g.: "gif jpg jpeg bmp png". Do not include leading dot.'),
201 '#default_value' => variable_get('search404_ignore_query', 'gif jpg jpeg bmp png'),
202 );
203 $form['advanced']['search404_regex'] = array(
204 '#type' => 'textfield',
205 '#title' => t('PCRE REGEX'),
206 '#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()')),
207 '#default_value' => variable_get('search404_regex',''),
208 );
209 return system_settings_form($form);
210 }

  ViewVC Help
Powered by ViewVC 1.1.2