Project

General

Profile

Download (29.2 KB) Statistics
| Branch: | Tag: | Revision:
1 6657531f Andreas Kohlbecker
<?php
2
/**
3
 * @file
4
 * Search related functions.
5
 */
6
7 a6ae799b Andreas Kohlbecker
define("SESSION_KEY_SEARCH_REGISTRATION_FILTER", "SESSION_KEY_SEARCH_REGISTRATION_FILTER");
8
9 6657531f Andreas Kohlbecker
/**
10
 * Returns a Drupal path to a search form for a CDM webservice.
11
 *
12
 * For a given CDM webservice end-point, the drupal page path to the
13
 * according search form is returned.
14
 * cdm webservice end points are defined in constant variables like:
15
 * <code>CDM_WS_PORTAL_TAXON_FIND</code> and
16
 * <code>CDM_WS_PORTAL_TAXON_FINDBY_DESCRIPTIONELEMENT_FULLTEXT</code>
17
 *
18
 * @param string $ws_endpoint
19
 *   The cdm webservice endpoint for which to find the search form path.
20
 *
21
 * @return string
22
 *   The Drupal path found.
23
 */
24
function cdm_dataportal_search_form_path_for_ws($ws_endpoint) {
25
  static $form_ws_map = array(
26
    CDM_WS_PORTAL_TAXON_FIND => "cdm_dataportal/search",
27 dc435632 Andreas Kohlbecker
    CDM_WS_PORTAL_TAXON_SEARCH => "cdm_dataportal/search",
28 6657531f Andreas Kohlbecker
    CDM_WS_PORTAL_TAXON_FINDBY_DESCRIPTIONELEMENT_FULLTEXT => "cdm_dataportal/search/taxon_by_description",
29
  );
30
  return $form_ws_map[$ws_endpoint];
31
}
32
33
/**
34
 * Prepares a form array for a general purpose search form.
35
 *
36
 * The form is used for general purpose search functionality in the
37 103a1463 Andreas Kohlbecker
 * dataportal. The form returned is populated with all necessary fields
38 6657531f Andreas Kohlbecker
 * for internal processing and has the textfield element $form['query']
39
 * which holds the query term.
40
 *
41
 * @param string $action_path
42
 *   The Drupal path to be put into the action url to which the form will
43
 *   be submitted.
44
 * @param string $search_webservice
45
 *   The cdm-remote webservice to be used, valid values are defined by
46
 *   the constants: FIXME.
47
 * @param string $query_field_default_value
48 632a697a Andreas Kohlbecker
 *   A default text for the query field
49 6657531f Andreas Kohlbecker
 * @param string $query_field_description
50 632a697a Andreas Kohlbecker
 *   The description text for the query field
51 6657531f Andreas Kohlbecker
 *
52
 * @return array
53
 *   The prepared form array.
54
 */
55 24797d7f Andreas Kohlbecker
function cdm_dataportal_search_form_prepare($action_path, $search_webservice, $query_field_default_value, $query_field_description) {
56 2d0d855a Andreas Kohlbecker
57
58 6657531f Andreas Kohlbecker
  $form['#method'] = 'get';
59
  $form['#action'] = url($action_path, array(
60
    'absolute' => TRUE,
61
  ));
62
63
  $form['ws'] = array(
64
    '#type' => 'hidden',
65
    '#value' => $search_webservice,
66
    '#name' => 'ws',
67
  );
68
69
  $form['query'] = array(
70
    '#weight' => 0,
71
    '#type' => 'textfield',
72
    '#size' => 68,
73 632a697a Andreas Kohlbecker
    // This causes the description to display also when hovering over
74 2d0d855a Andreas Kohlbecker
    // the textfield.
75
    // This is wanted behaviour for the simple seach but could
76 632a697a Andreas Kohlbecker
    // be disabled for the advances search.
77 6657531f Andreas Kohlbecker
    '#attributes' => array(
78
      'title' => $query_field_description,
79
    ),
80
    '#description' => $query_field_description,
81
    '#value' => $query_field_default_value,
82
    // '#description' => $query_field_description,
83
  );
84 023c4a03 Patrick Plitzner
  if(variable_get(SIMPLE_SEARCH_AUTO_SUGGEST)){
85 24f57e45 Patrick Plitzner
      $form['query']['#autocomplete_path'] = 'cdm_dataportal/taxon/autosuggest////';
86 35bea66c Patrick Plitzner
  }
87 6657531f Andreas Kohlbecker
88 93ae67cc Patrick Plitzner
    $form['search'] = array(
89 6657531f Andreas Kohlbecker
    '#weight' => 3,
90
    '#tree' => TRUE,
91 7b4c053d Andreas Kohlbecker
    // '#type' => $advanced_form ? 'fieldset': 'hidden',
92 6657531f Andreas Kohlbecker
    '#title' => t('Options'),
93
  );
94
95
  // Clean URL get forms breaks if we don't give it a 'q'.
96
  if (!(bool) variable_get('clean_url', '0')) {
97
    $form['search']['q'] = array(
98
      '#type' => 'hidden',
99
      '#value' => $action_path,
100
      '#name' => 'q',
101
    );
102
  }
103
104
  $form['submit'] = array(
105
    '#weight' => 5,
106
    '#type' => 'submit',
107
    '#name' => '',
108
    '#value' => t('Search'),
109
  );
110
111
  return $form;
112
}
113
114 24f57e45 Patrick Plitzner
function cdm_dataportal_taxon_autosuggest($classificationUuid = NULL, $areaUuid = NULL, $status = NULL, $string) {
115 93ae67cc Patrick Plitzner
  $matches = array();
116
117
  $queryParams = array();
118 04a1d647 Patrick Plitzner
  $queryParams['query'] = $string.'*';
119 24f57e45 Patrick Plitzner
  if((is_null($classificationUuid) || $classificationUuid=='') && isset($_SESSION['cdm']['taxonomictree_uuid'])){
120
    $classificationUuid = $_SESSION['cdm']['taxonomictree_uuid'];// if no classification uuid is set use the current one
121
  }
122
  if($classificationUuid){
123
    $queryParams['classificationUuid'] = $classificationUuid;
124 04a1d647 Patrick Plitzner
  }
125
  if($areaUuid){
126
    $queryParams['area'] = $areaUuid;
127
  }
128
  if($status){
129
    $queryParams['status'] = $status ;
130
  }
131 93ae67cc Patrick Plitzner
  $queryParams['pageNumber'] = '0';
132 04a1d647 Patrick Plitzner
  $queryParams['pageSize'] = '10';
133 93ae67cc Patrick Plitzner
  $queryParams['doTaxa'] = true;
134
  $queryParams['doSynonyms'] = true;
135
  $queryParams['doMisappliedNames'] = true;
136
  $queryParams['doTaxaByCommonNames'] = true;
137
138
  $search_results = cdm_ws_get(CDM_WS_TAXON_SEARCH, NULL, queryString($queryParams));
139
  foreach($search_results->records as $record){
140
      $titleCache = $record->entity->titleCache;
141 01fff74a Andreas Kohlbecker
      preg_match('/(.*) sec.*/', $titleCache, $trimmedTitle); //remove sec reference
142 93ae67cc Patrick Plitzner
      $trimmedTitle = trim($trimmedTitle[1]);
143 f35d3f4a Patrick Plitzner
      $matches[$trimmedTitle] = check_plain($trimmedTitle);
144 93ae67cc Patrick Plitzner
  }
145
  drupal_json_output($matches);
146
}
147
148
149
  /**
150 dbf4b8a8 Andreas Kohlbecker
 * Creates a search form for searching on taxa.
151
 *
152 7b4c053d Andreas Kohlbecker
 * If advanced $advanced_form id TRUE the form will offer additional choices
153 dbf4b8a8 Andreas Kohlbecker
 *
154 73874c48 Andreas Kohlbecker
 * @param array $form
155 7b4c053d Andreas Kohlbecker
 *   A drupal form array
156 73874c48 Andreas Kohlbecker
 * @param array $form_state
157 7b4c053d Andreas Kohlbecker
 *   The drupal form state passed as reference
158
 * @param bool $advanced_form
159 73874c48 Andreas Kohlbecker
 *   default is FALSE
160 7b4c053d Andreas Kohlbecker
 * @param bool $classification_select
161 01fff74a Andreas Kohlbecker
 *   set TRUE to offer a classification selector in the form - default is FALSE
162 73874c48 Andreas Kohlbecker
 *   if only available in the advanced mode
163 dbf4b8a8 Andreas Kohlbecker
 *
164 7b4c053d Andreas Kohlbecker
 * @return array
165 dbf4b8a8 Andreas Kohlbecker
 *   the form array
166 6657531f Andreas Kohlbecker
 */
167 7b4c053d Andreas Kohlbecker
function cdm_dataportal_search_taxon_form($form, &$form_state, $advanced_form = FALSE, $classification_select = TRUE) {
168 6657531f Andreas Kohlbecker
169
  $query_field_default_value = (isset($_SESSION['cdm']['search']['query']) ? $_SESSION['cdm']['search']['query'] : '');
170
171 7b4c053d Andreas Kohlbecker
  if ($advanced_form || variable_get(SIMPLE_SEARCH_USE_LUCENE_BACKEND, FALSE)) {
172 2d0d855a Andreas Kohlbecker
    $search_service_endpoint = CDM_WS_PORTAL_TAXON_SEARCH;
173 7b4c053d Andreas Kohlbecker
  }
174
  else {
175 2d0d855a Andreas Kohlbecker
    $search_service_endpoint = CDM_WS_PORTAL_TAXON_FIND;
176
  }
177
178
  $form = cdm_dataportal_search_form_prepare(
179
    'cdm_dataportal/search/results/taxon',
180
    $search_service_endpoint,
181
    $query_field_default_value,
182
    t('Enter the name or part of a name you wish to search for.
183 a6ae799b Andreas Kohlbecker
      The asterisk  character * can be used as wildcard, but must not be used as first character.')
184 2d0d855a Andreas Kohlbecker
  );
185 cd64df61 Andreas Kohlbecker
186 7b4c053d Andreas Kohlbecker
  if (!$advanced_form) {
187 6657531f Andreas Kohlbecker
    $form['query']['#size'] = 20;
188
  }
189
190
  $form['search']['pageSize'] = array(
191
    '#weight' => -1,
192
    '#type' => 'hidden',
193
    '#value' => variable_get('cdm_dataportal_search_items_on_page', 25),
194
  );
195
196
  $form['search']['pageNumber'] = array(
197
    '#weight' => -1,
198
    '#type' => 'hidden',
199
    '#value' => 0,
200
  );
201
202 7b4c053d Andreas Kohlbecker
  $search_taxa_mode_settings = get_array_variable_merged(
203
    CDM_SEARCH_TAXA_MODE,
204
    CDM_SEARCH_TAXA_MODE_DEFAULT
205
  );
206
  $preset_do_taxa = $search_taxa_mode_settings['doTaxa'] !== 0;
207
  $preset_do_synonyms = $search_taxa_mode_settings['doSynonyms'] !== 0;
208
  $preset_do_taxa_by_common_names = $search_taxa_mode_settings['doTaxaByCommonNames'] !== 0;
209
  $preset_do_misapplied_names = $search_taxa_mode_settings['doMisappliedNames'] !== 0;
210 6657531f Andreas Kohlbecker
211 7b4c053d Andreas Kohlbecker
  if ($advanced_form) {
212 642b323b Andreas Kohlbecker
213 6280e639 Andreas Kohlbecker
    // --- ADVANCED SEARCH FORM ---
214 61b6ee11 Andreas Kohlbecker
    //
215 dbf4b8a8 Andreas Kohlbecker
216 6657531f Andreas Kohlbecker
    // Get presets from settings.
217 7663cd0b Andreas Kohlbecker
    $preset_classification_uuid = get_current_classification_uuid();
218 6657531f Andreas Kohlbecker
219
    // Overwrite presets by user choice stored in session.
220 6280e639 Andreas Kohlbecker
    if (isset($_SESSION['cdm']['search'])) {
221 7b4c053d Andreas Kohlbecker
      $preset_do_taxa = (isset($_SESSION['cdm']['search']['doTaxa']) ? 1 : 0);
222
      $preset_do_synonyms = (isset($_SESSION['cdm']['search']['doSynonyms']) ? 1 : 0);
223
      $preset_do_misapplied_names = (isset($_SESSION['cdm']['search']['doMisappliedNames']) ? 1 : 0);
224
      $preset_do_taxa_by_common_names = (isset($_SESSION['cdm']['search']['doTaxaByCommonNames']) ? 1 : 0);
225 61b6ee11 Andreas Kohlbecker
      if (isset($_SESSION['cdm']['search']['tree'])) {
226
        $preset_classification_uuid = $_SESSION['cdm']['search']['tree'];
227
      }
228 6657531f Andreas Kohlbecker
    }
229 dbf4b8a8 Andreas Kohlbecker
230 7b4c053d Andreas Kohlbecker
    if ($classification_select === TRUE) {
231 f56b1626 Andreas Kohlbecker
      $form['search']['tree'] = array(
232 642b323b Andreas Kohlbecker
        '#title' => t('Classification'),
233
        '#weight' => 1,
234
        '#type' => 'select',
235 7d42c393 Andreas Kohlbecker
        '#default_value' => $preset_classification_uuid,
236 f56b1626 Andreas Kohlbecker
        '#options' => cdm_get_taxontrees_as_options(TRUE),
237 8ae3cfe3 Andreas Kohlbecker
        '#description' => t('A filter to limit the search to a specific classification. Choosing <em>--- ALL ---</em> will disable this filter.'),
238 dbf4b8a8 Andreas Kohlbecker
      );
239 632a697a Andreas Kohlbecker
    }
240 dbf4b8a8 Andreas Kohlbecker
241 6657531f Andreas Kohlbecker
    // General search parameters.
242
    $form['search']['doTaxa'] = array(
243
      '#weight' => 2,
244
      '#type' => 'checkbox',
245 51384c70 Andreas Kohlbecker
      '#title' => t('Include') . ' ' . t('accepted taxa'),
246 7b4c053d Andreas Kohlbecker
      '#value' => $preset_do_taxa,
247 6657531f Andreas Kohlbecker
    );
248
    $form['search']['doSynonyms'] = array(
249
      '#weight' => 3,
250
      '#type' => 'checkbox',
251 51384c70 Andreas Kohlbecker
      '#title' => t('Include') . ' ' . t('synonyms'),
252 7b4c053d Andreas Kohlbecker
      '#value' => $preset_do_synonyms,
253 6657531f Andreas Kohlbecker
    );
254
    $form['search']['doMisappliedNames'] = array(
255
      '#weight' => 4,
256
      '#type' => 'checkbox',
257 51384c70 Andreas Kohlbecker
      '#title' => t('Include') . ' ' . t('misapplied names'),
258 7b4c053d Andreas Kohlbecker
      '#value' => $preset_do_misapplied_names,
259 6657531f Andreas Kohlbecker
    );
260
    $form['search']['doTaxaByCommonNames'] = array(
261
      '#weight' => 5,
262
      '#type' => 'checkbox',
263 51384c70 Andreas Kohlbecker
      '#title' => t('Include') . ' ' . t('common names'),
264 7b4c053d Andreas Kohlbecker
      '#value' => $preset_do_taxa_by_common_names,
265 6657531f Andreas Kohlbecker
    );
266
267 7b4c053d Andreas Kohlbecker
    $area_term_dtos = cdm_ws_fetch_all(
268
      CDM_WS_DESCRIPTION_NAMEDAREAS_IN_USE,
269
      array('includeAllParents' => 'true')
270
    );
271 446cffc5 Andreas Kohlbecker
272 86424a78 Andreas Kohlbecker
    // create map: term_uuid => term
273 41c6dd13 Andreas Kohlbecker
    $term_map = array();
274 7b4c053d Andreas Kohlbecker
    foreach ($area_term_dtos as $term_dto) {
275 41c6dd13 Andreas Kohlbecker
      $term_map[$term_dto->uuid] = $term_dto;
276 632a697a Andreas Kohlbecker
    }
277 41c6dd13 Andreas Kohlbecker
278 632a697a Andreas Kohlbecker
    $term_tree = array();
279 41c6dd13 Andreas Kohlbecker
    // mixed_vocabularies will contain the uuid vocabularies which
280 86424a78 Andreas Kohlbecker
    // also contain terms of foreign vocabularies due to the term
281 41c6dd13 Andreas Kohlbecker
    // hierarchy
282
    $mixed_vocabularies = array();
283
284
    // Build hierarchy of the terms regardless of the vocabulary.
285 a783afbc Andreas Kohlbecker
    foreach ($term_map as $term_dto) {
286
      if (!empty($term_dto->partOfUuid)) {
287
        // Children.
288
        $parent =& $term_map[$term_dto->partOfUuid];
289
        if ($parent) {
290
          if (!isset($parent->children)) {
291
            $parent->children = array();
292 446cffc5 Andreas Kohlbecker
          }
293 a783afbc Andreas Kohlbecker
          $parent->children[$term_dto->uuid] = $term_dto;
294
          if ($parent->vocabularyUuid != $term_dto->vocabularyUuid) {
295
            $mixed_vocabularies[$parent->vocabularyUuid] = $parent->vocabularyUuid;
296 41c6dd13 Andreas Kohlbecker
          }
297 632a697a Andreas Kohlbecker
        }
298 446cffc5 Andreas Kohlbecker
      }
299 a783afbc Andreas Kohlbecker
      else {
300
        // group root nodes by vocabulary
301
        if (!isset($term_tree[$term_dto->vocabularyUuid])) {
302
          $term_tree[$term_dto->vocabularyUuid] = array();
303
        }
304
        $term_tree[$term_dto->vocabularyUuid][$term_dto->uuid] = $term_dto;
305
      }
306
    }
307
308 072122ee Andreas Kohlbecker
    $show_area_filter = ! variable_get(CDM_SEARCH_AREA_FILTER_PRESET, '');
309 446cffc5 Andreas Kohlbecker
310 072122ee Andreas Kohlbecker
    if($show_area_filter){
311
      drupal_add_js(drupal_get_path('module', 'cdm_dataportal') . '/js/search_area_filter.js');
312
313
      drupal_add_js('jQuery(document).ready(function() {
314 446cffc5 Andreas Kohlbecker
        jQuery(\'#edit-search-areas\').search_area_filter(\'#edit-search-areas-areas-filter\');
315
      });
316
      ', array('type' => 'inline'));
317
318 072122ee Andreas Kohlbecker
      $form['search']['areas'] = array(
319
        '#type' => 'fieldset',
320
        '#title' => t('Filter by distribution areas'),
321
        '#description' => t('The search will return taxa having distribution
322 722b1688 Andreas Kohlbecker
        information for at least one of the selected areas.') . ' '
323 072122ee Andreas Kohlbecker
          .(count($term_tree) > 1 ? t('The areas are grouped
324 722b1688 Andreas Kohlbecker
        by the vocabularies to which the highest level areas belong.') : ''),
325 632a697a Andreas Kohlbecker
      );
326 072122ee Andreas Kohlbecker
      $form['search']['areas']['areas_filter'] = array(
327
        '#type' => 'textfield',
328
        '#description' => t('Type to filter the areas listed below.'),
329
      );
330
      $vocab_cnt = 0;
331
      $areas_defaults = array();
332
      if (isset($_SESSION['cdm']['search']['area'])) {
333
        $areas_defaults = explode(',', $_SESSION['cdm']['search']['area']);
334
      }
335 6b605d3b Andreas Kohlbecker
      _add_js_resizable_element('.resizable-box', true);
336 072122ee Andreas Kohlbecker
      foreach ($term_tree as $vocab_uuid => $term_dto_tree) {
337
        $vocabulary = cdm_ws_get(CDM_WS_TERMVOCABULARY, array($vocab_uuid));
338
        $areas_options = term_tree_as_options($term_dto_tree);
339
        $form['search']['areas']['area'][$vocab_cnt++] = array(
340
          '#prefix' => '<strong>' . $vocabulary->representation_L10n
341
            . (isset($mixed_vocabularies[$vocab_uuid]) ? ' <span title="Contains terms of at least one other area vocabulary.">(' . t('mixed') . ')</span>': '')
342 6b605d3b Andreas Kohlbecker
            . '</strong><div class="resizable-container"><div class="resizable-box">',
343 072122ee Andreas Kohlbecker
          '#type' => 'checkboxes',
344
          '#default_value' => $areas_defaults,
345
          '#options' => $areas_options,
346 6b605d3b Andreas Kohlbecker
          '#suffix' => '</div></div>'
347 072122ee Andreas Kohlbecker
        );
348
      }
349 632a697a Andreas Kohlbecker
    }
350 446cffc5 Andreas Kohlbecker
351 7b4c053d Andreas Kohlbecker
  }
352
  else {
353 61b6ee11 Andreas Kohlbecker
    // --- SIMPLE SEARCH FORM ---
354
    //
355
356 6657531f Andreas Kohlbecker
    // Overwrite presets by user choice stored in session.
357 6280e639 Andreas Kohlbecker
    if (isset($_SESSION['cdm']['search'])) {
358 7b4c053d Andreas Kohlbecker
      $preset_do_misapplied_names = (isset($_SESSION['cdm']['search']['doMisappliedNames']) ? 1 : 0);
359 6657531f Andreas Kohlbecker
    }
360
361
    $form['search']['doTaxa'] = array(
362
      '#weight' => -2,
363
      '#type' => 'hidden',
364 7b4c053d Andreas Kohlbecker
      '#value' => $preset_do_taxa,
365 6657531f Andreas Kohlbecker
    );
366
    $form['search']['doSynonyms'] = array(
367
      '#weight' => -3,
368
      '#type' => 'hidden',
369 7b4c053d Andreas Kohlbecker
      '#value' => $preset_do_synonyms,
370 6657531f Andreas Kohlbecker
    );
371
    $form['search']['doMisappliedNames'] = array(
372
      '#weight' => -4,
373
      '#type' => 'checkbox',
374
      '#title' => t('Misapplied names'),
375 7b4c053d Andreas Kohlbecker
      '#value' => $preset_do_misapplied_names,
376 6657531f Andreas Kohlbecker
    );
377
    $form['search']['doTaxaByCommonNames'] = array(
378
      '#weight' => -5,
379
      '#type' => 'hidden',
380 7b4c053d Andreas Kohlbecker
      '#value' => $preset_do_taxa_by_common_names,
381 6657531f Andreas Kohlbecker
    );
382
  }
383
384
  return $form;
385
}
386 632a697a Andreas Kohlbecker
387 6657531f Andreas Kohlbecker
/**
388 7b4c053d Andreas Kohlbecker
 * Wrapper function for cdm_dataportal_search_taxon_form().
389
 *
390
 * This function makes ot possible possible to just pass the
391
 * correct $form_id 'cdm_dataportal_search_taxon_form_advanced' to
392
 * drupal_get_form like:
393
 * drupal_get_form('cdm_dataportal_search_taxon_form_advanced');
394
 *
395
 * @param array $form
396
 *   A drupal form array
397
 * @param array $form_state
398
 *   The drupal form state passed as reference
399
 *
400
 * @return array
401
 *   The form array
402 6657531f Andreas Kohlbecker
 */
403
function cdm_dataportal_search_taxon_form_advanced($form, &$form_state) {
404
  return cdm_dataportal_search_taxon_form($form, $form_state, TRUE);
405
}
406
407
/**
408 7b4c053d Andreas Kohlbecker
 * Form for searching taxa by the findByDescriptionElementFullText rest service.
409 6657531f Andreas Kohlbecker
 */
410
function cdm_dataportal_search_taxon_by_description_form() {
411
  $query_field_default_value = (isset($_SESSION['cdm']['search']['query']) ? $_SESSION['cdm']['search']['query'] : '');
412
413
  $form = cdm_dataportal_search_form_prepare(
414 632a697a Andreas Kohlbecker
    'cdm_dataportal/search/results/taxon',
415
    CDM_WS_PORTAL_TAXON_FINDBY_DESCRIPTIONELEMENT_FULLTEXT,
416
    $query_field_default_value,
417
    t("Enter the text you wish to search for. The asterisk character * can be
418 20624f5a Andreas Kohlbecker
        used as wildcard, but must not be used as first character. Terms can be combined with 'AND'. To search for a
419 36af8b60 Andreas Kohlbecker
        full phrase enclose the terms in parentheses. For more syntactical
420 7b4c053d Andreas Kohlbecker
        options please refer to the !link.",
421
      array(
422
        '!link' => l(
423
          t('Apache Lucene - Query Parser Syntax'),
424
          'http://lucene.apache.org/core/old_versioned_docs/versions/2_9_1/queryparsersyntax.html', array(
425
            'attributes' => array(
426
              'absolute' => TRUE,
427
              'html' => TRUE),
428
          )
429
        ),
430
      )
431 a6ae799b Andreas Kohlbecker
    )
432 632a697a Andreas Kohlbecker
  );
433 6657531f Andreas Kohlbecker
434
  $form['search']['tree'] = array(
435
    '#weight' => -1,
436
    '#type' => 'hidden',
437 7663cd0b Andreas Kohlbecker
    '#value' => get_current_classification_uuid(),
438 6657531f Andreas Kohlbecker
  );
439
440
  $form['search']['hl'] = array(
441
    '#weight' => -1,
442
    '#type' => 'hidden',
443
    '#value' => 1,
444
  );
445
446 b58fcc1f Andreas Kohlbecker
  // Only available to admins:
447 6657531f Andreas Kohlbecker
  if (!isset($_SESSION['cdm']['search']['clazz'])) {
448
    $_SESSION['cdm']['search']['clazz'] = '';
449
  }
450
  if (module_exists("user") && user_access('administer')) {
451
    $form['search']['clazz'] = array(
452
      '#type' => 'select',
453 b58fcc1f Andreas Kohlbecker
      '#title' => t('Limit to description item type'),
454 6657531f Andreas Kohlbecker
      '#default_value' => $_SESSION['cdm']['search']['clazz'],
455
      '#options' => cdm_descriptionElementTypes_as_option(TRUE),
456
    );
457
  }
458
459 7b4c053d Andreas Kohlbecker
  $profile_feature_tree = get_profile_feature_tree();
460
  $feature_options = _featureTree_nodes_as_feature_options($profile_feature_tree->root);
461 6657531f Andreas Kohlbecker
  if (isset($_SESSION['cdm']['search']['features'])) {
462
    $form['search']['features'] = array(
463
      '#type' => 'checkboxes',
464
      '#title' => t('Limit to selected features'),
465
      '#default_value' => $_SESSION['cdm']['search']['features'],
466
      '#options' => $feature_options,
467
    );
468
  }
469
  else {
470
    $form['search']['features'] = array(
471
      '#type' => 'checkboxes',
472
      '#title' => t('Limit to selected features'),
473
      '#options' => $feature_options,
474
    );
475
  }
476
  return $form;
477
}
478
479
/**
480 7b4c053d Andreas Kohlbecker
 * Processes the query parameters of the search form.
481
 *
482
 * Reads the query parameters from $_REQUEST and modifies and adds additional
483 103a1463 Andreas Kohlbecker
 * query parameters if necessary.
484 dbf4b8a8 Andreas Kohlbecker
 *
485
 *  - Filters $_REQUEST by a list of valid request parameters
486
 *  - modifies geographic_range parameters
487
 *  - adds taxon tree uuid if it is missing and if it should not be
488
 *    ignored (parameter value = 'IGNORE')
489
 *  - and more
490
 *
491 b3d49e6e Andreas Kohlbecker
 * @param $search_endpoint string
492
 *    The web service endpoint which will be used for executing the search.
493
 *    Usually one of CDM_WS_PORTAL_TAXON_SEARCH, CDM_WS_PORTAL_TAXON_FIND,
494
 *    CDM_WS_PORTAL_TAXON_FINDBY_DESCRIPTIONELEMENT_FULLTEXT.
495 7b4c053d Andreas Kohlbecker
 * @return array
496 dbf4b8a8 Andreas Kohlbecker
 *   the processed request parameters submitted by the search form and
497
 *   also stores them in $_SESSION['cdm']['search']
498 6657531f Andreas Kohlbecker
 */
499 b3d49e6e Andreas Kohlbecker
function cdm_dataportal_search_request($search_endpoint)
500 f48cede0 Andreas Kohlbecker
{
501 61b6ee11 Andreas Kohlbecker
502 6657531f Andreas Kohlbecker
  $form_params = array();
503 61b6ee11 Andreas Kohlbecker
504 34dd7be9 Andreas Kohlbecker
  if (isset($_REQUEST['search']) && is_array($_REQUEST['search'])) {
505 6657531f Andreas Kohlbecker
    array_deep_copy($_REQUEST['search'], $form_params);
506
  }
507 34dd7be9 Andreas Kohlbecker
508
  if (isset($_REQUEST['pager']) && is_array($_REQUEST['pager'])) {
509
    $form_params = array_merge($form_params, $_REQUEST['pager']);
510
  }
511
512 6657531f Andreas Kohlbecker
  $form_params['query'] = trim($_REQUEST['query']);
513
514 b3d49e6e Andreas Kohlbecker
515 6657531f Andreas Kohlbecker
  // --- handle geographic range
516
  // Split of geographic range.
517 44756fcd Andreas Kohlbecker
  unset($form_params['areas']);
518 072122ee Andreas Kohlbecker
519 9bbe3bcd Andreas Kohlbecker
  $area_filter_preset = null;
520 f48cede0 Andreas Kohlbecker
  if (variable_get(CDM_SEARCH_AREA_FILTER_PRESET, '')) {
521
    $area_filter_preset = explode(',', variable_get(CDM_SEARCH_AREA_FILTER_PRESET, ''));
522
  }
523 072122ee Andreas Kohlbecker
524 30399ffa Andreas Kohlbecker
  $area_uuids = array();
525 072122ee Andreas Kohlbecker
  if($area_filter_preset){
526
    $area_uuids = $area_filter_preset;
527
  }
528
  elseif (isset($_REQUEST['search']['areas']['area']) && is_array($_REQUEST['search']['areas']['area'])) {
529 7b4c053d Andreas Kohlbecker
    foreach ($_REQUEST['search']['areas']['area'] as $areas) {
530
      $area_uuids = array_merge($area_uuids, $areas);
531
    }
532 efa372e9 Andreas Kohlbecker
    // The area filter is limited to areas with non absent distribution status
533
    $presence_terms_options = cdm_vocabulary_as_option(UUID_PRESENCE_ABSENCE_TERM, null, FALSE, array('absenceTerm' => '/false/'));
534
    $presence_term_uuids = array_keys($presence_terms_options);
535
    $form_params['status'] = $presence_term_uuids;
536 072122ee Andreas Kohlbecker
  }
537 30399ffa Andreas Kohlbecker
  if(count($area_uuids) > 0){
538 7b4c053d Andreas Kohlbecker
    $form_params['area'] = implode(',', $area_uuids);
539 6657531f Andreas Kohlbecker
  }
540
541 7b4c053d Andreas Kohlbecker
  // Simple search will not submit a 'tree' query parameter,
542
  // so we add it here from what is stored in the session unless
543 90a6166e Andreas Kohlbecker
  // SIMPLE_SEARCH_IGNORE_CLASSIFICATION is checked in the settings.
544
  if (!isset($form_params['tree']) && !variable_get(SIMPLE_SEARCH_IGNORE_CLASSIFICATION, 0)) {
545 7663cd0b Andreas Kohlbecker
    $form_params['tree'] = get_current_classification_uuid();
546 61b6ee11 Andreas Kohlbecker
  }
547 38753115 Andreas Kohlbecker
  // Store in session.
548
  $_SESSION['cdm']['search'] = $form_params;
549
550
  // ----------- further processing that must not be store in the session --------- //
551
552 67a5cafa Andreas Kohlbecker
  if($search_endpoint == CDM_WS_PORTAL_TAXON_SEARCH){
553 a15edbb0 Andreas Kohlbecker
    // HACK to allow using dot characters
554
    $form_params['query'] = str_replace('.', '*', $form_params['query']);
555 a0557101 Andreas Kohlbecker
    // lucene based taxon search always as phrase search if the query string contains a whitespace --> enclose it in "
556
    if(preg_match("/\s+/", $form_params['query'])){
557
      if(!str_beginsWith($form_params['query'], '"')){
558
        $form_params['query'] = '"' . $form_params['query'];
559
      }
560
      if(!str_endsWith($form_params['query'], '"')){
561
        $form_params['query'] = $form_params['query'] . '"' ;
562
      }
563 67a5cafa Andreas Kohlbecker
    }
564
  }
565
566 efa372e9 Andreas Kohlbecker
  // If the 'NONE' classification has been chosen (advanced search)
567 7b4c053d Andreas Kohlbecker
  // delete the tree information to avoid unknown uuid exceptions in the
568
  // cdm service.
569
  if (isset($form_params['tree'])
570
    && ($form_params['tree'] == 'NONE' || !is_uuid($form_params['tree']))
571
  ) {
572
    // $form_params['ignore_classification'] =  TRUE;
573 dbf4b8a8 Andreas Kohlbecker
    unset($form_params['tree']);
574
  }
575 7b4c053d Andreas Kohlbecker
  // else {
576
  //   $form_params['ignore_classification'] =  NULL;
577
  // }
578 dbf4b8a8 Andreas Kohlbecker
579 6657531f Andreas Kohlbecker
580
  return $form_params;
581
}
582
583 61b6ee11 Andreas Kohlbecker
/**
584 44756fcd Andreas Kohlbecker
 * Provides the classification to which the last search has been limited to..
585 61b6ee11 Andreas Kohlbecker
 *
586 24797d7f Andreas Kohlbecker
 * This function should only be used after the cdm_dataportal_search_taxon_execute()
587 efa372e9 Andreas Kohlbecker
 * handler has been run, otherwise it will return the information from the last
588 7b4c053d Andreas Kohlbecker
 * search executed. The information is retrieved from
589 61b6ee11 Andreas Kohlbecker
 * the $_SESSION variable:  $_SESSION['cdm']['search']['tree']
590
 *
591 7b4c053d Andreas Kohlbecker
 * @return object
592
 *   the CDM classification instance which has been used a filter for the
593
 *   last processed search
594
 *   or NULL, it it was on all classifications
595 61b6ee11 Andreas Kohlbecker
 */
596
function cdm_dataportal_searched_in_classification() {
597
598
  $classification = &drupal_static(__FUNCTION__);
599
600
  if (!isset($classification)) {
601
    if (isset($_SESSION['cdm']['search']['tree'])) {
602
      $classification = cdm_ws_get(CDM_WS_PORTAL_TAXONOMY, ($_SESSION['cdm']['search']['tree']));
603 7b4c053d Andreas Kohlbecker
    }
604
    else {
605 61b6ee11 Andreas Kohlbecker
      $classification = FALSE;
606
    }
607
  }
608
609 7b4c053d Andreas Kohlbecker
  return $classification !== FALSE ? $classification : NULL;
610 61b6ee11 Andreas Kohlbecker
}
611
612 a6ae799b Andreas Kohlbecker
/**
613
 * Removed the drupal internal form parameters 'form_id', 'form_token', 'form_build_id' from the request array.
614
 *
615
 * @param $request array
616
 *   Pass $_REQUEST as paramter
617
 * @return array
618
 *  The $request array without drupal internal form parameters
619
 */
620
function remove_drupal_form_params($request) {
621
622
  static $exclude_keys = array('form_id', 'form_token', 'form_build_id');
623
  $request_sanitized = array();
624
  foreach ($request as $key => $value) {
625
    if(!array_search($key, $exclude_keys)){
626
      $request_sanitized[$key] = $value;
627
    }
628
  }
629
630
  return $request_sanitized;
631
}
632
633 6657531f Andreas Kohlbecker
/**
634 103a1463 Andreas Kohlbecker
 * Sends a search request to the cdm server.
635 dbf4b8a8 Andreas Kohlbecker
 *
636
 * The parameters to build the query are taken obtained by calling
637 efa372e9 Andreas Kohlbecker
 * cdm_dataportal_search_request() which reads the query parameters
638 dbf4b8a8 Andreas Kohlbecker
 * from $_REQUEST and add additional query parameters if nessecary.
639
 *
640 efa372e9 Andreas Kohlbecker
 * @see cdm_dataportal_search_request()
641 6657531f Andreas Kohlbecker
 */
642 24797d7f Andreas Kohlbecker
function cdm_dataportal_search_taxon_execute() {
643 6657531f Andreas Kohlbecker
644
  // Store as last search in session.
645
  $_SESSION['cdm']['last_search'] = $_SERVER['REQUEST_URI'];
646
647
  // Validate the search webservice parameter:
648 7b4c053d Andreas Kohlbecker
  if (!isset($_REQUEST['ws'])) {
649
    drupal_set_message(
650 103a1463 Andreas Kohlbecker
      t("Invalid search, webservice parameter 'ws' is missing"), 'warning'
651 7b4c053d Andreas Kohlbecker
    );
652 61b6ee11 Andreas Kohlbecker
    return NULL;
653
  }
654 7b4c053d Andreas Kohlbecker
  if (!cdm_dataportal_search_form_path_for_ws($_REQUEST['ws'])) {
655 6657531f Andreas Kohlbecker
    // Endpoint is unknown.
656 7b4c053d Andreas Kohlbecker
    drupal_set_message(
657 78ec4159 Andreas Kohlbecker
      t("Invalid search webservice parameter 'ws' given"), 'warning'
658 7b4c053d Andreas Kohlbecker
    );
659 6657531f Andreas Kohlbecker
    return NULL;
660
  }
661
662 7b4c053d Andreas Kohlbecker
  // Read the query parameters from $_REQUEST and add additional query
663
  // parameters if necessary.
664 b3d49e6e Andreas Kohlbecker
  $request_params = cdm_dataportal_search_request($_REQUEST['ws']);
665 dbf4b8a8 Andreas Kohlbecker
666 446cffc5 Andreas Kohlbecker
  $taxon_pager = cdm_ws_get($_REQUEST['ws'], NULL, queryString($request_params));
667
668
  return $taxon_pager;
669
}
670
671 a6ae799b Andreas Kohlbecker
672
/**
673
 * Sends a request to search for registrations to the cdm server.
674
 */
675
function cdm_dataportal_search_registrations_execute()
676
{
677
678
  static $query_param_map = array(
679
    'identifier' => 'identifierFilterPattern',
680
    'taxon_name'=> 'taxonNameFilterPattern',
681
    'type_designation_status' => 'typeDesignationStatusUuids',
682
  );
683
684
  // Read the query parameters from $_REQUEST and add additional query
685
  // parameters if necessary.
686
  $request_params = array();
687
688
  $request = remove_drupal_form_params($_REQUEST);
689
690
  if(count($request) > 0){
691
    $_SESSION['cdm'][SESSION_KEY_SEARCH_REGISTRATION_FILTER] = $request;
692
    foreach ($query_param_map as $filter_key => $query_param){
693
      if (isset($request[$filter_key])) {
694
        $request_params[$query_param] = $request[$filter_key];
695
      }
696
    }
697
    if(isset($request['pager']['pageNumber'])){
698
      $request_params['pageNumber'] = $request['pager']['pageNumber'];
699
    }
700
  }
701
702
  if(count($request_params) == 0 && isset($_SESSION['cdm'][SESSION_KEY_SEARCH_REGISTRATION_FILTER])){
703
    foreach ($query_param_map as $filter_key => $query_param){
704
      if (isset($_SESSION['cdm'][SESSION_KEY_SEARCH_REGISTRATION_FILTER][$filter_key])) {
705
        $request_params[$query_param] = $_SESSION['cdm'][SESSION_KEY_SEARCH_REGISTRATION_FILTER][$filter_key];
706
      }
707
    }
708
    if(isset($_SESSION['cdm'][SESSION_KEY_SEARCH_REGISTRATION_FILTER]['pager']['pageNumber'])){
709
      $request_params['pageNumber'] = $_SESSION['cdm'][SESSION_KEY_SEARCH_REGISTRATION_FILTER]['pager']['pageNumber'];
710
    }
711
  }
712
713
  // cleanup
714
  if(isset($request_params['typeDesignationStatusUuids'])){
715
    if(!$request_params['typeDesignationStatusUuids']
716
      || $request_params['typeDesignationStatusUuids'] == "0"
717
      || (isset($request_params['typeDesignationStatusUuids'][0]) && !$request_params['typeDesignationStatusUuids'][0])){
718
      unset($request_params['typeDesignationStatusUuids']);
719
    }
720 bb177c82 Andreas Kohlbecker
  }
721
  if(isset($request_params['taxonNameFilterPattern'])){
722
    // trim and remove empty taxon name query strings
723
    $request_params['taxonNameFilterPattern'] = trim($request_params['taxonNameFilterPattern']);
724
    if(!$request_params['taxonNameFilterPattern']){
725
      unset($request_params['taxonNameFilterPattern']);
726
    }
727 a6ae799b Andreas Kohlbecker
  }
728
729
  $registration_pager = cdm_ws_get('registrationDTO/find', NULL, queryString($request_params));
730
731
  return $registration_pager;
732
}
733
734 7b4c053d Andreas Kohlbecker
/**
735
 * Transforms the termDTO tree into options array.
736
 *
737
 *   TermDto:
738
 *      - partOfUuid:
739
 *      - representation_L10n:
740
 *      - representation_L10n_abbreviatedLabel:
741
 *      - uuid:
742
 *      - vocabularyUuid:
743
 *      - children: array of TermDto
744
 *
745
 * The options array is suitable for drupal form API elements that
746
 * allow multiple choices.
747
 * @see http://api.drupal.org/api/drupal/developer!topics!forms_api_reference.html/7#options
748
 *
749
 * @param array $term_dto_tree
750
 *   a hierarchic array of CDM TermDto instances, with additional
751
 * 'children' field:
752
 * @param array $options
753
 *   Internally used for recursive calls
754
 * @param string $prefix
755
 *   Internally used for recursive calls
756
 *
757
 * @return array
758
 *   the terms in an array as options for a form element that allows
759
 *   multiple choices.
760
 */
761
function term_tree_as_options($term_dto_tree, &$options = array(), $prefix = '') {
762
763 c079337e Andreas Kohlbecker
  uasort($term_dto_tree, 'compare_terms_by_order_index');
764 7b4c053d Andreas Kohlbecker
  foreach ($term_dto_tree as $uuid => $dto) {
765
    $label = $prefix . '<span class="child-label">'
766
      .  $dto->representation_L10n
767 35619936 Andreas Kohlbecker
      . '</span><span class="child-label-abbreviated"> (' . $dto->representation_L10n_abbreviatedLabel . ')</span>';
768 7b4c053d Andreas Kohlbecker
    $options[$uuid] = $label;
769
    if (isset($dto->children) && is_array($dto->children)) {
770
      term_tree_as_options(
771
        $dto->children,
772
        $options, $prefix
773 fdf52d6a Andreas Kohlbecker
          . '<span data-cdm-parent="' . $uuid . '" class="parent"></span>'
774
      );
775 446cffc5 Andreas Kohlbecker
    }
776 7b4c053d Andreas Kohlbecker
  }
777 6657531f Andreas Kohlbecker
778 7b4c053d Andreas Kohlbecker
  return $options;
779 6657531f Andreas Kohlbecker
}
780 a6ae799b Andreas Kohlbecker
781
782
function cdm_dataportal_search_registration_form($form, &$form_state) {
783
784 d68a30b0 Andreas Kohlbecker
  static $filter_presets_empty = array(
785
    'identifier'=> null,
786
    'taxon_name'=> null,
787
    'type_designation_status' => null
788
  );
789
790 6d9071b7 Andreas Kohlbecker
  _add_font_awesome_font();
791 bb177c82 Andreas Kohlbecker
792 a6ae799b Andreas Kohlbecker
  $filter_presets = (isset($_SESSION['cdm'][SESSION_KEY_SEARCH_REGISTRATION_FILTER]) ? $_SESSION['cdm'][SESSION_KEY_SEARCH_REGISTRATION_FILTER] : array());
793 d68a30b0 Andreas Kohlbecker
  $filter_presets = array_merge($filter_presets_empty, $filter_presets, remove_drupal_form_params($_REQUEST));
794 b49c60b7 Andreas Kohlbecker
  $form['#action'] =  url('/cdm_dataportal/search/registration/');
795 a6ae799b Andreas Kohlbecker
  $form['#method'] = 'get';
796
  $form['#attributes'] = array('class' => array('search-filter'));
797
  $form['identifier'] = array(
798
    '#type' => 'textfield',
799
    '#title' => t('Identifier'),
800
    '#default_value' => $filter_presets['identifier'],
801
    '#size' => 20,
802
    '#maxlength' => 128
803
  );
804
  $form['taxon_name'] = array(
805
    '#type' => 'textfield',
806
    '#title' => t('Scientific name'),
807
    '#default_value' => $filter_presets['taxon_name'],
808
    '#size' => 20,
809
    '#maxlength' => 128
810
  );
811
  $form['type_designation_status'] = array(
812
    '#type' => 'select',
813
    '#title' => t('Type designation status'),
814
    '#multiple' => true,
815
    '#options' => cdm_terms_by_type_as_option('TypeDesignationStatusBase', null, null, TRUE),
816
    '#default_value' => $filter_presets['type_designation_status']
817
  );
818
819
  $form['submit'] = array(
820
    '#type' => 'submit',
821
    '#attributes' => array('class' => array('fa-icon'), 'title' => t('Search')),
822
    '#value' => decode_entities('&#xf002;'), // fontawesome search icon
823 098b6358 Andreas Kohlbecker
//    '#prefix' => "<div class=\"form-item\"><label>&nbsp</label>",
824
//    '#suffix' => "</div>"
825 a6ae799b Andreas Kohlbecker
826
  );
827
  return $form;
828
}
829
830
831
/**
832
 * Compose the result set of a registration search from a pager object
833
 *
834
 * @param $registration_pager
835
 *    The pager containing registration objects
836
 *
837
 * @return
838
 *   A drupal render array.
839
 *
840
 * @ingroup compose
841
 *
842
 * TODO compose function into search.inc ?
843
 */
844 24797d7f Andreas Kohlbecker
function compose_registrations_search_results($registration_pager){
845 a6ae799b Andreas Kohlbecker
846
  $render_array = array();
847 6789eff8 Andreas Kohlbecker
  $render_array['pre'] = markup_to_render_array("<div class=\"cdm-item-list\">");
848 a6ae799b Andreas Kohlbecker
  if($registration_pager != null){
849
    $items_render_array = array();
850
    foreach($registration_pager->records as $registration) {
851
      $summary_markup = cdm_tagged_text_to_markup($registration->summaryTaggedText);
852
      $items_render_array[]  = markup_to_render_array(
853
        "<div class=\"item\"><div class=\"" . html_class_attribute_ref(new TypedEntityReference("Registration", $registration->uuid)) . "\">"
854
          . "<div class=\"identifier\">"
855 e0d3e148 Andreas Kohlbecker
          . l($registration->identifier, path_to_registration($registration->identifier), array('absolute' => true, 'attributes' => array('class' => array('identifier'))))
856 a6ae799b Andreas Kohlbecker
          . "</div>"
857
          . $summary_markup
858
          . "</div></div>"
859
        );
860
      ;
861
    }
862
    $render_array['items'] = $items_render_array;
863
    $render_array['pager'] =  markup_to_render_array(theme('cdm_pager', array(
864
          'pager' => $registration_pager,
865
          'path' => "cdm_dataportal/search/registration",
866
          'parameters' => $_REQUEST,
867
        )));
868
869
  } else {
870
    $render_array['items'] = markup_to_render_array("No results! Please use the search filter.");
871
  }
872
  $render_array['post'] = markup_to_render_array("</div>");
873
874
  return $render_array;
875
876
}