13ef18af17594a80414d65931c32c0ca0f8007b3
[mkdru-moved-to-drupal.org.git] / mkdru.module
1 <?php
2 // $Id$
3
4
5
6 // Module metainfo
7 /**
8 * Implementation of hook_node_info()
9 */
10 function mkdru_node_info() {
11   return array(
12     'mkdru' => array(
13       'name' => t("Pazpar2 metasearch interface"),
14       'module' => 'mkdru',
15       'description' => t("Metasearch interface for Z39.50/SRU and other targets via a Pazpar2/Service Proxy backend"),
16     )
17   );
18 }
19
20 function mkdru_ting_search_show($params) {
21    $path = drupal_get_path('module', 'mkdru');
22   // Include client library.
23   drupal_add_js(variable_get('pz2_js_path', 'pazpar2/js') 
24     . '/pz2.js', 'module', 'footer');
25   drupal_add_js($path . '/mkdru.theme.js', 'module', 'footer');
26   drupal_add_js($path . '/mkdru.client.js', 'module', 'footer');
27   $html = theme('mkdru_results'); 
28   drupal_add_js(array('mkdru' => 
29     array('use_sessions' => '1', 'query' => $params['keys']
30     )), 'setting');
31   return array("content" => $html);
32 }
33
34 /**
35 * Implementation of hook_perm()
36 */
37 function mkdru_perm() {
38   return array('create metasearch interface', 'edit any metasearch interface', 'edit own metasearch interface');
39 }
40
41 /**
42 * Implementation of hook_access()
43 */
44 function mkdru_access($op, $node, $account) {
45
46   if ($op == 'create') {
47     // Only users with permission to do so may create this node type.
48     return user_access('create metasearch interface', $account);
49   }
50
51   // Users who create a node may edit or delete it later, assuming they have the
52   // necessary permissions.
53   if ($op == 'update' || $op == 'delete') {
54     if (user_access('edit own metasearch interface', $account) && ($account->uid == $node->uid)) {
55       return TRUE;
56     }
57     elseif (user_access('edit any metasearch interface', $account)) {
58       return TRUE;
59     }
60   }
61 }
62
63 /**
64 * Implementation of hook_menu()
65 */
66 function mkdru_menu() {
67   $items['admin/settings/mkdru'] = array(
68     'title' => 'mkdru Settings',
69     'description' => 'Settings for mkdru.',
70     'page callback' => 'drupal_get_form',
71     'page arguments' => array('mkdru_admin_settings'),
72     'access arguments' => array('administer site configuration'),
73     'type' => MENU_NORMAL_ITEM,
74     'file' => 'mkdru.admin.inc',
75   );
76   return $items;
77 }
78
79 /**
80 * Implementation of hook_init()
81 */
82 function mkdru_init(){
83   // Applies our module specific CSS to all pages. This works best because
84   // all CSS is aggregated and cached so we reduce the number of HTTP 
85   // requests and the size is negligible.
86   drupal_add_css(drupal_get_path('module', 'mkdru') .'/mkdru.css');
87 }
88
89
90
91 // Node config
92 /**
93 * Implementation of hook_form()
94 */
95 function mkdru_form(&$node, $form_state) {
96   $type = node_get_types('type', $node);
97
98   $form['title'] = array(
99     '#type' => 'textfield',
100     '#title' => check_plain($type->title_label),
101     '#required' => FALSE,
102     '#default_value' => $node->title,
103     '#weight' => -5
104   );
105
106   $form['search_settings']  = array(
107     '#type' => 'fieldset',
108     '#title' => t('Pazpar2/Service Proxy search settings'),
109     '#collapsible' => TRUE,
110     '#collapsed' => FALSE
111   );
112   $form['search_settings']['pz2_path'] = array(
113     '#type' => 'textfield',
114     '#title' => t('Pazpar2/Service Proxy path'),
115     '#description' => t('Path that takes Pazpar2 commands via HTTP'),
116     '#required' => TRUE,
117     '#default_value' => isset($node->mkdru->pz2_path) ? $node->mkdru->pz2_path : '/pazpar2/search.pz2',
118   );
119   $form['search_settings']['use_sessions'] = array(
120     '#type' => 'checkbox',
121     '#title' => t('Session handling'),
122     '#description' => t('Disable for use with Service Proxy'),
123     '#default_value' => isset($node->mkdru->use_sessions) ? $node->mkdru->use_sessions : 1,
124   );
125
126   $form['display_settings']  = array(
127     '#type' => 'fieldset',
128     '#title' => t('Display settings'),
129     '#collapsible' => TRUE,
130     '#collapsed' => FALSE
131   );
132   $form['display_settings']['source_max'] = array(
133     '#type' => 'textfield',
134     '#title' => t('Number of sources to display'),
135     '#required' => TRUE,
136     '#default_value' => isset($node->mkdru->source_max) ? $node->mkdru->source_max : 10,
137     '#size' => 3,
138     '#maxlength' => 3,
139   );
140   $form['display_settings']['author_max'] = array(
141     '#type' => 'textfield',
142     '#title' => t('Number of authors to display'),
143     '#required' => TRUE,
144     '#default_value' => isset($node->mkdru->author_max) ? $node->mkdru->author_max : 10,
145     '#size' => 3,
146     '#maxlength' => 3,
147   );
148   $form['display_settings']['subject_max'] = array(
149     '#type' => 'textfield',
150     '#title' => t('Number of subjects to display'),
151     '#required' => TRUE,
152     '#default_value' => isset($node->mkdru->subject_max) ? $node->mkdru->subject_max : 10,
153     '#size' => 3,
154     '#maxlength' => 3,
155   );
156   return $form;
157 }
158
159
160 /**
161 * Implementation of hook_validate()
162 */
163 function mkdru_validate($node) {
164   if (!is_numeric($node->source_max)) {
165     form_set_error('source_max', t('Please enter a number.'));
166   }
167   if (!is_numeric($node->author_max)) {
168     form_set_error('author_max', t('Please enter a number.'));
169   }
170   if (!is_numeric($node->subject_max)) {
171     form_set_error('subject_max', t('Please enter a number.'));
172   }
173 }
174
175 /**
176 * Implementation of hook_insert().
177 */
178 function mkdru_insert($node) {
179   db_query("INSERT INTO {mkdru} (nid, vid, pz2_path, use_sessions, source_max, author_max, subject_max) VALUES (%d, %d, '%s', %d, %d, %d, %d)",
180     $node->nid, $node->vid, $node->pz2_path, $node->use_sessions, $node->source_max, $node->author_max, $node->subject_max);
181 }
182
183 /**
184 * Implementation of hook_update().
185 */
186 function mkdru_update($node) {
187   if ($node->revision) {
188     // New revision; treat it as a new record.
189     mkdru_insert($node);
190   }
191   else {
192     db_query("UPDATE {mkdru} SET pz2_path = '%s', use_sessions = %d, source_max = %d, author_max = %d, subject_max = %d WHERE vid = %d", $node->pz2_path, $node->use_sessions, $node->source_max, $node->author_max, $node->subject_max, $node->vid);
193   }
194 }
195
196 /**
197  * Implementation of hook_nodeapi().
198  *
199  * When a node revision is deleted, we need to remove the corresponding record
200  * from our table. The only way to handle revision deletion is by implementing
201  * hook_nodeapi().
202  */
203 function mkdru_nodeapi(&$node, $op, $teaser, $page) {
204   switch ($op) {
205     case 'delete revision':
206       db_query('DELETE FROM {mkdru} WHERE vid = %d', $node->vid);
207       break;
208   }
209 }
210
211 /**
212  * Implementation of hook_delete().
213  */
214 function mkdru_delete($node) {
215   // Deleting by nid covers all revisions.
216   db_query('DELETE FROM {mkdru} WHERE nid = %d', $node->nid);
217 }
218
219
220
221 // Node rendering
222 /**
223 * Implementation of hook_load()
224 */
225 function mkdru_load($node) {
226   return array('mkdru' => db_fetch_object(db_query(
227     'SELECT * FROM {mkdru} WHERE vid = %d', $node->vid)));
228 }
229
230 /**
231 * Implementation of hook_theme().
232 */
233 function mkdru_theme() {
234   return array(
235     'mkdru_form' => array(
236       'template' => 'mkdru-form',
237       'arguments' => array(),
238     ),
239     'mkdru_results' => array(
240       'template' => 'mkdru-results',
241       'arguments' => array(),
242     ),
243     'mkdru_js' => array(
244       'arguments' => array('node' => NULL),
245     ),
246     'mkdru_block_search' => array(
247       'template' => 'mkdru-block-search',
248       'arguments' => array('nid' => null, 'path' => NULL),
249     ),
250 //     'mkdru_block_facet' => array(
251 //       'template' => 'mkdru-block-facet',
252 //       'arguments' => array('divId' => NULL),
253 //     ),
254   );
255 }
256
257 /**
258 * Theme function to include Javascript search client and deps
259 */
260 function theme_mkdru_js($node) {
261   $path = drupal_get_path('module', 'mkdru');
262   // Pazpar2 client library.
263   drupal_add_js(variable_get('pz2_js_path', 'pazpar2/js') . '/pz2.js', 'module', 'footer', TRUE, TRUE, FALSE);
264   // jQuery plugin for query string/history manipulation.
265   drupal_add_js($path . '/jquery.ba-bbq.js', 'module', 'footer', TRUE, TRUE, FALSE);
266   drupal_add_js($path . '/mkdru.theme.js', 'module', 'footer', TRUE, TRUE, FALSE);
267   drupal_add_js($path . '/mkdru.client.js', 'module', 'footer', TRUE, TRUE, FALSE);
268   drupal_add_js(array('mkdru' => $node->mkdru), 'setting');
269 }
270
271 /** 
272 * Implementation of hook_view()
273 */
274 function mkdru_view($node, $teaser = FALSE, $page = FALSE) {
275   $node->content['mkdru_js'] = array(
276     '#value' => theme('mkdru_js', $node), 
277     '#weight' => 0,
278   );
279   $node->content['mkdru_form'] = array(
280     '#value' => theme('mkdru_form'), 
281     '#weight' => 1,
282   );
283   $node->content['mkdru_results'] = array(
284     '#value' => theme('mkdru_results'), 
285     '#weight' => 2,
286   );
287   return $node;
288 }
289
290 /** 
291 * Implementation of hook_block()
292 */
293 function mkdru_block($op='list', $delta='sources', $edit=array()) {
294   switch ($op) {
295     case 'list':
296       // facet blocks
297       // NB: block caching is redundant for static content
298       $blocks['mkdru_sources']['info'] = t('mkdru - source facets');
299       $blocks['mkdru_sources']['cache'] = BLOCK_NO_CACHE;
300       $blocks['mkdru_subjects']['info'] = t('mkdru - subject facets');
301       $blocks['mkdru_subjects']['cache'] = BLOCK_NO_CACHE;
302       $blocks['mkdru_authors']['info'] = t('mkdru - author facets');
303       $blocks['mkdru_authors']['cache'] = BLOCK_NO_CACHE;
304       // search blocks
305       $result = db_query("SELECT title, nid FROM {node} WHERE type = 'mkdru';");
306       while ($node = db_fetch_object($result)) {
307         $blocks['mkdru_search_' . $node->nid]['info'] = 
308            t('mkdru - search box for "' . $node->title . '"');
309         $blocks['mkdru_sources']['cache'] = BLOCK_NO_CACHE;
310       };
311       return $blocks;
312
313     case 'view':
314       switch ($delta) {
315         // TODO: make the facet themable, I have no clue why this won't work
316 //         case 'mkdru_sources':
317 //           $block['subject'] = t('Source');
318 //           $block['content'] = theme('mkdru_block_facet', 'mkdru-sources');
319 //           return $block;
320 //         case 'mkdru_subjects':
321 //           $block['subject'] = t('Subject');
322 //           $block['content'] = theme('mkdru_block_facet', 'mkdru-subjects');
323 //           return $block;
324 //         case 'mkdru_authors':
325 //           $block['subject'] = t('Author');
326 //           $block['content'] = theme('mkdru_block_facet', 'mkdru-authors');
327 //           return $block;
328         case 'mkdru_sources':
329           $block['subject'] = t('Source');
330           $block['content'] = '<div class="mkdru-facet mkdru-facet-sources"> </div>';
331           return $block;
332         case 'mkdru_subjects':
333           $block['subject'] = t('Subject');
334           $block['content'] = '<div class="mkdru-facet mkdru-facet-subjects"> </div>';
335           return $block;
336         case 'mkdru_authors':
337           $block['subject'] = t('Author');
338           $block['content'] = '<div class="mkdru-facet mkdru-facet-authors"> </div>';
339           return $block;
340     }
341     if (substr($delta, 0, 13) == 'mkdru_search_') {
342       $nid = substr($delta, 13);
343       $block['content'] = theme('mkdru_block_search', $nid, '/node/' . $nid);
344       return $block;
345     }
346   }
347 }