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

Contents of /contributions/modules/distributed_search/distributed_search.module

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


Revision 1.1 - (show annotations) (download) (as text)
Wed Oct 15 21:44:12 2008 UTC (13 months, 1 week ago) by aufumy
Branch: MAIN
CVS Tags: HEAD
Branch point for: DRUPAL-6--1
File MIME type: text/x-php
Search multiple drupal sites, using services module
1 <?php
2 // $Id$
3
4 /**
5 * @file
6 * Distributed search with client sites having services,xmlrpc and search-services enabled
7 */
8
9 /**
10 * Implementation of hook_help().
11 */
12 function distributed_search_help($path = '', $arg) {
13 switch ($path) {
14 case 'admin/modules#description':
15 return t('Distributed search of drupal sites that have services and xmlrpc-server enabled.');
16 }
17 }
18
19 /**
20 * Implementation of hook_perm().
21 */
22 function distributed_search_perm() {
23 return array('administer distributed search');
24 }
25
26 /**
27 * Implementation of hook_menu().
28 */
29 function distributed_search_menu() {
30 $items = array();
31 $items['distributed_search_test'] = array(
32 'title' => t('Distributed Search Test'),
33 'page callback' => 'distributed_search_test',
34 'type' => MENU_CALLBACK,
35 'access arguments' => array('search content'),
36 );
37
38 $admin_access = array('administer distributed search');
39 $items['admin/settings/distributed_search'] = array(
40 'title' => 'Distributed Search',
41 'description' => 'Configure Distributed Search sources.',
42 'page callback' => 'distributed_search_admin',
43 'access arguments' => $admin_access
44 );
45 $items['admin/settings/distributed_search/list'] = array(
46 'title' => 'List',
47 'type' => MENU_DEFAULT_LOCAL_TASK,
48 'weight' => -10,
49 'access arguments' => $admin_access
50 );
51 $items['admin/settings/distributed_search/add/source'] = array(
52 'title' => 'Add source',
53 'page callback' => 'drupal_get_form',
54 'page arguments' => array('distributed_search_form_source'),
55 'access arguments' => $admin_access,
56 'type' => MENU_LOCAL_TASK
57 );
58 $items['admin/settings/distributed_search/edit/source/%'] = array(
59 'title' => 'Edit source',
60 'page callback' => 'drupal_get_form',
61 'page arguments' => array('distributed_search_form_source', 5),
62 'access arguments' => $admin_access,
63 'type' => MENU_CALLBACK
64 );
65
66 return $items;
67 }
68
69 /**
70 * Implementation of hook_search().
71 */
72 function distributed_search_search($op = 'search', $keywords = NULL) {
73 switch ($op) {
74 case 'name':
75 return t('distributed');
76 case 'reset':
77 return;
78 case 'search':
79 return distributed_search_results();
80 }
81 }
82
83 function distributed_search_results() {
84 global $user;
85
86 $sources = distributed_search_get_sources();
87
88 $domain = $_SERVER['HTTP_HOST'];
89 foreach ($sources as $source) {
90 $site = trim($source->url);
91 $sessid = session_id();
92 $nonce = user_password();
93 $timestamp = time();
94 $hash_parameters = array($timestamp, $domain, $nonce, 'search.nodes');
95 $hash = hash_hmac('sha256', implode(';', $hash_parameters), $source->apikey);
96 $results = xmlrpc($site .'/services/xmlrpc', 'search.nodes', $hash, $domain, "$timestamp", $nonce, $sessid, 'test', 'simple');
97 // If no results returned, search the next site
98 if (!$results) {
99 continue;
100 }
101 foreach ($results as $key => $result) {
102 $result['site'] = $site;
103 $results[$key] = $result;
104 $searches[] = $result;
105 }
106 }
107 return $searches;
108 }
109
110 /**
111 * Menu callback
112 */
113 function distributed_search_admin() {
114 $result = db_query('SELECT * FROM {distributed_search_source} ORDER BY title');
115 $output = '<h3>'. t('Source overview') .'</h3>';
116
117 $header = array(t('Title'), t('URL'), t('API key'), array('data' => t('Operations'), 'colspan' => ' 1'));
118 $rows = array();
119 while ($source = db_fetch_object($result)) {
120 $rows[] = array(
121 check_plain($source->title),
122 check_url(url($source->url)),
123 check_plain($source->apikey),
124 l(t('edit'), "admin/settings/distributed_search/edit/source/$source->sid")
125 );
126 }
127 if (count($rows) == 0) {
128 $rows[] = array(array('colspan' => 4, 'data' => t('No sources defined.')));
129 }
130 $output .= theme('table', $header, $rows);
131 return $output;
132 }
133
134 /**
135 * Fetch a distributed search source.
136 */
137 function distributed_search_get_source($sid) {
138 return db_fetch_array(db_query('SELECT * FROM {distributed_search_source} WHERE sid = %d', $sid));
139 }
140
141 /**
142 * Return the list of distributed search sources that are configured.
143 */
144 function distributed_search_get_sources() {
145 $sources = array();
146 $result = db_query('SELECT * FROM {distributed_search_source}');
147 while ($source = db_fetch_object($result)) {
148 $sources[$source->sid] = $source;
149 }
150 return $sources;
151 }
152
153 /**
154 * Generate a form to add/edit sources.
155 */
156 function distributed_search_form_source($form_state, $nid = 0) {
157 $edit = distributed_search_get_source($nid);
158
159 $form['title'] = array(
160 '#type' => 'textfield',
161 '#title' => t('Title'),
162 '#default_value' => $edit['title'],
163 '#maxlength' => 64,
164 '#description' => t('The name of the source; typically the name of the web site you syndicate content from.'),
165 '#required' => TRUE,
166 );
167 $form['url'] = array(
168 '#type' => 'textfield',
169 '#title' => t('Description URL'),
170 '#default_value' => $edit['url'],
171 '#maxlength' => 255,
172 '#description' => t('The fully-qualified URL of the Distributed Search client site.'),
173 '#required' => TRUE,
174 );
175 $form['apikey'] = array(
176 '#type' => 'textfield',
177 '#title' => t('API key.'),
178 '#default_value' => $edit['url'],
179 '#maxlength' => 255,
180 '#description' => t('The API key generated by the search client site, to connect to it.'),
181 '#required' => TRUE,
182 );
183
184 $form['submit'] = array('#type' => 'submit', '#value' => t('Submit'));
185
186 if ($edit['sid']) {
187 $form['delete'] = array('#type' => 'submit', '#value' => t('Delete'));
188 $form['sid'] = array('#type' => 'hidden', '#value' => $edit['sid']);
189 }
190
191 return $form;
192 }
193
194 /**
195 * check http request for the url
196 */
197 function check_http_request($url) {
198 $result = drupal_http_request($url);
199 // Process HTTP response code.
200 switch ($result->code) {
201 case 301:
202 // Redirect.
203 return check_http_request($result->redirect_url);
204 case 200:
205 case 302:
206 case 307:
207 if ($result->data) {
208 return array('success' => TRUE);
209 }
210 default:
211 return array('success' => FALSE, 'error' => $result->code .' '. $result->error);
212 }
213 }
214
215 /**
216 * Validate distributed_search_form_source form submissions.
217 */
218 function distributed_search_form_source_validate($form, &$form_state) {
219 if ($form_state['values']['op'] == t('Submit')) {
220 // Check for duplicate titles
221 if (isset($form_state['values']['sid'])) {
222 $result = db_query("SELECT title, url FROM {distributed_search_source} WHERE (title = '%s' OR url = '%s') AND sid <> %d", $form_state['values']['title'], $form_state['values']['url'], $form_state['values']['sid']);
223 }
224 else {
225 $result = db_query("SELECT title, url FROM {distributed_search_source} WHERE title = '%s' OR url = '%s'", $form_state['values']['title'], $form_state['values']['url']);
226 }
227 while ($source = db_fetch_object($result)) {
228 if (strcasecmp($source->title, $form_state['values']['title']) == 0) {
229 form_set_error('title', t('A source named %source already exists. Please enter a unique title.', array('%source' => $form_state['values']['title'])));
230 }
231 }
232
233 $discover = check_http_request($form_state['values']['url']);
234 if (! $discover['success']) {
235 form_set_error('url', t('URL did not return a valid HTTP Response. The error was: %error', array('%error' => $discover['error'])));
236 }
237 }
238 }
239
240 /**
241 * Process distributed_search_form_source form submissions.
242 * @todo Add delete confirmation dialog.
243 */
244 function distributed_search_form_source_submit($form, &$form_state) {
245 if ($form_state['values']['op'] == t('Delete')) {
246 $title = $form_state['values']['title'];
247 // Unset the title:
248 unset($form_state['values']['title']);
249 }
250 distributed_search_save_source($form_state['values']);
251 if (isset($form_state['values']['sid'])) {
252 if (isset($form_state['values']['title'])) {
253 drupal_set_message(t('The source %source has been updated.', array('%source' => $form_state['values']['title'])));
254 }
255 else {
256 watchdog('distributed_search', 'Source %source deleted.', array('%source' => $title));
257 drupal_set_message(t('The source %source has been deleted.', array('%source' => $title)));
258 }
259 }
260 else {
261 watchdog('distributed_search', 'Source %source added.', array('%source' => $form_state['values']['title']), WATCHDOG_NOTICE, l(t('view'), 'admin/settings/distributed_search'));
262 drupal_set_message(t('The source %source has been added.', array('%source' => $form_state['values']['title'])));
263 }
264 $form_state['redirect'] = 'admin/settings/distributed_search';
265 }
266
267 /**
268 * Add/edit/delete an aggregator source.
269 */
270 function distributed_search_save_source($edit) {
271 if (!empty($edit['sid']) && !empty($edit['title'])) {
272 db_query("UPDATE {distributed_search_source} SET title = '%s', url = '%s', apikey = '%s' WHERE sid = %d", $edit['title'], $edit['url'], $edit['apikey'], $edit['sid']);
273 }
274 else if (!empty($edit['sid'])) {
275 db_query('DELETE FROM {distributed_search_source} WHERE sid = %d', $edit['sid']);
276 }
277 else if ($edit['title']) {
278 db_query("INSERT INTO {distributed_search_source} (title, url, apikey) VALUES ('%s', '%s', '%s')", $edit['title'], $edit['url'], $edit['apikey']);
279 $edit['sid'] = db_last_insert_id('distributed_search_source', 'sid');
280 }
281 }
282

  ViewVC Help
Powered by ViewVC 1.1.2