Project

General

Profile

Download (20.6 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/**
3
 * @file
4
 * Search related functions.
5
 */
6

    
7
/**
8
 * Returns a Drupal path to a search form for a CDM webservice.
9
 *
10
 * For a given CDM webservice end-point, the drupal page path to the
11
 * according search form is returned.
12
 * cdm webservice end points are defined in constant variables like:
13
 * <code>CDM_WS_PORTAL_TAXON_FIND</code> and
14
 * <code>CDM_WS_PORTAL_TAXON_FINDBY_DESCRIPTIONELEMENT_FULLTEXT</code>
15
 *
16
 * @param string $ws_endpoint
17
 *   The cdm webservice endpoint for which to find the search form path.
18
 *
19
 * @return string
20
 *   The Drupal path found.
21
 */
22
function cdm_dataportal_search_form_path_for_ws($ws_endpoint) {
23
  static $form_ws_map = array(
24
    CDM_WS_PORTAL_TAXON_FIND => "cdm_dataportal/search",
25
    CDM_WS_PORTAL_TAXON_SEARCH => "cdm_dataportal/search",
26
    CDM_WS_PORTAL_TAXON_FINDBY_DESCRIPTIONELEMENT_FULLTEXT => "cdm_dataportal/search/taxon_by_description",
27
  );
28
  return $form_ws_map[$ws_endpoint];
29
}
30

    
31
/**
32
 * Prepares a form array for a general purpose search form.
33
 *
34
 * The form is used for general purpose search functionality in the
35
 * dataportal. The form returned is populated with all nessecary fields
36
 * for internal processing and has the textfield element $form['query']
37
 * which holds the query term.
38
 * he sub tree array can be extended to contain additional search parameters.
39
 *
40
 * @param string $action_path
41
 *   The Drupal path to be put into the action url to which the form will
42
 *   be submitted.
43
 * @param string $search_webservice
44
 *   The cdm-remote webservice to be used, valid values are defined by
45
 *   the constants: FIXME.
46
 * @param string $query_field_default_value
47
 *   A default text for the query field
48
 * @param string $query_field_description
49
 *   The description text for the query field
50
 * @param string $process
51
 *   The value for #process, if NULL (default), 'cdm_dataportal_search_process'
52
 *   is used.
53
 *
54
 * @return array
55
 *   The prepared form array.
56
 */
57
function cdm_dataportal_search_form_prepare($action_path, $search_webservice, $query_field_default_value, $query_field_description, $process = NULL) {
58

    
59
  if ($process == NULL) {
60
    $process = 'cdm_dataportal_search_process';
61
  }
62

    
63
  $form['#method'] = 'get';
64
  //
65
  //  $form['#process'] = array(
66
  //  $process => array(),
67
  //  );
68
  //
69
  $form['#action'] = url($action_path, array(
70
    'absolute' => TRUE,
71
  ));
72

    
73
  $form['ws'] = array(
74
    '#type' => 'hidden',
75
    '#value' => $search_webservice,
76
    '#name' => 'ws',
77
  );
78

    
79
  $form['query'] = array(
80
    '#weight' => 0,
81
    '#type' => 'textfield',
82
    '#size' => 68,
83
    // This causes the description to display also when hovering over
84
    // the textfield.
85
    // This is wanted behaviour for the simple seach but could
86
    // be disabled for the advances search.
87
    '#attributes' => array(
88
      'title' => $query_field_description,
89
    ),
90
    '#description' => $query_field_description,
91
    '#value' => $query_field_default_value,
92
    // '#description' => $query_field_description,
93
  );
94

    
95
  $form['search'] = array(
96
    '#weight' => 3,
97
    '#tree' => TRUE,
98
    // '#type' => $advanced_form ? 'fieldset': 'hidden',
99
    '#title' => t('Options'),
100
  );
101

    
102
  // Clean URL get forms breaks if we don't give it a 'q'.
103
  if (!(bool) variable_get('clean_url', '0')) {
104
    $form['search']['q'] = array(
105
      '#type' => 'hidden',
106
      '#value' => $action_path,
107
      '#name' => 'q',
108
    );
109
  }
110

    
111
  $form['submit'] = array(
112
    '#weight' => 5,
113
    '#type' => 'submit',
114
    '#name' => '',
115
    '#value' => t('Search'),
116
  );
117

    
118
  return $form;
119
}
120

    
121
/**
122
 * Creates a search form for searching on taxa.
123
 *
124
 * If advanced $advanced_form id TRUE the form will offer additional choices
125
 *
126
 * @param array $form
127
 *   A drupal form array
128
 * @param array $form_state
129
 *   The drupal form state passed as reference
130
 * @param bool $advanced_form
131
 *   default is FALSE
132
 * @param bool $classification_select
133
 *   set TRUE to offer a classifiaction selector in the form - default is FALSE
134
 *   if only available in the advanced mode
135
 *
136
 * @return array
137
 *   the form array
138
 */
139
function cdm_dataportal_search_taxon_form($form, &$form_state, $advanced_form = FALSE, $classification_select = TRUE) {
140

    
141
  $query_field_default_value = (isset($_SESSION['cdm']['search']['query']) ? $_SESSION['cdm']['search']['query'] : '');
142

    
143
  if ($advanced_form || variable_get(SIMPLE_SEARCH_USE_LUCENE_BACKEND, FALSE)) {
144
    $search_service_endpoint = CDM_WS_PORTAL_TAXON_SEARCH;
145
  }
146
  else {
147
    $search_service_endpoint = CDM_WS_PORTAL_TAXON_FIND;
148
  }
149

    
150
  $form = cdm_dataportal_search_form_prepare(
151
    'cdm_dataportal/search/results/taxon',
152
    $search_service_endpoint,
153
    $query_field_default_value,
154
    t('Enter the name or part of a name you wish to search for.
155
      The asterisk  character * can be used as wildcard.'),
156
      NULL
157
  );
158

    
159
  if (!$advanced_form) {
160
    $form['query']['#size'] = 20;
161
  }
162

    
163
  $form['search']['pageSize'] = array(
164
    '#weight' => -1,
165
    '#type' => 'hidden',
166
    '#value' => variable_get('cdm_dataportal_search_items_on_page', 25),
167
  );
168

    
169
  $form['search']['pageNumber'] = array(
170
    '#weight' => -1,
171
    '#type' => 'hidden',
172
    '#value' => 0,
173
  );
174

    
175
  $search_taxa_mode_settings = get_array_variable_merged(
176
    CDM_SEARCH_TAXA_MODE,
177
    CDM_SEARCH_TAXA_MODE_DEFAULT
178
  );
179
  $preset_do_taxa = $search_taxa_mode_settings['doTaxa'] !== 0;
180
  $preset_do_synonyms = $search_taxa_mode_settings['doSynonyms'] !== 0;
181
  $preset_do_taxa_by_common_names = $search_taxa_mode_settings['doTaxaByCommonNames'] !== 0;
182
  $preset_do_misapplied_names = $search_taxa_mode_settings['doMisappliedNames'] !== 0;
183

    
184
  if ($advanced_form) {
185

    
186
    // --- ADVANCED SEARCH FORM ---
187
    //
188

    
189
    // Get presets from settings.
190
    $preset_classification_uuid = get_current_classification_uuid();
191

    
192
    // Overwrite presets by user choice stored in session.
193
    if (isset($_SESSION['cdm']['search'])) {
194
      $preset_do_taxa = (isset($_SESSION['cdm']['search']['doTaxa']) ? 1 : 0);
195
      $preset_do_synonyms = (isset($_SESSION['cdm']['search']['doSynonyms']) ? 1 : 0);
196
      $preset_do_misapplied_names = (isset($_SESSION['cdm']['search']['doMisappliedNames']) ? 1 : 0);
197
      $preset_do_taxa_by_common_names = (isset($_SESSION['cdm']['search']['doTaxaByCommonNames']) ? 1 : 0);
198
      if (isset($_SESSION['cdm']['search']['tree'])) {
199
        $preset_classification_uuid = $_SESSION['cdm']['search']['tree'];
200
      }
201
    }
202

    
203
    if ($classification_select === TRUE) {
204
      $form['search']['tree'] = array(
205
        '#title' => t('Classification'),
206
        '#weight' => 1,
207
        '#type' => 'select',
208
        '#default_value' => get_current_classification_uuid(),
209
        '#options' => cdm_get_taxontrees_as_options(TRUE),
210
        '#description' => t('A filter to limit the search to a specific classification. Choosing <em>--- ALL ---</em> will disable this filter.'),
211
      );
212
    }
213

    
214
    // General search parameters.
215
    $form['search']['doTaxa'] = array(
216
      '#weight' => 2,
217
      '#type' => 'checkbox',
218
      '#title' => t('Search for') . ' ' . t('accepted taxa'),
219
      '#value' => $preset_do_taxa,
220
    );
221
    $form['search']['doSynonyms'] = array(
222
      '#weight' => 3,
223
      '#type' => 'checkbox',
224
      '#title' => t('Search for') . ' ' . t('synonyms'),
225
      '#value' => $preset_do_synonyms,
226
    );
227
    $form['search']['doMisappliedNames'] = array(
228
      '#weight' => 4,
229
      '#type' => 'checkbox',
230
      '#title' => t('Search for') . ' ' . t('misapplied names'),
231
      '#value' => $preset_do_misapplied_names,
232
    );
233
    $form['search']['doTaxaByCommonNames'] = array(
234
      '#weight' => 5,
235
      '#type' => 'checkbox',
236
      '#title' => t('Search for') . ' ' . t('common names'),
237
      '#value' => $preset_do_taxa_by_common_names,
238
    );
239

    
240
    $area_term_dtos = cdm_ws_fetch_all(
241
      CDM_WS_DESCRIPTION_NAMEDAREAS_IN_USE,
242
      array('includeAllParents' => 'true')
243
    );
244

    
245
    // create map: parent_term_uuid => term
246
    $term_map = array();
247
    foreach ($area_term_dtos as $term_dto) {
248
      $term_map[$term_dto->uuid] = $term_dto;
249
    }
250

    
251
    $term_tree = array();
252
    // mixed_vocabularies will contain the uuid vocabularies which
253
    // also contain terms of foreign vocabuaries due to the term
254
    // hierarchy
255
    $mixed_vocabularies = array();
256

    
257
    // Build hierarchy of the terms regardless of the vocabulary.
258
    foreach ($term_map as $term_dto) {
259
      if (!empty($term_dto->partOfUuid)) {
260
        // Children.
261
        $parent =& $term_map[$term_dto->partOfUuid];
262
        if ($parent) {
263
          if (!isset($parent->children)) {
264
            $parent->children = array();
265
          }
266
          $parent->children[$term_dto->uuid] = $term_dto;
267
          if ($parent->vocabularyUuid != $term_dto->vocabularyUuid) {
268
            $mixed_vocabularies[$parent->vocabularyUuid] = $parent->vocabularyUuid;
269
          }
270
        }
271
      }
272
      else {
273
        // group root nodes by vocabulary
274
        if (!isset($term_tree[$term_dto->vocabularyUuid])) {
275
          $term_tree[$term_dto->vocabularyUuid] = array();
276
        }
277
        $term_tree[$term_dto->vocabularyUuid][$term_dto->uuid] = $term_dto;
278
      }
279
    }
280

    
281
    $show_area_filter = ! variable_get(CDM_SEARCH_AREA_FILTER_PRESET, '');
282

    
283
    if($show_area_filter){
284
      drupal_add_js(drupal_get_path('module', 'cdm_dataportal') . '/js/search_area_filter.js');
285

    
286
      drupal_add_js('jQuery(document).ready(function() {
287
        jQuery(\'#edit-search-areas\').search_area_filter(\'#edit-search-areas-areas-filter\');
288
      });
289
      ', array('type' => 'inline'));
290

    
291
      $form['search']['areas'] = array(
292
        '#type' => 'fieldset',
293
        '#title' => t('Filter by distribution areas'),
294
        '#description' => t('The search will return taxa having distribution
295
        information for at least one of the selected areas.') . ' '
296
          .(count($term_tree) > 1 ? t('The areas are grouped
297
        by the vocabularies to which the highest level areas belong.') : ''),
298
      );
299
      $form['search']['areas']['areas_filter'] = array(
300
        '#type' => 'textfield',
301
        '#description' => t('Type to filter the areas listed below.'),
302
      );
303
      $vocab_cnt = 0;
304
      $areas_defaults = array();
305
      if (isset($_SESSION['cdm']['search']['area'])) {
306
        $areas_defaults = explode(',', $_SESSION['cdm']['search']['area']);
307
      }
308
      foreach ($term_tree as $vocab_uuid => $term_dto_tree) {
309
        $vocabulary = cdm_ws_get(CDM_WS_TERMVOCABULARY, array($vocab_uuid));
310
        $areas_options = term_tree_as_options($term_dto_tree);
311
        $form['search']['areas']['area'][$vocab_cnt++] = array(
312
          '#prefix' => '<strong>' . $vocabulary->representation_L10n
313
            . (isset($mixed_vocabularies[$vocab_uuid]) ? ' <span title="Contains terms of at least one other area vocabulary.">(' . t('mixed') . ')</span>': '')
314
            . '</strong>',
315
          '#type' => 'checkboxes',
316
          '#default_value' => $areas_defaults,
317
          '#options' => $areas_options,
318
        );
319
      }
320
    }
321

    
322
  }
323
  else {
324
    // --- SIMPLE SEARCH FORM ---
325
    //
326

    
327
    // Overwrite presets by user choice stored in session.
328
    if (isset($_SESSION['cdm']['search'])) {
329
      $preset_do_misapplied_names = (isset($_SESSION['cdm']['search']['doMisappliedNames']) ? 1 : 0);
330
    }
331

    
332
    $form['search']['doTaxa'] = array(
333
      '#weight' => -2,
334
      '#type' => 'hidden',
335
      '#value' => $preset_do_taxa,
336
    );
337
    $form['search']['doSynonyms'] = array(
338
      '#weight' => -3,
339
      '#type' => 'hidden',
340
      '#value' => $preset_do_synonyms,
341
    );
342
    $form['search']['doMisappliedNames'] = array(
343
      '#weight' => -4,
344
      '#type' => 'checkbox',
345
      '#title' => t('Misapplied names'),
346
      '#value' => $preset_do_misapplied_names,
347
    );
348
    $form['search']['doTaxaByCommonNames'] = array(
349
      '#weight' => -5,
350
      '#type' => 'hidden',
351
      '#value' => $preset_do_taxa_by_common_names,
352
    );
353
  }
354

    
355
  return $form;
356
}
357

    
358
/**
359
 * Wrapper function for cdm_dataportal_search_taxon_form().
360
 *
361
 * This function makes ot possible possible to just pass the
362
 * correct $form_id 'cdm_dataportal_search_taxon_form_advanced' to
363
 * drupal_get_form like:
364
 * drupal_get_form('cdm_dataportal_search_taxon_form_advanced');
365
 *
366
 * @param array $form
367
 *   A drupal form array
368
 * @param array $form_state
369
 *   The drupal form state passed as reference
370
 *
371
 * @return array
372
 *   The form array
373
 */
374
function cdm_dataportal_search_taxon_form_advanced($form, &$form_state) {
375
  return cdm_dataportal_search_taxon_form($form, $form_state, TRUE);
376
}
377

    
378
/**
379
 * Form for searching taxa by the findByDescriptionElementFullText rest service.
380
 */
381
function cdm_dataportal_search_taxon_by_description_form() {
382
  $query_field_default_value = (isset($_SESSION['cdm']['search']['query']) ? $_SESSION['cdm']['search']['query'] : '');
383

    
384
  $form = cdm_dataportal_search_form_prepare(
385
    'cdm_dataportal/search/results/taxon',
386
    CDM_WS_PORTAL_TAXON_FINDBY_DESCRIPTIONELEMENT_FULLTEXT,
387
    $query_field_default_value,
388
    t("Enter the text you wish to search for. The asterisk character * can be
389
        used as wildcard. Terms can be combined with 'AND'. To search for a
390
        full phrase enclose the terms in parentheses. For more syntactical
391
        options please refer to the !link.",
392
      array(
393
        '!link' => l(
394
          t('Apache Lucene - Query Parser Syntax'),
395
          'http://lucene.apache.org/core/old_versioned_docs/versions/2_9_1/queryparsersyntax.html', array(
396
            'attributes' => array(
397
              'absolute' => TRUE,
398
              'html' => TRUE),
399
          )
400
        ),
401
      )
402
    ),
403
    NULL
404
  );
405

    
406
  $form['search']['tree'] = array(
407
    '#weight' => -1,
408
    '#type' => 'hidden',
409
    '#value' => get_current_classification_uuid(),
410
  );
411

    
412
  $form['search']['hl'] = array(
413
    '#weight' => -1,
414
    '#type' => 'hidden',
415
    '#value' => 1,
416
  );
417

    
418
  // Only available to admins:
419
  if (!isset($_SESSION['cdm']['search']['clazz'])) {
420
    $_SESSION['cdm']['search']['clazz'] = '';
421
  }
422
  if (module_exists("user") && user_access('administer')) {
423
    $form['search']['clazz'] = array(
424
      '#type' => 'select',
425
      '#title' => t('Limit to description item type'),
426
      '#default_value' => $_SESSION['cdm']['search']['clazz'],
427
      '#options' => cdm_descriptionElementTypes_as_option(TRUE),
428
    );
429
  }
430

    
431
  $profile_feature_tree = get_profile_feature_tree();
432
  $feature_options = _featureTree_nodes_as_feature_options($profile_feature_tree->root);
433
  if (isset($_SESSION['cdm']['search']['features'])) {
434
    $form['search']['features'] = array(
435
      '#type' => 'checkboxes',
436
      '#title' => t('Limit to selected features'),
437
      '#default_value' => $_SESSION['cdm']['search']['features'],
438
      '#options' => $feature_options,
439
    );
440
  }
441
  else {
442
    $form['search']['features'] = array(
443
      '#type' => 'checkboxes',
444
      '#title' => t('Limit to selected features'),
445
      '#options' => $feature_options,
446
    );
447
  }
448
  return $form;
449
}
450

    
451
/**
452
 * Processes the query parameters of the search form.
453
 *
454
 * Reads the query parameters from $_REQUEST and modifies and adds additional
455
 * query parameters if nessecary.
456
 *
457
 *  - Filters $_REQUEST by a list of valid request parameters
458
 *  - modifies geographic_range parameters
459
 *  - adds taxon tree uuid if it is missing and if it should not be
460
 *    ignored (parameter value = 'IGNORE')
461
 *  - and more
462
 *
463
 *
464
 * @return array
465
 *   the processed request parameters submitted by the search form and
466
 *   also stores them in $_SESSION['cdm']['search']
467
 */
468
function cdm_dataportal_search_form_request()
469
{
470

    
471
  $form_params = array();
472

    
473
  if (isset($_REQUEST['search']) && is_array($_REQUEST['search'])) {
474
    array_deep_copy($_REQUEST['search'], $form_params);
475
  }
476

    
477
  if (isset($_REQUEST['pager']) && is_array($_REQUEST['pager'])) {
478
    $form_params = array_merge($form_params, $_REQUEST['pager']);
479
  }
480

    
481
  $form_params['query'] = trim($_REQUEST['query']);
482

    
483
  // --- handle geographic range
484
  // Split of geographic range.
485
  unset($form_params['areas']);
486

    
487
  if (variable_get(CDM_SEARCH_AREA_FILTER_PRESET, '')) {
488
    $area_filter_preset = explode(',', variable_get(CDM_SEARCH_AREA_FILTER_PRESET, ''));
489
  }
490

    
491
  if($area_filter_preset){
492
    $area_uuids = $area_filter_preset;
493
  }
494
  elseif (isset($_REQUEST['search']['areas']['area']) && is_array($_REQUEST['search']['areas']['area'])) {
495
    $area_uuids = array();
496
    foreach ($_REQUEST['search']['areas']['area'] as $areas) {
497
      $area_uuids = array_merge($area_uuids, $areas);
498
    }
499
  }
500
  if(isset($area_uuids[0])){
501
    $form_params['area'] = implode(',', $area_uuids);
502
  }
503

    
504
  // Simple search will not submit a 'tree' query parameter,
505
  // so we add it here from what is stored in the session unless
506
  // SIMPLE_SEARCH_IGNORE_CLASSIFICATION is checked in the settings.
507
  if (!isset($form_params['tree']) && !variable_get(SIMPLE_SEARCH_IGNORE_CLASSIFICATION, 0)) {
508
    $form_params['tree'] = get_current_classification_uuid();
509
  }
510
  // If the 'NONE' classification has been chosen (adanced search)
511
  // delete the tree information to avoid unknown uuid exceptions in the
512
  // cdm service.
513
  if (isset($form_params['tree'])
514
    && ($form_params['tree'] == 'NONE' || !is_uuid($form_params['tree']))
515
  ) {
516
    // $form_params['ignore_classification'] =  TRUE;
517
    unset($form_params['tree']);
518
  }
519
  // else {
520
  //   $form_params['ignore_classification'] =  NULL;
521
  // }
522

    
523
  // Store in session.
524
  $_SESSION['cdm']['search'] = $form_params;
525

    
526
  return $form_params;
527
}
528

    
529
/**
530
 * Provides the classification to which the last search has been limited to..
531
 *
532
 * This function should only be used after the cdm_dataportal_search_execute()
533
 * handler has been run, otherwise it will return the infomation from the last
534
 * search executed. The information is retrieved from
535
 * the $_SESSION variable:  $_SESSION['cdm']['search']['tree']
536
 *
537
 * @return object
538
 *   the CDM classification instance which has been used a filter for the
539
 *   last processed search
540
 *   or NULL, it it was on all classifications
541
 */
542
function cdm_dataportal_searched_in_classification() {
543

    
544
  $classification = &drupal_static(__FUNCTION__);
545

    
546
  if (!isset($classification)) {
547
    if (isset($_SESSION['cdm']['search']['tree'])) {
548
      $classification = cdm_ws_get(CDM_WS_PORTAL_TAXONOMY, ($_SESSION['cdm']['search']['tree']));
549
    }
550
    else {
551
      $classification = FALSE;
552
    }
553
  }
554

    
555
  return $classification !== FALSE ? $classification : NULL;
556
}
557

    
558
/**
559
 * Removes Drupal internal form elements from query.
560
 */
561
function cdm_dataportal_search_process($form, &$form_state) {
562
  unset($form['form_id']);
563
  unset($form['form_token']);
564
  return $form;
565
}
566

    
567
/**
568
 * Sends a search request at the cdm web server.
569
 *
570
 * The parameters to build the query are taken obtained by calling
571
 * cdm_dataportal_search_form_request() which reads the query parameters
572
 * from $_REQUEST and add additional query parameters if nessecary.
573
 *
574
 * @see cdm_dataportal_search_form_request()
575
 */
576
function cdm_dataportal_search_execute() {
577

    
578
  // Store as last search in session.
579
  $_SESSION['cdm']['last_search'] = $_SERVER['REQUEST_URI'];
580

    
581
  // Validate the search webservice parameter:
582
  if (!isset($_REQUEST['ws'])) {
583
    drupal_set_message(
584
      t("Invalid search webservice parameter 'ws' given"), 'warning'
585
    );
586
    return NULL;
587
  }
588
  if (!cdm_dataportal_search_form_path_for_ws($_REQUEST['ws'])) {
589
    // Endpoint is unknown.
590
    drupal_set_message(
591
      t("Invalid search webservice parameter 'ws' given"), 'warning'
592
    );
593
    return NULL;
594
  }
595

    
596
  // Read the query parameters from $_REQUEST and add additional query
597
  // parameters if necessary.
598
  $request_params = cdm_dataportal_search_form_request();
599

    
600
  $taxon_pager = cdm_ws_get($_REQUEST['ws'], NULL, queryString($request_params));
601

    
602
  return $taxon_pager;
603
}
604

    
605
/**
606
 * Transforms the termDTO tree into options array.
607
 *
608
 *   TermDto:
609
 *      - partOfUuid:
610
 *      - representation_L10n:
611
 *      - representation_L10n_abbreviatedLabel:
612
 *      - uuid:
613
 *      - vocabularyUuid:
614
 *      - children: array of TermDto
615
 *
616
 * The options array is suitable for drupal form API elements that
617
 * allow multiple choices.
618
 * @see http://api.drupal.org/api/drupal/developer!topics!forms_api_reference.html/7#options
619
 *
620
 * @param array $term_dto_tree
621
 *   a hierarchic array of CDM TermDto instances, with additional
622
 * 'children' field:
623
 * @param array $options
624
 *   Internally used for recursive calls
625
 * @param string $prefix
626
 *   Internally used for recursive calls
627
 *
628
 * @return array
629
 *   the terms in an array as options for a form element that allows
630
 *   multiple choices.
631
 */
632
function term_tree_as_options($term_dto_tree, &$options = array(), $prefix = '') {
633

    
634
  foreach ($term_dto_tree as $uuid => $dto) {
635
    $label = $prefix . '<span class="child-label">'
636
      .  $dto->representation_L10n
637
      . '</span><span class="child-label-abbreviated"> (' . $dto->representation_L10n_abbreviatedLabel . ')</span>';
638
    $options[$uuid] = $label;
639
    if (isset($dto->children) && is_array($dto->children)) {
640
      uasort($dto->children, 'compare_terms_by_representationL10n');
641
      term_tree_as_options(
642
        $dto->children,
643
        $options, $prefix
644
          . '<span data-cdm-parent="' . $uuid . '" class="parent"></span>');
645
    }
646
  }
647

    
648
  return $options;
649
}
(11-11/16)