commit 72d57201d9c9b557895fd7ede7a277f84d1d9b76
Author: Katja Luther <k.luther@bgbm.org>
Date:   Thu Jun 6 13:57:38 2019 +0200

    ref #8182: specimen tree is collapsable, blast result table with clickable details

diff --git a/modules/cdm_dataportal/cdm_dataportal.search.php b/modules/cdm_dataportal/cdm_dataportal.search.php
index c5111d25..2a323ae8 100755
--- a/modules/cdm_dataportal/cdm_dataportal.search.php
+++ b/modules/cdm_dataportal/cdm_dataportal.search.php
@@ -786,32 +786,18 @@ function cdm_dataportal_search_request($search_endpoint)
  */
 function cdm_dataportal_blast_search_request($search_endpoint)
 {
-
     $form_params = array();
 
     if (isset($_REQUEST['search']) && is_array($_REQUEST['search'])) {
         array_deep_copy($_REQUEST['search'], $form_params['data']);
     }
-
-
-    //$query = trim($_REQUEST['query']);
-    $form_params['data'] = formatParams($_REQUEST['search']);
-
-    /*if (isset($_REQUEST['pager']) && is_array($_REQUEST['pager'])) {
-        $form_params = array_merge($form_params, $_REQUEST['pager']);
-    }*/
-
-    $form_params['query']= trim($_REQUEST['query']);
-
-
+    $form_params['data'] = formatWSParams($_REQUEST['search']);
+    $form_params['query']= trim($_REQUEST['query']).$form_params['data'];
     // Store in session.
     $_SESSION['cdm']['search'] = $form_params;
-
     return $form_params;
 }
 
-
-
 /**
  * Provides the classification to which the last search has been limited to..
  *
@@ -933,7 +919,7 @@ function cdm_dataportal_search_blast_execute() {
     // parameters if necessary.
     $request_params = cdm_dataportal_blast_search_request($_REQUEST['ws']);
    // $url = drupal_http_build_query($_REQUEST['ws'], $request_params);
-
+    $request_params['timeout'] = 200;
     $taxon_pager = drupal_http_request($_REQUEST['ws'].'?sequence='.$request_params['query'], $request_params);
 
     return $taxon_pager;
diff --git a/modules/cdm_dataportal/includes/common.inc b/modules/cdm_dataportal/includes/common.inc
index 4bc4c4bf..105c62ac 100755
--- a/modules/cdm_dataportal/includes/common.inc
+++ b/modules/cdm_dataportal/includes/common.inc
@@ -600,3 +600,16 @@ function formatParams($params) {
     return $paramString;
 }
 
+function formatWSParams($params) {
+    if (is_array($params)){
+        $keys =array_keys($params);
+        $paramString = '';
+        foreach ($keys as $k ){
+            if ($k != 'pageNumber' && $k != 'pageSize'){
+                $paramString .= '&'.$k.'='.urlencode($params[$k]);
+            }
+        }
+    }
+    return $paramString;
+}
+
diff --git a/modules/cdm_dataportal/includes/occurrences.inc b/modules/cdm_dataportal/includes/occurrences.inc
index 42c22cf8..c2b12461 100755
--- a/modules/cdm_dataportal/includes/occurrences.inc
+++ b/modules/cdm_dataportal/includes/occurrences.inc
@@ -469,9 +469,9 @@ function compose_cdm_specimen_or_observation($specimen_or_observation, $isSpecim
                                 $taxon_name = cdm_ws_get(CDM_WS_NAME, $determinationEvent->taxonName->uuid);
                                 $taxon_name->taggedName = cdm_ws_get(CDM_WS_NAME, array($determinationEvent->taxonName->uuid, "taggedName"));
                                 $name_link = path_to_name($determinationEvent->taxonName->uuid);
-                            }else if ($determinationEvent->taxon) {
-                                 $taxon_name = cdm_ws_get(CDM_WS_TAXON . '/$0/name', $determinationEvent->taxon->uuid);
-                                 $name_link = path_to_taxon($determinationEvent->taxon->uuid);
+                            } else if ($determinationEvent->taxon) {
+                                $taxon_name = cdm_ws_get(CDM_WS_TAXON . '/$0/name', $determinationEvent->taxon->uuid);
+                                $name_link = path_to_taxon($determinationEvent->taxon->uuid);
                             }
                             if ($taxon_name) {
                                 $taxon_html = render_taxon_or_name($taxon_name, $name_link);
@@ -501,9 +501,9 @@ function compose_cdm_specimen_or_observation($specimen_or_observation, $isSpecim
                         foreach ($value as $description) {
                             $description = cdm_ws_get(CDM_WS_PORTAL_DESCRIPTION, $description->uuid);
 
-                        if($description->imageGallery == TRUE) {
-                            continue;
-                        }
+                            if ($description->imageGallery == TRUE) {
+                                continue;
+                            }
                             $elements_by_feature = _mergeFeatureTreeDescriptions($occurrence_featureTree->root->childNodes, $description->elements);
                             $description_render_elements = _block_get_renderable_array(make_feature_block_list($elements_by_feature, null));
                             $dd_elements[] = $description_render_elements;
@@ -512,7 +512,7 @@ function compose_cdm_specimen_or_observation($specimen_or_observation, $isSpecim
                         @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $dd_elements);
                         break;
                     case '_derivedUnitMedia':
-                        if ($isSpecimen_page){
+                        if ($isSpecimen_page) {
                             $gallery_settings = getGallerySettings(CDM_DATAPORTAL_SPECIMEN_GALLERY_NAME);
                             $captionElements = array(
                                 '#uri' => t('open media'),
@@ -528,10 +528,10 @@ function compose_cdm_specimen_or_observation($specimen_or_observation, $isSpecim
                                 'alternativeMediaUri' => NULL,
                                 'galleryLinkUri' => NULL,
                             ));
-                            @_description_list_group_add($groups, "Detail Images:" , markup_to_render_array($gallery_html),'',20);
+                            @_description_list_group_add($groups, "Detail Images:", markup_to_render_array($gallery_html), '', 20);
                         }
 
-                       // $dd_elements[] = markup_to_render_array($gallery_html);
+                        // $dd_elements[] = markup_to_render_array($gallery_html);
 
                         break;
                     case 'sources':
@@ -546,8 +546,8 @@ function compose_cdm_specimen_or_observation($specimen_or_observation, $isSpecim
                             NULL,
                             ''
                         );
-                        if(!empty($annotations_and_sources['source_references'])){
-                            @_description_list_group_add($groups, t('Sources') . ':', join(', ', $annotations_and_sources['source_references']),'',12 );
+                        if (!empty($annotations_and_sources['source_references'])) {
+                            @_description_list_group_add($groups, t('Sources') . ':', join(', ', $annotations_and_sources['source_references']), '', 12);
                         }
                         break;
 
@@ -559,14 +559,14 @@ function compose_cdm_specimen_or_observation($specimen_or_observation, $isSpecim
                             foreach ($derivedFrom->originals as $original) {
                                 $pathToSpecimen = path_to_specimen($original->uuid);
                                 $description = "";
-                                if (isset( $derivedFrom->description) && $derivedFrom->description != ''){
+                                if (isset($derivedFrom->description) && $derivedFrom->description != '') {
                                     $description = $derivedFrom->description . ": ";
                                 }
 
                                 $originals[] = markup_to_render_array(l($description . $original->titleCache, $pathToSpecimen, array('attributes' => array('target' => '_blank'))));
-                                if ($original->class == 'FieldUnit'){
+                                if ($original->class == 'FieldUnit') {
                                     $label = t('Field data');
-                                }else{
+                                } else {
                                     $label = t('Derived from');
                                 }
                                 @_description_list_group_add($groups, $label . ':',
@@ -588,10 +588,11 @@ function compose_cdm_specimen_or_observation($specimen_or_observation, $isSpecim
                                     }
 
                                     $derived_units[] = markup_to_render_array(l($description . $derived_unit->titleCache, $pathToSpecimen, array('attributes' => array('target' => '_blank'))));
-                                 }
-                            } @_description_list_group_add($groups, t('Derivates') . ':',
+                                }
+                            }
+                            @_description_list_group_add($groups, t('Derivates') . ':',
                                 $derived_units,
-                                    '', 100);
+                                '', 100);
 
                         }
                         break;
@@ -616,7 +617,43 @@ function compose_cdm_specimen_or_observation($specimen_or_observation, $isSpecim
                     case 'storedUnder':
                         @_description_list_group_add($groups, cdm_occurrence_field_name_label('storedUnder'), render_taxon_or_name($value));
                         break;
+                    case 'dnaQuality':
+                        $sub_dl_groups = array();
+
+                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('purificationMethod'), $value->purificationMethod, NULL, 1);
+                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('ratioOfAbsorbance260_230'), $value->ratioOfAbsorbance260_230, NULL, 2);
+                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('ratioOfAbsorbance260_280'), $value->ratioOfAbsorbance260_280, NULL, 3);
+                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('concentration'), $value->concentration, NULL, 4);
+                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('concentrationUnit'), $value->concentrationUnit, NULL, 4);
+                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('qualityTerm'), $value->qualityTerm, NULL, 4);
+                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('qualityCheckDate'), $value->qualityCheckDate, NULL, 4);
+
+                        if (is_array($sub_dl_groups) && sizeof($sub_dl_groups)>0) {
+                            @_description_list_group_add($groups, cdm_occurrence_field_name_label($field),
+                                array(
+                                    array('#markup' => $value->titleCache),
+                                    array('#theme' => 'description_list', '#groups' => $sub_dl_groups)
+                                )
+                            );
+                        }
+                        break;
+
+                    case 'preservation':
+                        $sub_dl_groups = array();
 
+                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('medium'), $value->medium, NULL, 1);
+                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('temperature'), $value->temperature, NULL, 2);
+                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('definedMaterialOrMethod'), $value->definedMaterialOrMethod, NULL, 3);
+
+                        if (is_array($sub_dl_groups) && sizeof($sub_dl_groups)>0) {
+                            @_description_list_group_add($groups, cdm_occurrence_field_name_label($field),
+                                array(
+                                    array('#markup' => $value->titleCache),
+                                    array('#theme' => 'description_list', '#groups' => $sub_dl_groups)
+                                )
+                            );
+                        }
+                        break;
 
                     /* ---- Specimen --- */
                     case 'sequences':
@@ -1064,7 +1101,9 @@ function compose_cdm_specimen_or_observation_tree_entry($specimen_or_observation
                     case 'kindOfUnit':
                         @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $value, NULL, 1);
                         break;
-
+                    case 'accessionNumber':
+                        @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $value, NULL, 0);
+                        break;
 
                     case 'preferredStableUri':
 
@@ -1092,7 +1131,7 @@ function compose_cdm_specimen_or_observation_tree_entry($specimen_or_observation
                         );
                         $gallery_html = compose_cdm_media_gallerie(array(
                             'mediaList' => $value,
-                            'galleryName' => $specimen_or_observation->label,
+                            'galleryName' => $specimen_or_observation->uuid,
                             'maxExtend' => $gallery_settings['cdm_dataportal_media_maxextend'],
                             'cols' => $gallery_settings['cdm_dataportal_media_cols'],
                             'maxRows' => isset($gallery_settings['cdm_dataportal_media_maxRows']) ? isset($gallery_settings['cdm_dataportal_media_maxRows']) : null,
@@ -1209,6 +1248,19 @@ function compose_cdm_specimen_or_observation_tree_entry($specimen_or_observation
                     case 'derivationEvents':
                         //@_description_list_group_add($groups, t('Association type'), $value->description);
                         break;
+                    case 'determinedNames':
+                        $dd_elements = array();
+                        foreach ($value as $name) {
+                            $taxon_name = cdm_ws_get(CDM_WS_NAME, $name->key);
+                            $taxon_name->taggedName = cdm_ws_get(CDM_WS_NAME, array($name->key, "taggedName"));
+                            $name_link = path_to_name($name->key);
+
+                            //$taxon_html = render_taxon_or_name($taxon_name, $name_link);
+                            $taxon_html = l($taxon_name->titleCache, $name_link, array('attributes' => array('target' => '_blank')));
+                            $dd_elements[] = $taxon_html;
+                        }
+                        @_description_list_group_add($groups, cdm_occurrence_field_name_label("Identification(s)"), $dd_elements,'', 100);
+                        break;
 
 
                     default:
@@ -1240,13 +1292,31 @@ function compose_cdm_specimen_or_observation_tree_entry($specimen_or_observation
             $output .= $gallery_html;
         }
         $pathToSpecimen = path_to_specimen($specimen_or_observation->uuid);
-        $output .=  l("detail page", $pathToSpecimen, array('attributes' => array('target' => '_blank')));
+        $output .=  l("Detail page", $pathToSpecimen, array('attributes' => array('target' => '_blank')));
     } // END of $specimenOrObservation exists
 
     return $output;
 }
 
 function compose_table_of_blast_result(array $data){
+   // get icon images
+  $expand_icon = font_awesome_icon_markup(
+      'fa-plus-square-o',
+      array(
+          'alt' => 'Show details',
+          'class' => array('expand_icon')
+      )
+  );
+  $collapse_icon = font_awesome_icon_markup(
+      'fa-minus-square-o',
+      array(
+          'alt' => 'Show details',
+          'class' => array('collapse_icon')
+      )
+  );
+  //$detail_image_icon = '<img title="Detail Image" src="' . base_path() . drupal_get_path('module', 'cdm_dataportal') . '/images/detail_image_derivate-16x16-32.png' . '"/>';
+    $rowcount = 0;
+    $rows = array();
 
     foreach ($data as $row_data){
         $pathToSpecimen = path_to_specimen_by_accession_number($row_data['id']);
@@ -1254,6 +1324,10 @@ function compose_table_of_blast_result(array $data){
 
         $rows[] =  array(
             'data' => array(
+                array(
+                    'data' => $expand_icon . $collapse_icon,
+                    'class' => array('summary_row_cell', 'summary_row_icon', 'expand_column')
+                ),
                 array(
                     'data' => $row_data['def'],
                 ),
@@ -1263,21 +1337,53 @@ function compose_table_of_blast_result(array $data){
                 array(
                     'data' => $row_data['hsp_align_length'],
                 ),
-              //  array(
-              //     'data' => $row_data['midline'],
-              //  ),
                 array(
-                    'data' => $row_data['hsp_evalue'],
+                   'data' => $row_data['hsp_identity'],
+                ),
+                array(
+                    'data' => $row_data['hsp_identity']/$row_data['hsp_align_length']*100,
                 )
-            )
+            ),
+            'id' => 'blast_summary' . $rowcount, // summary row id
+            'class' => array('summary_row'),
+        );
+        $detail_html = "";
+
+        $detail_html .= create_label("Details") . $row_data["hsp_align_length"] . "<br>";
+
+
+        $detail_html .= "<br>";
+        $detail_html .= $row_data["hsp_midline"];
+
+        //$detail_html .= "<br>";
+
+        $rows[] = array(
+            'data' => array(
+                array(
+                    'data' => "", //empty first column
+                    'class' => array('expand_column')
+                ),
+                array(
+                    'data' => $detail_html,
+                    'colspan' => 5,
+                ),
+            ),
+            'id' => 'blast_detail' . $rowcount,//details row ID
+            'class' => array('detail_row'),
         );
+        $rowcount++;
     }
+
     $tableId = "blast_result_table";
     $blast_result_table = array(
         "#theme" => "table",
         "#weight" => 2,
         "#header" => array(
-                        "Name", "id", "Align Length", "e Value"),
+            array(
+                'data' => "",
+                'class' => array('expand_column')
+            ),
+                        "Name", "Accession Number", "Align Length", "Identity", "% Identity"),
         "#rows" => $rows,
         "#attributes" => array(
             "id" => $tableId,
@@ -1287,11 +1393,9 @@ function compose_table_of_blast_result(array $data){
 
     drupal_add_js_rowToggle("#".$tableId);
 
-    $render_array['content'] = $blast_result_table;
+    $render_array[$tableId] = $blast_result_table;
     $out = drupal_render($render_array);
    //$blast_result_page-> content = drupal_render($render_array);
    return $out;
 }
 
-
-
diff --git a/modules/cdm_dataportal/includes/pages.inc b/modules/cdm_dataportal/includes/pages.inc
index 21765c2a..17b01fa6 100755
--- a/modules/cdm_dataportal/includes/pages.inc
+++ b/modules/cdm_dataportal/includes/pages.inc
@@ -159,38 +159,72 @@ function cdm_dataportal_taxon_page_specimens($taxon) {
         );
     }
     else if(variable_get('cdm_dataportal_specimen_derivate_tree')){
+
+        $expand_icon = font_awesome_icon_markup(
+            'fa-plus-square-o',
+            array(
+                'alt' => 'Show details',
+                'class' => array('expand_icon')
+            )
+        );
+        $collapse_icon = font_awesome_icon_markup(
+            'fa-minus-square-o',
+            array(
+                'alt' => 'Show details',
+                'class' => array('collapse_icon')
+            )
+        );
+        $tableId = "specimen_tree_table";
         $specimen_table = array(
             '#theme' => 'table',
             '#weight' => 2,
             // prefix attributes and rows with '#' to let it pass toF the theme function,
             // otherwise it is handled as child render array
-            '#attributes' => array('class' => 'specimens'),
+            '#attributes' => array('class' => 'specimens',
+                                    'id' => $tableId),
             '#rows' => array(),
         );
         $specimen_array = compose_specimen_array($specimensOrObservations);
-
+        $rowcount = 0;
         foreach($specimen_array as $value){
             $renderArray = array(
                 '#theme' => 'item_list',
-                '#items' => array($value),
+                '#items' => $value['children'],
                 '#type' => 'ul');
             $output = drupal_render($renderArray);
-//            $specimen_table['#rows'][] = array(
-//                // An array of table rows. collabsible row
-//                'data' => "",
-//                'class' => array('expand_column')
-//            );
+
             $specimen_table['#rows'][] = array(
-                // An array of table rows. Every row is an array of cells, or an associative array
-                'data' => array($output),
-                'class' =>  array(
-                    'descriptionElement',
-                    'descriptionElement_IndividualsAssociation'
-                ),
-            );
+                'data' =>array(
+                    array(
+                        'data' => $expand_icon . $collapse_icon,
+                        'class' => array('summary_row_cell', 'summary_row_icon', 'expand_column')
+                    ),
+                    $value['data']),
 
+                'id' => 'label' . $rowcount, // summary row id
+                'class' => array('summary_row'),
+            );
+            $specimen_table['#rows'][] = array(
+                'data' =>  array(
+                        array(
+                            'data' => "", //empty first column
+                            'class' => array('expand_column')
+                        ),
+                        array(
+                        'data' => $output
+
+                        )
+                    ),
+                    'class' =>  array('detail_row')
+//                'class' =>  array(
+//                    'descriptionElement',
+//                    'descriptionElement_IndividualsAssociation'
+ //               ),
+            );
+            $rowcount++;
 
         }
+        drupal_add_js_rowToggle("#".$tableId);
 
         $render_array['specimen_list'] = $specimen_table;
 
diff --git a/modules/cdm_dataportal/theme/cdm_dataportal.page.theme b/modules/cdm_dataportal/theme/cdm_dataportal.page.theme
index 5947cfdc..42d0f68b 100755
--- a/modules/cdm_dataportal/theme/cdm_dataportal.page.theme
+++ b/modules/cdm_dataportal/theme/cdm_dataportal.page.theme
@@ -99,14 +99,81 @@ function theme_cdm_specimen_page_title($variables)
         $out .= "Specimen ";
     }
 
-  if($collection){
-    $out .= $collection." ";
-  }
-  $out .= $specimenID;
+    if($collection){
+        $out .= $collection." ";
+    }
+    $out .= $specimenID;
 
-  RenderHints::popFromRenderStack();
+    RenderHints::popFromRenderStack();
+
+    return '<span class="' . $specimen->class . '">' . $out . '</span>';
+}
+
+/**
+ * Returns HTML for the default title of a specimen page.
+ *  * The returned title is a the identifier of the specimen.
+ *
+ * @param array $variables
+ *   An associative array containing:
+ *   - specimen: The specimen being formatted for the title.
+ *
+ * @return string
+ *  Markup for the title of a specimen page
+ *
+ * @ingroup themeable
+ */
+function theme_cdm_specimen_dto_page_title($variables)
+{
+
+    $specimen = $variables['specimen'];
+    RenderHints::pushToRenderStack('specimen_page_title');
+    $referenceUri = '';
+    $out = '';
+
+    $collection = null;
+    if (!($specimen->class == 'FieldUnit')) {
+        if ($specimen->collection) {
+            if ($specimen->collection->code) {
+                $collection = $specimen->collection->code;
+            } elseif ($specimen->collection->name) {
+                $collection = $specimen->collection->name;
+            }
+        }
+        if ($specimen->accessionNumber) {
+            $specimenID = $specimen->accessionNumber;
+        } elseif ($specimen->barcode) {
+            $specimenID = $specimen->barcode;
+        } elseif ($specimen->catalogNumber) {
+            $specimenID = $specimen->catalogNumber;
+        } elseif ($specimen->titleCache) {
+            $specimenID = $specimen->titleCache;
+        }
+        if (!isset($specimenID) and !isset($collection)) {
+            $specimenID = $specimen->uuid;
+        }
+    }else{
+        if ($specimen->titleCache) {
+            $specimenID = $specimen->titleCache;
+        }
+        if (!isset($specimenID) and !isset($collection)) {
+            $specimenID = $specimen->uuid;
+        }
+    }
+
+    if ($specimen ->class == 'FieldUnit'){
+        $out .= "FieldUnit ";
+    }else{
+        $out .= "Specimen ";
+    }
+
+    if($collection){
+        $out .= $collection." ";
+    }
+    $out .= $specimenID;
+
+    RenderHints::popFromRenderStack();
 
-  return '<span class="' . $specimen->class . '">' . $out . '</span>';
+    return '<span class="' . $specimen->class . '">' . $out . '</span>';
 }
 
 /**
