/[drupal]/contributions/modules/biblio/biblio.pages.inc
ViewVC logotype

Contents of /contributions/modules/biblio/biblio.pages.inc

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


Revision 1.55 - (show annotations) (download) (as text)
Fri Oct 23 20:19:37 2009 UTC (4 weeks, 6 days ago) by rjerome
Branch: MAIN
CVS Tags: HEAD
Branch point for: DRUPAL-7--1
Changes since 1.54: +38 -10 lines
File MIME type: text/x-php
merged changes from DRUPAL-6--1 branch
1 <?PHP
2 // $Id: biblio.pages.inc,v 1.54 2009/10/01 01:45:42 rjerome Exp $
3 /**
4 *
5 * Copyright (C) 2006-2008 Ron Jerome
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 ****************************************************************************/
22
23 /**
24 * @return unknown_type
25 */
26 function biblio_db_search() {
27
28 $arg_list = func_get_args();
29 // Drupal search? It returns an array of search results. We store the nids
30 // of the result nodes and make them a "where n.nid in {..}" filter.
31 // After installing the filter, we can go on as usual.
32
33 // When called manually, search takes one parameter, i.e.
34 // biblio_db_search('search', 'bla blu')
35 $search = array_search('search', $arg_list);
36 if ($search !== FALSE) {
37 $keys = $arg_list[$search+1];
38
39 // Special case: if search is activated via URL, i.e., biblio/search/...,
40 // we reset the search session filter. Two searches are not combinable.
41 $base = variable_get('biblio_base', 'biblio');
42 if (preg_match('+'.$base.'/search/+', $_GET['q'])) {
43 $_SESSION['biblio_filter'] = array();
44 }
45 }
46 else {
47 $keys = _get_biblio_search_filter();
48 }
49
50 if ($keys) {
51 // Only search in biblio nodes. If we use a SESSION filter and have a list of
52 // nids stored there, don't re-search. List is reset when submitting a new search.
53 if ($search !== FALSE || !_get_biblio_search_filter('nodelist')) {
54 if ($result = biblio_build_search_query($keys)) {
55 $node_list = '';
56 while ($nid = db_result($result)) {
57 $node_list .= $nid.",";
58 }
59 // No node search result. Make sure we find nothing, too. Node -1 does not exist.
60 if (empty($node_list)) $node_list = '-1';
61
62 // Store as SESSION filter or argument list.
63 // When called as function argument it takes only one parameter, i.e.
64 // biblio_db_search('search', 'bla blu') and we must insert the node
65 // list inbetween.
66 if ($search !== FALSE) {
67 array_splice($arg_list, $search + 1, 0, $node_list);
68 }
69 else {
70 $_SESSION['biblio_filter'] = array(array('search', rtrim($node_list, ','), $keys));
71 }
72 }
73 // Wrong query (too short, only negative words etc.). Warning has been issued.
74 else $_SESSION['biblio_filter'] = array();
75 }
76 }
77
78 $inline = in_array('inline', $arg_list);
79 $inline = in_array('profile', $arg_list)?'profile':$inline;
80
81 $query_info = biblio_build_query($arg_list);
82 if ($query_info['rss']['feed']){
83 biblio_filter_feed($query_info['query'], $query_info['query_terms'], $query_info['rss']);
84 }
85 else{
86 //$count = db_result(db_query($query_info['count_query'],$query_info['query_terms']));
87 $result = pager_query($query_info['query'], variable_get('biblio_rowsperpage', 25),0,$query_info['count_query'],$query_info['query_terms']);
88 return biblio_show_results($result, $query_info['sort_attrib'], $query_info['args'],$inline);
89 }
90
91 }
92 /*
93 * biblio_db_search builds the SQL query which will be used to
94 * select and order "biblio" type nodes. The query results are
95 * then passed to biblio_show_results for output
96 *
97 *
98 */
99 function biblio_build_query($arg_list) {
100 global $user, $db_type;
101 static $bcc; //biblio_contributor (bc) count , increase for every invocation
102 static $tcc; //term counter, increase for every invocation
103 if ( !isset( $bcc ) ) $bcc = 0;
104 if ( !isset( $tcc ) ) $tcc = 0;
105 $inline = $rss_info['feed'] = false;
106 $joins = array();
107 $selects = array();
108 $count_selects = array();
109 $count_limit = '';
110
111 $selects[] = "DISTINCT(n.nid)";
112 $count_selects[] = "DISTINCT(n.nid)";
113 //$selects[] = "n.*";
114 //$selects[] = "b.*";
115 $selects[] = "bt.name as biblio_type_name";
116
117 $joins[] = "left join {biblio} b on n.vid=b.vid ";
118 $joins[] = "inner join {biblio_types} bt on b.biblio_type=bt.tid ";
119
120 // POSIX regular expression matching, case insensitive
121 $match_op = ($db_type == 'pgsql') ? '~*' : 'RLIKE';
122 // The following is to be used to compare titles
123 // LOWER() is required for case insensitive sorting (at least, in PostgreSQL)
124 $sort_title =" CASE
125 WHEN SUBSTR(n.title,1,1)='\"' THEN LOWER(SUBSTR(n.title,2))
126 WHEN SUBSTR(n.title,1,1)='\'' THEN LOWER(SUBSTR(n.title,2))
127 WHEN SUBSTR(n.title,1,2)='A ' THEN LOWER(SUBSTR(n.title,3))
128 WHEN SUBSTR(n.title,1,3)='An ' THEN LOWER(SUBSTR(n.title,4))
129 WHEN SUBSTR(n.title,1,4)='The ' THEN LOWER(SUBSTR(n.title,5))
130 ELSE LOWER(n.title)
131 END ";
132
133 $limit = '';
134 if (variable_get('biblio_view_only_own', 0) ) {
135 $limit .= " AND n.uid = $user->uid ";
136 }
137
138 $sort_attrib = array("sort" => variable_get('biblio_sort', 'year'), 'order' => variable_get('biblio_order', 'DESC'));
139 $limits = null;
140
141 if (isset($_GET['order'])) {
142 $sort_attrib['order'] = ($_GET['order'] == 'desc') ? 'desc' : 'asc';
143 }
144 if (isset($_GET['sort'])) {
145 $sort_attrib['sort'] = check_plain($_GET['sort']);
146 }
147
148 switch ($sort_attrib['sort']) {
149 case 'type':
150 //$sortby = "ORDER BY bt.name %s, b.biblio_year DESC ";
151 $sortby = "ORDER BY bt.name %s, $sort_title";
152 break;
153 case 'title':
154 //$sortby = "ORDER BY SUBSTRING(n.title,1,3) %s, b.biblio_year DESC ";
155 $sortby = "ORDER BY $sort_title %s";
156 break;
157 case 'author':
158 $sortby = "ORDER BY bcd.lastname %s ";
159 $where['bc-rank'] = "bc.rank=0";
160 $where['bc-auth-category'] = "bc.auth_category=1";
161 $joins['bc'] = ' INNER JOIN {biblio_contributor} as bc on b.vid = bc.vid ';
162 $joins['bcd'] = ' JOIN {biblio_contributor_data} as bcd on bc.cid = bcd.cid ';
163 break;
164 case 'keyword': // added msh 070808
165 $sortby = "ORDER BY bkd.word %s ";
166 $joins['bk'] = ' JOIN {biblio_keyword} as bk on b.vid = bk.vid ';
167 $joins['bkd'] = ' JOIN {biblio_keyword_data} as bkd on bk.kid = bkd.kid ';
168 $selects[] = "bkd.word as biblio_keyword";
169 $count_selects[] = "bkd.word";
170 break;
171 case 'year':
172 default:
173 $sortby = "ORDER BY b.biblio_year %s, b.biblio_date %s";
174 } //end switch
175 if (!isset($_SESSION['biblio_filter']) || !is_array($_SESSION['biblio_filter'])) {
176 $_SESSION['biblio_filter'] = array();
177 }
178
179 $session = &$_SESSION['biblio_filter'];
180
181 if (!in_array('no_filters', $arg_list)) {
182 foreach ($session as $filter) {
183 $arg_list = array_merge($arg_list, $filter);
184 }
185 }
186
187 if (count($arg_list) ) {
188 $args = array();
189 while ($arg_list) {
190 $type = $arg_list[0];
191 array_shift($arg_list);
192 $operator = ($operator)?$operator:" AND "; //defaults to AND
193 switch ($type) {
194 case 'no_filters':
195 break;
196 case 'and':
197 $operator = " AND ";
198 break;
199 case 'or':
200 $operator = " OR ";
201 break;
202 case 'inline':
203 $inline = true;
204 break;
205 case 'rss.xml':
206 $rss_info['feed'] = true;
207 $count_limit = 'LIMIT '. variable_get('biblio_rss_number_of_entries', 10);
208 break;
209 case 'profile':
210 $inline = "profile";
211 break;
212 case 'cid':
213 case 'aid':
214 $bcc++;
215 $term = explode("?",array_shift($arg_list));
216 $joins[] = "inner join {biblio_contributor} as bc". $bcc ." on n.vid = bc". $bcc .".vid";
217 $where[] = "bc". $bcc .".cid = '%d' ";
218 $terms[] = db_escape_string($term[0]);
219 array_push($args, $type, $term[0]);
220 break;
221 case 'term':
222 case 'term_id':
223 $term = explode("?",array_shift($arg_list));
224 $joins[] = "inner join {term_node} as tn". $tcc ." on n.vid = tn".$tcc.".vid";
225 if ($type == 'term') {
226 $joins[] = "inner join {term_data} as td on tn". $tcc .".tid= td.tid";
227 $where[] = "td.name = '%s' ";
228 }elseif ($type == 'term_id') {
229 $where[] = "tn". $tcc .".tid = '%d' ";
230 }
231 $terms[] = db_escape_string($term[0]);
232 array_push($args, $type, $term[0]);
233 $tcc++;
234 break;
235 case 'tg':
236 $term = explode("?",array_shift($arg_list));
237 $where[] = "substring($sort_title,1 ,1)" . $match_op . " LOWER('%s')";
238 $terms[] = db_escape_string($term[0]);
239 array_push($args, $type, $term[0]);
240 $operator = NULL;
241 break;
242 case 'ag': //selects entries whoose authors firstname starts with the letter provided
243 $term = explode("?",array_shift($arg_list));
244 $where[] = " UPPER(substring(bcd.lastname,1,1)) = '%s' ";
245 //$where['bc-rank'] = "bc.rank=0";
246 $joins['bc'] = ' INNER JOIN {biblio_contributor} as bc on b.vid = bc.vid ';
247 $joins['bcd'] = ' JOIN {biblio_contributor_data} as bcd on bc.cid = bcd.cid ';
248 $terms[] = db_escape_string(strtoupper($term[0]));
249 array_push($args, $type, $term[0]);
250 $operator = NULL;
251 break;
252 case 'author':
253 $bcc++;
254 $term = explode("?",array_shift($arg_list));
255
256 if (is_numeric($term[0])){
257 $joins[] = "inner join {biblio_contributor} as bc". $bcc ." on n.vid = bc". $bcc .".vid";
258 //$where[] = "bc". $bcc .".cid = '%d' ";
259 //
260 $cids = db_query('SELECT cid FROM {biblio_contributor_data}
261 WHERE cid = %d OR aka = (SELECT aka FROM {biblio_contributor_data} WHERE cid = %d)'
262 ,$term[0],$term[0]);
263 while ($cid = db_fetch_object($cids) ){
264 $wr .= empty($wr)?'':' OR ';
265 $wr .= "bc". $bcc .".cid = $cid->cid ";
266 }
267
268 $where[] = (!empty($wr)) ? $wr : "bc". $bcc .".cid = -1 ";
269
270 // $where[] = 'bc'. $bcc .'.cid in ( (select cid from {biblio_contributor_data}
271 // where cid = %d
272 // or aka = %d
273 // or cid = (select aka from {biblio_contributor_data} where cid = %d)
274 // or aka = (select aka from {biblio_contributor_data} where cid = %d)
275 // and biblio_contributor_data.aka > 0)) ';
276 // $terms[] = db_escape_string($term[0]);
277 // $terms[] = db_escape_string($term[0]);
278 // $terms[] = db_escape_string($term[0]);
279 // $terms[] = db_escape_string($term[0]);
280 }else{
281 $where[] = " bcd". $bcc .'.name '. $match_op .' "[[:<:]]%s[[:>:]]" ';
282 $joins[] = " JOIN {biblio_contributor} as bc". $bcc ." on b.vid = bc". $bcc .".vid ";
283 $joins[] = " JOIN {biblio_contributor_data} as bcd". $bcc ." on bc". $bcc .".cid = bcd".$bcc .".cid ";
284 $terms[] = db_escape_string($term[0]);
285 $operator = NULL;
286 $rss_info['title'] = t("Publications by " . $term[0]);
287 $rss_info['description'] = t("These publications by %author are part of the works listed at %sitename", array('%author' => $term[0], '%sitename' => variable_get('site_name', 'Drupal')));
288 $rss_info['link'] = '/author/' . $term[0];
289 }
290 array_push($args, $type, $term[0]);
291 break;
292 case 'publisher':
293 $term = explode("?",array_shift($arg_list));
294 $where[] = "b.biblio_publisher ". $match_op ." '%s' ";
295 $terms[] = db_escape_string($term[0]);
296 array_push($args, $type, $term[0]);
297 $operator = NULL;
298 break;
299 case 'year':
300 $term = db_escape_string(array_shift($arg_list));
301 $where[] = "b.biblio_year=%d ";
302 //$limit .= " AND b.biblio_year=%d ";
303 $terms[] = (int)$term;
304 array_push($args, $type, (int)$term);
305 $operator = NULL;
306 break;
307 case 'uid':
308 $term = db_escape_string(array_shift($arg_list));
309 $where[] = "n.uid=%d ";
310 //$limit .= " AND b.biblio_year=%d ";
311 $terms[] = (int)$term;
312 array_push($args, $type, (int)$term);
313 $operator = NULL;
314 break;
315 case 'keyword':
316 $bkd++;
317 $term = explode("?",array_shift($arg_list));
318 if (is_numeric($term[0])){
319 $terms[] = db_escape_string($term[0]);
320 $joins[] = "inner join {biblio_keyword} as bk on n.vid = bk.vid";
321 //$joins[] = "inner join {biblio_keyword_data} as bkd on bk.kid= bkd.kid";
322 $where[] = "bk.kid = %d ";
323 }else{
324 $where[] = " bkd". $bkd .'.word '. $match_op .' "[[:<:]]%s[[:>:]]" ';
325 $joins[] = " JOIN {biblio_keyword} as bk". $bkd ." on b.vid = bk". $bkd .".vid ";
326 $joins[] = " JOIN {biblio_keyword_data} as bkd". $bkd ." on bk". $bkd .".kid = bkd".$bkd .".kid ";
327 $terms[] = db_escape_string($term[0]);
328 $operator = NULL;
329 $rss_info['title'] = t("Keyword " . $term[0]);
330 $rss_info['description'] = t("These publications, containing the keyword: %keyword, are part of the works listed at %sitename", array('%keyword' => $term[0], '%sitename' => variable_get('site_name', 'Drupal')));
331 $rss_info['link'] = '/keyword/' . $term[0];
332 }
333 array_push($args, $type, $term[0]);
334 $operator = NULL;
335 break;
336 case 'citekey':
337 $term = explode("?",array_shift($arg_list));
338 $terms[] = db_escape_string($term[0]);
339 $where[] = "b.biblio_citekey= '%s' ";
340 array_push($args, $type, $term[0]);
341 $operator = NULL;
342 break;
343 case 'type':
344 $term = db_escape_string(array_shift($arg_list));
345 $where[] = "b.biblio_type=%d ";
346 //$limit .= $operator. "b.biblio_type=%d ";
347 $terms[] = (int)$term;
348 array_push($args, $type, (int)$term);
349 $operator = NULL;
350 break;
351 case 'order':
352 $term = (db_escape_string(array_shift($arg_list)) == 'desc')?'desc':'asc';
353 $sort_attrib['order'] = $term;
354 array_push($args, $type, $term);
355 break;
356 case 'sort':
357 $term = db_escape_string(array_shift($arg_list));
358 $sort_attrib['sort'] = $term;
359 array_push($args, $type, $term);
360 switch ($term) {
361 case 'type':
362 $sortby = "ORDER BY bt.name %s, b.biblio_year DESC ";
363 break;
364 case 'title':
365 $sortby = "ORDER BY $sort_title %s, b.biblio_year DESC ";
366 break;
367 case 'year':
368 default:
369 $sortby = "ORDER BY b.biblio_year %s, b.biblio_date %s, $sort_title ASC, bt.name ASC ";
370 } //end switch
371 break;
372 case 'search':
373 $term = explode("?",array_shift($arg_list));
374 $result_nids = split(',', $term[0]);
375 $where[] = "n.nid in (".db_placeholders($result_nids).")";
376 foreach ($result_nids as $result_nid) {
377 $terms[] = db_escape_string($result_nid);
378 array_push($args, $type, $result_nid);
379 }
380 // Save search keyword to show in the filter list.
381 $term = array_shift($arg_list);
382 array_push($args, $type, $term);
383 $operator = NULL;
384 break;
385 default:
386 $fields = biblio_get_db_fields();
387 $term = explode("?",array_shift($arg_list));
388 if (in_array("biblio_$type",$fields))
389 {
390 $where[] = "b.biblio_$type ".$match_op ." '%s' ";
391 $terms[] = db_escape_string($term[0]);
392 array_push($args, $type, $term[0]);
393 $operator = NULL;
394 }
395 break;
396 }
397 }
398 }
399 $where[] = "n.type='biblio' ";
400 if ($user->uid != 1 ) {
401 $where[] = 'n.status = 1 ';
402 }//show only published entries to everyone except admin
403
404 $select = implode(', ', $selects);
405 $count_select = implode(', ', $count_selects);
406 $join = implode(' ', $joins);
407
408 $where_clause = count($where) > 1 ? '('. implode(') AND (', $where) .')': $where[0];
409
410 $query = db_rewrite_sql("SELECT $select FROM {node} n $join WHERE $where_clause $limit $sortby $count_limit");
411 $count_query = db_rewrite_sql("SELECT COUNT($count_select) FROM {node} n $join WHERE $where_clause $limit $count_limit");
412 $_SESSION['last_biblio_query'] = $query;
413 $terms[] = $sort_attrib['order']; // this is either asc or desc to be inserted into the first term of the ORDER clause
414 if($sort_attrib['sort'] == 'year') $terms[] = $sort_attrib['order']; // we need any extra order term when sorting by year since there are to date terms biblio_year and biblio_date
415 $_SESSION['last_biblio_query_terms'] = $terms;
416
417 return (array('query' => $query,
418 'query_terms' => $terms,
419 'count_query' => $count_query,
420 'args' => $args,
421 'sort_attrib' => $sort_attrib,
422 'rss' => $rss_info
423 ));
424
425 }
426
427 /**
428 * biblio_show_results takes the query results from biblio_db_search and
429 * adds some controls to the page then loops through the results applying
430 * the selected style to each entry
431 *
432 * @param $result
433 * @param $count
434 * @param $attrib
435 * @param $args
436 * @param $inline
437 * @return unknown_type
438 */
439 function biblio_show_results($result, $attrib = array("sort" => 'year', 'order' => 'DESC'), $args = null,$inline=false) {
440 global $pager_total_items;
441 module_load_include('inc','biblio','biblio.contributors');
442 module_load_include('inc','biblio','biblio.keywords');
443
444 $base = variable_get('biblio_base', 'biblio');
445 $style = biblio_get_style();
446 if ($inline === 'profile') {
447 $profile = true;
448 $inline = false;
449 }
450 if (module_exists('popups')){
451 popups_add_popups();
452 }
453 if (!$inline && !$profile) {
454
455 if (variable_get('biblio_rss', 0)) {
456 drupal_set_html_head('<link rel="alternate" type="application/rss+xml" title="'.variable_get('site_name', 'Drupal').' RSS" href="'.url("$base/rss.xml").'" />');
457 }
458 // Search box. Has same permissions as the filter tab.
459 $content .= '<div id="biblio-header" class="clear-block">';
460 if (variable_get('biblio_search',0) && user_access('show filter tab')) {
461 $content .= drupal_get_form('biblio_search_form');
462 }
463 if ( biblio_access('export')) {
464 $content .= '<div class="biblio-export">'. theme('biblio_export_links'). '</div>';
465 }else{
466 $content .= '<div class="biblio-export">'.t('Found @count results', array('@count' => $pager_total_items[0])) .'</div><br />';
467 }
468 // Add some links to the top of the page to change the sorting/ordering...
469 if (user_access('show sort links')) {
470 $content .= _biblio_sort_tabs($attrib, $options);
471 }
472 $content .= '</div>';
473
474 if (user_access('show filter tab')) {
475 $content .= _biblio_filter_info_line($args);
476 }
477 }
478
479 if ($inline === true) print '<div class="biblio-inline">';
480
481 if ($_GET['sort'] == 'title' || $_GET['sort'] == 'author') {
482 if (strpos($_GET['q'],'ag') || strpos($_GET['q'],'tg')) {
483 $value = substr($_GET['q'],strrpos($_GET['q'],'/')+1);
484 }
485 $content .= theme(biblio_alpha_line,$_GET['sort'],$value);
486 }
487
488 $count = 0;
489
490 while ($node = db_fetch_object($result)) {
491 $count++;
492 $node = node_load($node->nid);
493
494 if (variable_get('biblio_hide_bibtex_braces', 0)) $node->title = biblio_remove_brace($node->title);
495 if (variable_get('biblio_fix_isi_links', 0)) biblio_fix_isi_links($node);
496
497
498 // output separator bar if needed
499 $content .= _biblio_category_separator_bar($attrib, $node);
500
501 $inline_links = ($inline && variable_get('biblio_inlinemode_in_links',0)) ? true : false;
502
503 $content .= theme('biblio_entry', $node,$base,$style,$inline_links);
504 } //end while
505 if ($count) $content .= '</div><!-- end category-section -->';
506 $content .= theme('pager', 0, variable_get('biblio_rowsperpage', 25));
507 if ($count == 0) {
508 $content .= "<h3>".t("No items found")."</h3>";
509 if (strstr($content, "Filters:")) {
510 $content .= t('!modify_link or !remove_link your filters and try again.', array('!modify_link' => l(t('Modify'),"$base/filter"), '!remove_link' => l(t('remove'),"$base/filter/clear")));
511 }
512 }
513 if ($profile === true) return $content;
514 if ($inline === true) return $content . "</div>";
515 if ($inline === false) {
516 $base_title = variable_get('biblio_base_title', 'Biblio');
517 drupal_set_title($base_title);
518 return $content;
519 }
520
521 }
522
523 function _biblio_sort_tabs($attrib, $options) {
524 global $base_path;
525 $content = '';
526 $sort_links = array();
527 $tabs = variable_get('biblio_sort_tabs_style', 0);
528 $order = ($attrib['order'] == "desc" || $attrib['order'] == "DESC")?"asc":"desc";
529 $cur_order = ($attrib['order'] == "desc" || $attrib['order'] == "DESC")?"desc":"asc";
530 $path = drupal_get_path('module','biblio');
531 $order_arrow = ($order == 'asc') ? '<img src ="'. $base_path . $path. '/arrow-asc.png" alt =" (Desc)" />':'<img src ="'. $base_path . $path .'/arrow-desc.png" alt = " (Asc)" />';
532 $sort_links = variable_get('biblio_sort_tabs', array('author'=>'author', 'title'=>'title', 'type'=>'type', 'year'=>'year', 'keyword'=>'keyword'));
533 ksort($sort_links);
534 $content .= $tabs ? '<ul class="tabs secondary ">':'';
535
536 foreach($sort_links as $key => $link) {
537 $sort_links['options'] = array();
538 $sort_links['options']['attributes'] = array("title"=>t("Click a second time to reverse the sort order"));
539 $sort_links['options']['html'] = TRUE;
540 $title = t(ucfirst($link));
541 if ($key === $link && $link == $attrib['sort']) {
542 $sort_links['options']['query'] = "sort=$link&order=$order";
543 $sort_links['class'] = 'class="active"';
544 $sort_links['pfx'] = ' [ ';
545 $sort_links['sfx'] = '] ';
546 $sort_links['arrow'] = $order_arrow;
547 $content .= _biblio_sort_tab($sort_links, $title, $tabs );
548
549 }
550 elseif ($key === $link ) {
551 $sort_links['options']['query'] = "sort=$link&order=$cur_order";
552 $sort_links['class'] = '';
553 $sort_links['pfx'] = ' ';
554 $sort_links['sfx'] = ' ';
555 $sort_links['arrow'] = '';
556 $content .= _biblio_sort_tab($sort_links, t("!title", array('!title' => $title)), $tabs );
557 }
558
559 }
560 if (!$tabs) $content = t('Sort by').': '.$content;
561 $content .= $tabs ? '</ul>':'';
562
563 return $content;
564 }
565
566 function _biblio_sort_tab($options, $title, $tabs = FALSE) {
567 if ($tabs) {
568 $content .= '<li '.$options['class'] .'>';
569 $content .= '<a title="'.$options['options']['attributes']['title'].'"';
570 $content .= 'href="'. url($_GET['q']).'&amp;'.$options['options']['query'].'"';
571 $content .= $options['class'] .'>';
572 $content .= '<span class="a"><span class="b">'. $title .$options['arrow'].'</span></span></a></li>';
573 } else {
574 $content .= $options['pfx'].l($title ,$_GET['q'],$options['options']).$options['arrow'].$options['sfx'];
575 }
576 return $content;
577 }
578
579 function _biblio_filter_info_line($args) {
580 $content = '';
581 $base = variable_get('biblio_base', 'biblio');
582 $session = &$_SESSION['biblio_filter'];
583 // if there are any filters in place, print them at the top of the list
584 if (count($args)) {
585 $i = 0;
586 while ($args) {
587 $type = $args[0];
588 array_shift($args);
589 $value = db_escape_string($args[0]);
590 if ($type == 'search') {
591 $search_content = array_shift($args);
592 continue;
593 }
594 if ($type == 'term_id') {
595 $term = taxonomy_get_term($value);
596 $value = $term->name;
597 $type = t("Taxonomy term");
598 }
599 if ($type == 'keyword') {
600 require_once(drupal_get_path('module', 'biblio') .'/biblio.keywords.inc');
601 if (is_numeric($value)) {
602 $term = biblio_get_keyword_by_id($value);
603 $value = $term->word;
604 }
605 $type = t("Keyword");
606 }
607 if ($type == 'uid' ) {
608 $user = user_load($value);
609 $value = $user->name;
610 $type = t("Drupal user");
611 }
612 if ($type == 'aid' || ($type == 'author' && is_numeric($value))) {
613 $author = biblio_get_contributor($value);
614 $value = $author->name;
615 $type = t("Author");
616 }
617 if ($type == 'ag' ) {
618 //return;
619 $type = t("First letter of last name");
620 }
621 if ($type == 'tg' ) {
622 //return;
623 $type = t("First letter of title");
624 }
625 if ($type == 'type' && $value > 0) {
626 if (($pub_type = db_fetch_object(db_query('SELECT t.* FROM {biblio_types} as t WHERE t.tid=%d', $value)))) {
627 $value = drupal_ucfirst($pub_type->name);
628 $type = t("Type");
629 }
630 }
631 array_shift($args);
632 $params = array('%a' => check_plain(ucwords($type)) , '%b' => check_plain($value) );
633 $filtercontent .= ($i++ ? t('<em> and</em> <strong>%a</strong> is <strong>%b</strong>', $params) : t('<strong>%a</strong> is <strong>%b</strong>', $params)) ;
634 }
635 if ($search_content) {
636 $content .= '<div class="biblio-current-filters"><b>'.t('Search results for ').'</b>';
637 $content .= '<em>'. check_plain($search_content) .'</em>';
638 if ($filtercontent) {
639 $content .= '<br><b>'.t('Filters').': </b>';
640 }
641 }
642 else {
643 $content .= '<div class="biblio-current-filters"><b>'.t('Filters').': </b>';
644 }
645 $content .= $filtercontent;
646
647 $link_options = array();
648 if (isset($_GET['sort'])) {
649 $link_options['query'] .= "sort=" . $_GET['sort'];
650 }
651 if (isset($_GET['order'])) {
652 $link_options['query'] .= $link_options['query'] ? "&" : "" ;
653 $link_options['query'] .= "order=" . $_GET['order'];
654 }
655
656 if ($search_content) {
657 $content .= '&nbsp;&nbsp;'.l('['.t('Reset Search').']',"$base/filter/clear", $link_options);
658 } else {
659 $content .= '&nbsp;&nbsp;'.l('['.t('Clear All Filters').']',"$base/filter/clear", $link_options);
660 }
661 $content .= '</div>';
662 }
663
664 return $content;
665 }
666
667 function _biblio_category_separator_bar($attrib, $node) {
668 static $_text = '';
669
670 switch ($attrib['sort']) {
671 case 'title':
672 $first = drupal_substr(drupal_ucfirst(ltrim($node->title)), 0, 1);
673 if (drupal_substr(drupal_ucfirst(ltrim($node->title)), 0, 1) == '"' ) $first = drupal_ucfirst(drupal_substr(ltrim($node->title), 1, 1));
674 if (drupal_substr(drupal_ucfirst(ltrim($node->title)), 0, 1) == "'" ) $first = drupal_ucfirst(drupal_substr(ltrim($node->title), 1, 1));
675 if (drupal_substr(drupal_ucfirst(ltrim($node->title)), 0, 2) == "A " ) $first = drupal_ucfirst(drupal_substr(ltrim($node->title), 2, 1));
676 if (drupal_substr(drupal_ucfirst(ltrim($node->title)), 0, 3) == "An " ) $first = drupal_ucfirst(drupal_substr(ltrim($node->title), 3, 1));
677 if (drupal_substr(drupal_ucfirst(ltrim($node->title)), 0, 4) == "The " ) $first = drupal_ucfirst(drupal_substr(ltrim($node->title), 4, 1));
678 if ( $first != $_text) {
679 if ($_text != '' ) {
680 $content .= theme_biblio_end_category_section();
681 }
682 $_text = $first ;
683 $content .= theme_biblio_separator_bar($_text);
684 }
685 break;
686 case 'author':
687 if ( (isset($node->biblio_contributors[1][0]['lastname'])) &&
688 (drupal_substr(drupal_ucfirst(ltrim($node->biblio_contributors[1][0]['lastname'])), 0, 1) != $_text))
689 {
690 if ($_text != '' ) {
691 $content .= theme_biblio_end_category_section();
692 }
693 $_text = drupal_substr(drupal_ucfirst(ltrim($node->biblio_contributors[1][0]['lastname'])), 0, 1) ;
694 $content .= theme_biblio_separator_bar($_text);
695 }
696 break;
697 case 'type':
698 if ($node->biblio_type_name != $_text) {
699 if ($_text != '' ) {
700 $content .= theme_biblio_end_category_section();
701 }
702 $_text = $node->biblio_type_name;
703 // $name = db_result(db_query("SELECT name FROM {biblio_types} as t where t.tid=%d", $node->biblio_type)) ;
704 $content .= theme_biblio_separator_bar($_text);
705 }
706 break;
707 case 'keyword': // added msh 08 aug 07
708 // $kw = array_shift($node->biblio_keyword);
709 $tok = $node->biblio_keyword;
710 if (empty($tok)) {
711 $tok = t("No Keywords");
712 }
713 if ($tok != $_text) {
714 if ($_text != '' ) {
715 $content .= theme_biblio_end_category_section();
716 }
717 $_text = $tok;
718 if ($_text != '') {
719 $content .= theme_biblio_separator_bar($_text);
720 }
721 }
722 break;
723 case 'year':
724 default:
725 if ($node->biblio_year != $_text) {
726 if ($_text != '' ) {
727 $content .= theme_biblio_end_category_section();
728 }
729 $_text = $node->biblio_year;
730 $content .= theme_biblio_separator_bar($_text);
731 }
732 } //end switch
733 return $content;
734 }
735 function theme_biblio_separator_bar($text) {
736 $content .= "\n".'<div class="biblio-separator-bar">' . check_plain($text) . "</div>\n";
737 $content .= "\n".'<div class ="biblio-category-section">';
738 return $content;
739 }
740
741 function theme_biblio_end_category_section() {
742 return "\n</div><!-- end category-section -->";
743 }
744
745 /**
746 * Add a search field on the main biblio page.
747 */
748 /**
749 * @param $form_state
750 * @return unknown_type
751 */
752 function biblio_search_form(&$form_state) {
753 $form['biblio_search'] = array(
754 '#prefix' => '<div class="container-inline biblio-search clear-block">',
755 '#suffix' => '</div>',
756 );
757 $form['biblio_search']['keys'] = array(
758 '#type' => 'textfield',
759 '#title' => '',
760 '#default_value' => '',
761 '#size' => 25,
762 '#maxlength' => 255,
763 );
764 $button_text = variable_get('biblio_search_button_text', 'Biblio search');
765 $form['biblio_search']['submit'] = array('#type' => 'submit', '#value' => t($button_text));
766 return $form;
767 }
768
769 /**
770 * Build the query following the do_search algorithm in search.module.
771 * Unfortunately we cannot reuse anything from do_search as everything
772 * is hard-coded :-(
773 * @param $keys
774 */
775 function biblio_build_search_query($keys = '') {
776 if ($keys != '') {
777 $query = search_parse_query($keys);
778 if ($query[2] == '') {
779 form_set_error('keys', t('You must include at least one positive keyword with @count characters or more.', array('@count' => variable_get('minimum_word_size', 3))));
780 return FALSE;
781 }
782 if ($query === NULL || $query[0] == '') return FALSE;
783
784 $where = '('.$query[2].')';
785 $args = $query[3];
786 if (!$query[5]) {
787 $where .= " AND ($query[0])";
788 $args = array_merge($args, $query[1]);
789 $join = " INNER JOIN {search_dataset} d ON i.sid = d.sid AND i.type = d.type";
790 }
791 // The COUNT ensures that we get only nodes where "term1 AND term2"
792 // match as we demand 2 matches. Note that this doesn't work when
793 // using the partial word search patch.
794 $args[] =$query[4];
795
796 $query = "SELECT distinct(i.sid) FROM {search_index} i
797 INNER JOIN {node} n ON n.nid = i.sid
798 $join
799 WHERE n.status = 1 AND (n.type = 'biblio')
800 AND $where
801 AND i.type = 'node'
802 GROUP BY i.type, i.sid HAVING COUNT(*) >= %d";
803 return db_query(db_rewrite_sql($query), $args);
804 }
805 return FALSE;
806 }
807
808
809 /**
810 * When we submit a search, we revoke all current filters since search
811 * and filtering are considered two different concepts things* conceptually.
812 *
813 * But we store the results as a filter (which is just a list of node ids that
814 * matched the search request) so that we can reorder or export the search
815 * results like with any other filter. The filter has three components:
816 * ('search',<list of node ids>,<search keywords>).
817 * The second component, the filter value, is empty when submitting keywords.
818 * In biblio_db_search we fill the second component with the list of nids
819 * matching our keywords, as returned by node_search. We store the keywords
820 * only for showing them in "Search results for <keywords>".
821 */
822 /**
823 * @param $form
824 * @param $form_state
825 * @return unknown_type
826 */
827 function biblio_search_form_submit($form, &$form_state) {
828 $keys = $form_state['values']['keys'];
829 if ($keys != '') {
830 $_SESSION['biblio_filter'] = array(array('search','',$keys));
831 $base = variable_get('biblio_base', 'biblio');
832 $form_state['redirect'] = $base;
833 }
834 else {
835 // No keywords. Remove former search keys if any. Leaves other filters intact.
836 if (_get_biblio_search_filter()){
837 $_SESSION['biblio_filter'] = array();
838 }
839 }
840 }
841
842 /**
843 * @param $arg
844 * @return unknown_type
845 */
846 function _get_biblio_search_filter($arg = 'keys') {
847 if (variable_get('biblio_search',0) &&
848 is_array($_SESSION['biblio_filter']) &&
849 is_array($_SESSION['biblio_filter'][0]) &&
850 in_array('search',$_SESSION['biblio_filter'][0])
851 ){
852 switch ($arg) {
853 case 'keys': return $_SESSION['biblio_filter'][0][2]; break;
854 case 'nodelist': return $_SESSION['biblio_filter'][0][1]; break;
855 }
856 }
857 }
858
859
860 function _get_biblio_filters() {
861
862 $fields = " b.biblio_year, t.name , t.tid ";
863 $order = " b.biblio_year DESC";
864 $taxo_fields = "td.name as termname,td.tid as taxid, v.name as vocab_name";
865 $taxo_order = "vocab_name ASC, termname ASC";
866 $table = "{node} as n inner join {biblio} as b on n.vid=b.vid ";
867 $join = "left join {biblio_types} as t on b.biblio_type = t.tid";
868 $taxo_join = array("inner join {term_node} as tn on n.vid = tn.vid",
869 "left join {term_data} as td on tn.tid= td.tid",
870 "left join {vocabulary} as v on v.vid= td.vid");
871
872 $taxo_joins = implode(' ',$taxo_join);
873
874 $result = db_query("SELECT $fields FROM $table $join ORDER BY $order");
875 $authors = db_query("SELECT firstname, initials, lastname, cid FROM {biblio_contributor_data} ORDER BY lastname ASC");
876 $keywords = db_query("SELECT word, kid FROM {biblio_keyword_data} ORDER BY word ASC");
877 $taxoresult = db_query("SELECT $taxo_fields FROM $table $taxo_joins ORDER BY $taxo_order");
878
879 while ($option = db_fetch_object($result)) {
880 if (isset ($option->biblio_year)) {
881 $option->biblio_year = _biblio_text_year($option->biblio_year);
882 }
883 $pub_years["$option->biblio_year"] = $option->biblio_year;
884 $pub_type["$option->tid"] = $option->name;
885 }
886
887 while($auth = db_fetch_object($authors)) {
888 $pub_authors[$auth->cid] = $auth->lastname .((!empty($auth->firstname) || !empty($auth->initials))?', '.$auth->firstname.' '.$auth->initials :'');
889 }
890 while($keyword = db_fetch_object($keywords)) {
891 $pub_keywords[$keyword->kid] = $keyword->word;
892 }
893 while ($tax = db_fetch_object($taxoresult)) {
894 $pub_taxo["$tax->taxid"] = "$tax->vocab_name - $tax->termname";
895 }
896 $author_select = isset($pub_authors) ? array('title' => t('Author'), 'options' => $pub_authors) : null;
897 $years_select = isset($pub_years) ? array('title' => t('Year'), 'options' => array_unique($pub_years)) : null;
898 $type_select = isset($pub_type) ? array('title' => t('Type'), 'options' => array_unique($pub_type)) : null;
899 $tax_select = isset($pub_taxo) ? array('title' => t('Term'),'options' => array_unique($pub_taxo)) : null;
900 $keyword_select = isset($pub_keywords) ? array('title' => t('Keyword'), 'options' => $pub_keywords) : null;
901
902 $filters = array(
903 'author' => $author_select,
904 'type' => $type_select,
905 'term_id' => $tax_select,
906 'year' => $years_select,
907 'keyword' => $keyword_select,
908 );
909
910 return $filters;
911 }
912
913 /**
914 * @return unknown_type
915 */
916 function biblio_form_filter() {
917 // No longer use &$_SESSION so that we can alter $session in case of the search filter.
918 $session = $_SESSION['biblio_filter'];
919 $session = is_array($session) ? $session : array();
920 $filters = _get_biblio_filters();
921
922 $i = 0;
923 $form['filters'] = array('#type' => 'fieldset',
924 '#title' => t('Show only items where'),
925 '#theme' => 'biblio_filters',
926 );
927 foreach ($session as $filter) {
928 list($type, $value) = $filter;
929 // Don't show the search filter. Reset $session because of the $count(session) below.
930 if ($type == 'search') {
931 $session = array ();
932 break;
933 }
934 if ($type == 'category') {
935 // Load term name from DB rather than search and parse options array.
936 $value = module_invoke('taxonomy', 'get_term', $value);
937 $value = $value->name;
938 }else {
939 $value = $filters[$type]['options'][$value];
940 }
941 $string = ($i++ ? '<em>and</em> where <strong>%a</strong> is <strong>%b</strong>' : '<strong>%a</strong> is <strong>%b</strong>');
942 $form['filters']['current'][] = array('#value' => t($string, array('%a' => $filters[$type]['title'] , '%b' => $value)));
943 }
944
945 foreach ($filters as $key => $filter) {
946 if (count ($filter['options'])) {
947 $names[$key] = $filter['title'];
948 $form['filters']['status'][$key] = array('#type' => 'select', '#options' => $filter['options']);
949 }
950 }
951
952 $form['filters']['filter'] = array('#type' => 'radios', '#options' => $names, '#default_value' => 'author');
953 $form['filters']['buttons']['submit'] = array('#type' => 'submit', '#value' => (count($session) ? t('Refine') : t('Filter')));
954 if (count($session) && $type != 'search') {
955 $form['filters']['buttons']['undo'] = array('#type' => 'submit', '#value' => t('Undo'));
956 $form['filters']['buttons']['reset'] = array('#type' => 'submit', '#value' => t('Reset'));
957 }
958
959 return $form;
960 }
961
962 /**
963 * @param $form
964 * @param $form_state
965 * @return unknown_type
966 */
967 function biblio_form_filter_submit($form, &$form_state) {
968 // If the search filter was set, remove it now.
969 if(_get_biblio_search_filter()){
970 $_SESSION['biblio_filter'] = array ();
971 }
972 $op = $form_state['values']['op'];
973 $filters = _get_biblio_filters();
974 switch ($op) {
975 case t('Filter'):
976 case t('Refine'):
977 if (isset($form_state['values']['filter'])) {
978 $filter = $form_state['values']['filter'];
979
980 // Flatten the options array to accommodate hierarchical/nested options.
981 if (isset($filters[$filter]['options'])) {
982 $flat_options = form_options_flatten($filters[$filter]['options']);
983 }
984
985 if (isset($flat_options[$form_state['values'][$filter]]) ) {
986 $_SESSION['biblio_filter'][] = array($filter, $form_state['values'][$filter]);
987 $base = variable_get('biblio_base', 'biblio');
988 drupal_goto($base);
989
990 }
991 }
992 break;
993 case t('Undo'):
994 array_pop($_SESSION['biblio_filter']);
995 break;
996 case t('Reset'):
997 $_SESSION['biblio_filter'] = array();
998 break;
999 }
1000 }
1001
1002 /**
1003 * @param $user
1004 * @param $profile
1005 * @return unknown_type
1006 */
1007 function biblio_get_user_pubs($user, $profile='', $nofilters=''){
1008 if (isset($user->biblio_contributor_id) && $user->biblio_contributor_id > 0 ){
1009 $pubs = biblio_db_search('author', $user->biblio_contributor_id, $profile, $nofilters);
1010 }else{
1011 $pubs = biblio_db_search