Browse Source

Merge branch '7.x-3.x' of https://github.com/tripal/tripal into 7.x-3.x

Lacey Sanderson 7 years ago
parent
commit
228ab686a4

+ 235 - 143
tripal_chado/api/modules/tripal_chado.cv.api.inc

@@ -366,42 +366,86 @@ function tripal_update_cvtermpath($cv_id, $job_id = NULL) {
 }
 
 /**
+ * Duplicate of fill_cvtermpath() stored procedure in Chado.
  *
- * @param unknown $cv_id
- * @param string $job_id
+ * Identifies all of the root terms of the controlled vocabulary. These
+ * root terms are then processed by calling the
+ * tripal_update_cvtermpath_root_loop() function on each one.
+ *
+ * @param $cvid
+ *   The controlled vocabulary ID from the cv table of Chado (i.e. cv.cv_id).
+ * @param $job_id
  */
 function tripal_update_cvtermpath_bak($cv_id, $job_id = NULL){
-  chado_set_active('chado');
-  $result = db_query('
-    SELECT DISTINCT t.*
-    FROM cvterm t
-      LEFT JOIN cvterm_relationship r ON (t.cvterm_id = r.subject_id)
-      INNER JOIN cvterm_relationship r2 ON (t.cvterm_id = r2.object_id)
-    WHERE t.cv_id = :cvid AND r.subject_id is null',
-    array(':cvid' => $cv_id)
-  );
+  // TODO: there's a function to determine the current Chado instance.
+  // we should use that.
+  $prev_db = chado_set_active('chado');
+  try {
+    $result = db_query('
+      SELECT DISTINCT t.*
+      FROM cvterm t
+        LEFT JOIN cvterm_relationship r ON (t.cvterm_id = r.subject_id)
+        INNER JOIN cvterm_relationship r2 ON (t.cvterm_id = r2.object_id)
+      WHERE t.cv_id = :cvid AND r.subject_id is null',
+      array(':cvid' => $cv_id)
+    );
 
-  $record = $result->fetchObject();
-  tripal_update_cvtermpath_root_loop($record->cvterm_id, $record->cv_id);
+    // Iterate through each root level term.
+    $record = $result->fetchAll();
+    $roots = array();
+    foreach ($record as $item){
+      tripal_update_cvtermpath_root_loop($item->cvterm_id, $item->cv_id, $roots);
+    }
+  }
+  catch (Exception $e) {
+    // If there's an exception we have to set the database back. So, do that
+    // and then rethrow the error.
+    chado_set_active($prev_db);
+    throw $e;
+  }
+  chado_set_active($prev_db);
 }
 
 /**
+ *  Duplicate of _fill_cvtermpath4root() stored procedure in Chado.
+ *
+ *  This function process a "branch" of the ontology.  Initially, the
+ *  "root" starts at the top of the tree. But, as the cvtermpath is populated
+ *  the "root" becomes terms deeper in the tree.
  *
- * @param unknown $rootid
- * @param unknown $cvid
+ * @param $rootid
+ *   The term ID from the cvterm table of Chado (i.e. cvterm.cvterm_id).
+ * @param $cvid
+ *   The controlled vocabulary ID from the cv table of Chado (i.e. cv.cv_id).
  */
-function tripal_update_cvtermpath_root_loop($rootid, $cvid){
-  chado_set_active('chado');
+function tripal_update_cvtermpath_root_loop($rootid, $cvid, &$roots){
+
+  // Get's the cvterm record for this "root".
   $ttype = db_select('cvterm', 'cv')
           ->fields('cv', array('cvterm_id'));
   $db_or = db_or();
-  $db_or->condition('cv.name', "isa", '=' );
-  $db_or->condition('cv.name', "is_a", '=' );
+  $db_or->condition('cv.name', "isa", '=');
+  $db_or->condition('cv.name', "is_a", '=');
   $ttype->condition($db_or);
   $result = $ttype->execute()->fetchObject();
 
-  $result = tripal_update_cvtermpath_loop($rootid, $rootid, $cvid, $result->cvterm_id, 0, 0, array());
+  $term_id = $rootid . '|' . $rootid . '|' . $cvid . '|' . $result->cvterm_id;
+  // If the child_id matches any other id in the array then we've hit a loop.
+  foreach ($roots as $element_id) {
+    if ($element_id == $term_id) {
+      return;
+    }
+  }
+  // Then add that new entry to the $tree_path.
+  $roots[] =  $term_id;
+
+  // Descends through the branch starting at this "root" term.
+  $visited = array();
+  $depth = 0;
+  tripal_update_cvtermpath_loop($rootid, $rootid, $cvid, $result->cvterm_id, $depth, 0, $visited);
 
+  // Get's the children terms of this "root" term and then recursively calls
+  // this function making each child root.
   $cterm = db_query(
     'SELECT *
      FROM cvterm_relationship
@@ -409,30 +453,40 @@ function tripal_update_cvtermpath_root_loop($rootid, $cvid){
     ',
     array(':rootid' => $rootid)
   );
-
   while($cterm_result = $cterm->fetchAssoc()) {
-    if ($result === 'LOOP'){
-      watchdog('debug', '<pre>$result: ' . print_r($result, TRUE) . '</pre>');
-
-      continue;
-    }
-    else {
-      tripal_update_cvtermpath_root_loop($cterm_result['subject_id'], $cvid);
-    }
+    tripal_update_cvtermpath_root_loop($cterm_result['subject_id'], $cvid, $roots);
   }
 }
 
 /**
  *
  * @param $origin
+ *   The root terms cvterm_id.
  * @param $child_id
+ *   The cvterm_id of the current child term.  The child term is a descendent
+ *   of the origin.
  * @param $cv_id
+ *   The controlled vocabulary ID from the cv table of Chado (i.e. cv.cv_id).
  * @param $type_id
+ *   The relationship type between the origin term and the child.
  * @param $depth
+ *   The depth of the recursion.
+ * @param $increment_of_depth.
+ *   An integer ??
+ * @param $tree_path.
+ *   The array of every term between the current child and the origin. Each
+ *   element in the array is an associative array with the keys:
+ *     -build_id: an string identifier for the child that combines the origin,
+ *      child cvterm_id,cv_id, and the type_id.
+ *     -depth: the depth that a child was inserted into the cvtermpath table.
  * @return multitype:
  */
-function tripal_update_cvtermpath_loop($origin, $child_id, $cv_id, $type_id, $depth, $increment_of_depth, $array_of_children){
+$loop_data;
 
+function tripal_update_cvtermpath_loop($origin, $child_id, $cv_id, $type_id, $depth,
+                                       $increment_of_depth, $tree_path){
+  // An array of
+  global $loop_data;
   // Check to see if a row with these values already exists.
   chado_set_active('chado');
   $count =  db_query(
@@ -446,63 +500,81 @@ function tripal_update_cvtermpath_loop($origin, $child_id, $cv_id, $type_id, $de
     array(':cvid' => $cv_id, ':origin' => $origin, ':child_id' => $child_id, ':depth' => $depth)
   );
   $count_total = $count->rowCount();
-
-  try{
-    if($count_total == 0) {
-      // If row with values does not already exist write to table.
-      chado_set_active('chado');
-
-      $query = db_insert('cvtermpath')
-        ->fields(array(
-          'object_id' => $origin,
-          'subject_id' => $child_id,
-          'cv_id' => $cv_id,
-          'type_id' => $type_id,
-          'pathdistance' => $depth,
-        ));
-      $rows = $query->execute();
-      //watchdog('debug', '<pre>$rows: ' . print_r($rows, TRUE) . '</pre>');
-
-     // if($rows) {
-        // Build the ID.
-        $children_id = $origin . '|' . $child_id . '|' . $cv_id . '|' . $type_id;
-        // Now check if the most recent entry already exists in the array.
-        if ($increment_of_depth != 0) {
-          // Search the $array_of_children for the new $child_id in the build_id column.
-          foreach ($array_of_children as $key => $val) {
-            if ($val['build_id'] == $children_id) {
-              // If the search returns something check for a possible loop.
-              $result_of_loop_checker = tripal_update_cvtermpath_loop_checker($origin, $child_id, $cv_id, $type_id, $depth, $increment_of_depth, 0, $val, [], $depth);
-              watchdog('debug', '<pre>tripal_update_cvtermpath_loop  $result_of_loop_checker: ' . print_r($result_of_loop_checker, TRUE) . '</pre>');
-              if ($result_of_loop_checker) {
-                watchdog('debug', 'Loop found exit the loop function');
-                return 'LOOP';
-              }
+  // If we've already seen this term then just return, we don't want
+  // to insert it again.
+  if ($count_total > 0) {
+    return $loop_data;
+  }
+  // Build the ID.
+  $term_id = $origin . '|' . $child_id . '|' . $cv_id . '|' . $type_id;
+  // Now check if the most recent entry already exists in the array.
+  if ($increment_of_depth != 0 && empty($loop_data)) {
+    // Search the $tree_path for the new $child_id in the build_id column.
+    foreach ($tree_path as $parent) {
+      // If this child is the same as a parent term that has already been
+      // processed then we have a potential loop.
+      if ($parent['build_id'] == $term_id) {
+        // The loop checker function below.
+        $result_of_loop_checker = tripal_update_cvtermpath_loop_checker($origin,
+          $child_id, $cv_id, $type_id, $depth, $increment_of_depth, 0,
+          $parent, array(), $depth);
+        if (!empty($result_of_loop_checker)) {
+          $loop_data = $result_of_loop_checker;
+          //Find the depth of the loop start by finding it in the array_of_children
+          foreach($tree_path as $children => $child){
+            if($child['build_id'] == $loop_data['build_id']){
+              $loop_location = $child['depth'];
             }
           }
+          $array_loop_data = (array)$loop_data;
+          $array_loop_data['depth'] = $loop_location;
+          $loop_data = $array_loop_data;
+          break;
         }
-        // Then add that new entry to the $array_of_children.
-        $array_of_children[$increment_of_depth] = [
-          'build_id' => $children_id,
-          'depth' => $depth
-        ];
-
-        $query = db_select('cvterm_relationship', 'cvtr')
-          ->fields('cvtr')
-          ->condition('cvtr.object_id', $child_id, '=')
-          ->execute();
-        $cterm = $query->fetchAll();
-
-        foreach ($cterm as $item) {
-          $increment_of_depth++;
-          tripal_update_cvtermpath_loop($origin, $item->subject_id, $cv_id, $item->type_id, $depth + 1, $increment_of_depth, $array_of_children);
-        }
-     // }
+      }
+      if (!empty($loop_data)) {
+        return $loop_data;
+      }
     }
   }
-  catch(Exception $e){
-    watchdog_exception('tripal_ds', $e);
-    return FALSE;
+  // We have not detected a loop, so it's safe to insert the term.
+  $query = db_insert('cvtermpath')
+    ->fields([
+      'object_id' => $origin,
+      'subject_id' => $child_id,
+      'cv_id' => $cv_id,
+      'type_id' => $type_id,
+      'pathdistance' => $depth,
+    ]);
+  $rows = $query->execute();
+  // Then add that new entry to the $tree_path.
+  $tree_path[$increment_of_depth] = [
+    'build_id' => $term_id,
+    'depth' => $depth
+  ];
+  // Get all of the relationships of this child term, and recursively
+  // call the tripal_update_cvtermpath_loop() function to continue
+  // descending down the tree.
+  $query = db_select('cvterm_relationship', 'cvtr')
+    ->fields('cvtr')
+    ->condition('cvtr.object_id', $child_id, '=')
+    ->execute();
+  $cterm_relationships = $query->fetchAll();
+  foreach ($cterm_relationships as $item) {
+    if (!empty($loop_data)) {
+      if ($loop_data['depth'] < $depth) {
+        break;
+      }
+      elseif ($loop_data['depth'] > $depth) {
+        $loop_data = NULL;
+        break;
+      }
+    }
+    else {
+      $increment_of_depth++;
+      tripal_update_cvtermpath_loop($origin, $item->subject_id, $cv_id,
+        $item->type_id, $depth + 1, $increment_of_depth, $tree_path);
+    }
   }
 }
 
@@ -520,89 +592,109 @@ function tripal_update_cvtermpath_loop($origin, $child_id, $cv_id, $type_id, $de
  *
  * @return bool
  */
-function tripal_update_cvtermpath_loop_checker($origin, $child_id, $cv_id, $type_id, $depth, $increment_of_depth, $distance_between_parent_child, $possible_start_of_loop, $array_of_possible_loop, $depth_at_start_of_loop){
-    chado_set_active('chado');
-    $query = db_select('cvterm_relationship', 'cvtr')
-      ->fields('cvtr')
-      ->condition('cvtr.object_id', $child_id, '=')
-      ->execute();
-    $cterm = $query->fetchAll();
+function tripal_update_cvtermpath_loop_checker($origin, $child_id, $cv_id, $type_id,
+    $depth, $increment_of_depth, $distance_between_parent_child, $possible_start_of_loop,
+    $array_of_possible_loop, $depth_at_start_of_loop){
 
-    foreach ($cterm as $item){
-      if ($distance_between_parent_child > 0){
-        // Search the $array_of_children for the new $child_id in the build_id column.
-        foreach ($array_of_possible_loop as $key => $val) {
-          if ($val['build_id'] === $possible_start_of_loop['build_id']) {
-            $possible_loop_starts = $val;
-            // If the search returns something check for a possible loop.
-            if (!empty($possible_loop_starts)) {
-              $result = tripal_update_cvtermpath_loop_checker_traverse($origin, $child_id, $cv_id, $type_id, $depth, $increment_of_depth, $possible_start_of_loop, $array_of_possible_loop, array(), 0);
-              watchdog('debug', '<pre>tripal_update_cvtermpath_loop_checker  $result: '. print_r($result, TRUE) .'</pre>');
-              if(!empty($result)){
-                return $result;
-              }
-            }
+  // Find the child terms of the current term via the relationship taboe.
+  chado_set_active('chado');
+  $query = db_select('cvterm_relationship', 'cvtr')
+    ->fields('cvtr')
+    ->condition('cvtr.object_id', $child_id, '=')
+    ->execute();
+  $cterm_relationships = $query->fetchAll();
+
+  // Iterate through the child terms via the relationships.
+  foreach ($cterm_relationships as $item){
+    // Search the $tree_path for the new $child_id in the build_id column.
+    foreach ($array_of_possible_loop as $parent) {
+      if ($parent['build_id'] === $possible_start_of_loop['build_id']) {
+        // If the search returns something check for a possible loop.
+        if (!empty($parent)) {
+          $result = tripal_update_cvtermpath_loop_checker_traverse($origin, $child_id,
+              $cv_id, $type_id, $depth, $increment_of_depth, $possible_start_of_loop,
+              $array_of_possible_loop, array(), 0);
+          if(!empty($result)){
+            break 2;
           }
         }
       }
-      elseif($loop_found !== TRUE){}
-      $increment_of_depth++;
-      $distance_between_parent_child++;
-      $children_id = $origin .'|' .$item->subject_id .'|' .$cv_id.'|' .$item->type_id;
-      $array_of_possible_loop[$distance_between_parent_child] = array('build_id' => $children_id);
-      $result = tripal_update_cvtermpath_loop_checker($origin, $item->subject_id, $cv_id, $item->type_id, $depth + 1, $increment_of_depth, $distance_between_parent_child, $possible_start_of_loop, $array_of_possible_loop, $depth_at_start_of_loop);
-      if($result !== FALSE){
-        return $result;
-      }
     }
-  return FALSE;
-}
 
-function tripal_update_cvtermpath_loop_checker_traverse($origin, $child_id, $cv_id, $type_id, $depth, $increment_of_depth, $possible_start_of_loop, $array_of_possible_loop, $traverse_of_loop, $increment){
-    if($increment > 10){
-      die();
+    $increment_of_depth++;
+    $distance_between_parent_child++;
+    $child_id = $origin . '|' . $item->subject_id . '|' . $cv_id . '|' . $item->type_id;
+    $array_of_possible_loop[$distance_between_parent_child] = ['build_id' => $child_id];
+    $result = tripal_update_cvtermpath_loop_checker($origin, $item->subject_id, $cv_id, $item->type_id, $depth + 1, $increment_of_depth, $distance_between_parent_child, $possible_start_of_loop, $array_of_possible_loop, $depth_at_start_of_loop);
+    if($result !== FALSE){
+      return $result;
     }
-    chado_set_active('chado');
-    $query = db_select('cvterm_relationship', 'cvtr')
-      ->fields('cvtr')
-      ->condition('cvtr.object_id', $child_id, '=')
-      ->execute();
-    $cterm = $query->fetchAll();
 
-    foreach ($cterm as $item){
-      if($array_of_possible_loop === $traverse_of_loop){
-        watchdog('debug', '<pre>$array_of_possible_loop: '. print_r($array_of_possible_loop, TRUE) .'</pre>');
-        watchdog('debug', '<pre>$traverse_of_loop: '. print_r($traverse_of_loop, TRUE) .'</pre>');
-        watchdog('debug', 'LOOP');
-        //Report the loop.
-        return $item;
-      }
-      elseif($array_of_possible_loop != $traverse_of_loop) {
-        $increment_of_depth++;
-        $increment++;
-        $children_id = $origin . '|' . $item->subject_id . '|' . $cv_id . '|' . $item->type_id;
-        $traverse_of_loop[$increment] = ['build_id' => $children_id];
-        $result = tripal_update_cvtermpath_loop_checker_traverse($origin, $item->subject_id, $cv_id, $item->type_id, $depth + 1, $increment_of_depth, $possible_start_of_loop, $array_of_possible_loop, $traverse_of_loop, $increment);
-        if($result !== FALSE){
-          return $result;
-        }
+  }
+  if (!empty($result)) {
+    return $result;
+  }
+  else {
+    return FALSE;
+  }
+}
+
+function tripal_update_cvtermpath_loop_checker_traverse($origin, $child_id, $cv_id,
+    $type_id, $depth, $increment_of_depth, $possible_start_of_loop, $array_of_possible_loop,
+    $traverse_of_loop, $increment) {
+
+  //watchdog('debug', '<pre>$increment: '. print_r($increment, TRUE) .'</pre>');
+  /*if ($increment > 10) {
+    die();
+  }*/
+  chado_set_active('chado');
+  $query = db_select('cvterm_relationship', 'cvtr')
+    ->fields('cvtr')
+    ->condition('cvtr.object_id', $child_id, '=')
+    ->execute();
+  $cterm = $query->fetchAll();
+
+  foreach ($cterm as $item) {
+    if ($array_of_possible_loop === $traverse_of_loop) {
+      watchdog('debug', 'LOOP');
+      //Report the loop.
+      $loop_found = end($array_of_possible_loop);
+      break;
+    }
+    elseif ($array_of_possible_loop != $traverse_of_loop) {
+      $increment_of_depth++;
+      $increment++;
+      $child_id = $origin . '|' . $item->subject_id . '|' . $cv_id . '|' . $item->type_id;
+      $traverse_of_loop[$increment] = ['build_id' => $child_id];
+      $result = tripal_update_cvtermpath_loop_checker_traverse($origin,
+          $item->subject_id, $cv_id, $item->type_id, $depth + 1,
+          $increment_of_depth, $possible_start_of_loop, $array_of_possible_loop,
+          $traverse_of_loop, $increment);
+      if ($result !== FALSE) {
+        return $result;
       }
     }
+  }
+  if ($loop_found) {
+    return $loop_found;
+  }
+  else {
     return FALSE;
-}
 
+  }
+}
 /*
  *
  * @param $origin
  * @param $subject_id
- * @param $cv_id
+ * @param $cv_idxkcd
  * @param $type_id
  * @param $depth
  * @return multitype:
 
 function tripal_update_cvtermpath_loop($origin, $child_id, $cv_id, $type_id, $depth){
   // Variables and arrays needed for loop checking.
-  $array_of_children;
+  $tree_path;
   $array_of_possible_loop;
   $possible_start_of_loop;
   $distance_between_parent_child;

+ 3 - 0
tripal_chado/includes/TripalFields/schema__additional_type/schema__additional_type_widget.inc

@@ -40,6 +40,9 @@ class schema__additional_type_widget extends ChadoFieldWidget {
       '#value' => $value,
     );
 
+    If ($field_table == 'pub' && empty($vocabulary)){
+      $vocabulary = 'tripal_pub';
+    };
     // If a parent_term is provided then use that to get the options
     $options = array();
     $options[] = 'Select a type';

+ 10 - 8
tripal_ds/api/tripal_ds.pane.api.inc

@@ -27,13 +27,15 @@
  * Example usage:
  *
  * @code
- *
+ *  field_create_field($field);
+ *  field_create_instance($instance);
+ *  tripal_ds_field_create_field($field_label, $field, $bundle);
  */
 function tripal_ds_field_create_field($field_label, $field, $bundle_name) {
-//Build the rest of the passes parameters.
-$group_field_name = 'gp_'.$field['field_name'];
-//Create the field groups.
-_additional_fields_field_group_info($bundle_name, $field_label, $group_field_name, $field);
-//Place the field groups in the layout.
-tripal_ds_update_ds_layout($bundle_name, $field, $group_field_name);
-}
+  //Build the rest of the passes parameters.
+  $group_field_name = 'gp_'.$field['field_name'];
+  //Create the field groups.
+  _additional_fields_field_group_info($bundle_name, $field_label, $group_field_name, $field);
+  //Place the field groups in the layout.
+  tripal_ds_update_ds_layout($bundle_name, $field, $group_field_name);
+}

+ 101 - 38
tripal_ds/includes/tripal_ds.ds.inc

@@ -8,7 +8,7 @@
  *
  * @return \Closure
  */
-function sort_array($key) {
+function tripal_ds_sort_array($key) {
   return function ($a, $b) use ($key) {
     return strnatcmp($a[$key], $b[$key]);
   };
@@ -21,13 +21,20 @@ function sort_array($key) {
  *
  * @return \Closure
  */
-function sort_object($key) {
+function tripal_ds_sort_object($key) {
   return function ($a, $b) use ($key) {
     return strnatcmp($a->$key, $b->$key);
   };
 }
+
 /**
- * Implements hook_ds_layout_settings_info().
+ * Builds the tripal_ds layout for all content types other than Publications.
+ *
+ * @param $bundle_name
+ *  Machine name of bundle, example bio_data_1
+ * @param $instances
+ *
+ * @return bool
  */
 function _ds_layout_settings_info($bundle_name, $instances) {
   $region_right = array();
@@ -51,7 +58,7 @@ function _ds_layout_settings_info($bundle_name, $instances) {
       $all_fields[$i] = $instance;
       $i++;
     }
-    usort($all_fields, sort_array('label'));
+    usort($all_fields, tripal_ds_sort_array('label'));
 
     // Iterate through the fields of this bundle.
     foreach ($all_fields as $key => $instance){
@@ -142,37 +149,69 @@ function _ds_layout_settings_info($bundle_name, $instances) {
       foreach ($all_field_groups['default'] as $key => $field_name) {
         $right_fields[$key] = $field_name;
       }
-      usort($right_fields, sort_object('label'));
-      watchdog('debug', '<pre>$right_fields: '. print_r($right_fields, TRUE) .'</pre>');
+      usort($right_fields, tripal_ds_sort_object('label'));
+    }
+    elseif(empty($all_field_groups)) {
+      //Add the original instances that were passed and the field_groups that
+      //were created.
+      $field_group_fields = db_select('field_group', 'fg')
+        ->fields('fg', array('group_name', 'data'))
+        ->condition('bundle', $bundle_name, '=')
+        ->execute()
+        ->fetchAll();
+
+      $instance_names = array();
+      $field_group_names = array();
+      foreach ($all_fields as $key => $instance){
+        $instance_names[$key]['field_name'] = $instance['field_name'];
+        $instance_names[$key]['label'] = $instance['label'];
 
+      }
+      foreach ($field_group_fields as $key => $field_group_name){
+        $data = unserialize($field_group_name->data);
+        $field_group_names[$key]['field_name'] = $field_group_name->group_name;
+        $field_group_names[$key]['label'] = $data['format_settings']['label'];
+
+      }
+      $all_field_groups = array_merge($instance_names, $field_group_names);
+      usort($all_field_groups, tripal_ds_sort_array('label'));
     }
 
     // Now build the $region_right array and the fields array.
     $i = 0;
-    foreach ($right_fields as $index => $field) {
-      // Check if the child is already present which is a problem when groups
-      // are nested within groups.
-      if (in_array($field->group_name, $region_right)) {
-        // Still need to check for children and add them.
-        if (!empty($field->children)) {
-          foreach($field->children as $index => $child){
-            $region_right[$i] = $child;
-            $i++;
+    if(empty($right_fields)) {
+      foreach ($all_field_groups as $index => $field) {
+        $region_right[$i] = $field['field_name'];
+        $i++;
+        tripal_ds_field_group_update_weight($field['field_name'], $bundle_name, $i);
+      }
+    }
+    elseif (!empty($right_fields)) {
+      foreach ($right_fields as $index => $field) {
+        // Check if the child is already present which is a problem when groups
+        // are nested within groups.
+        if (in_array($field->group_name, $region_right)) {
+          // Still need to check for children and add them.
+          if (!empty($field->children)) {
+            foreach ($field->children as $index => $child) {
+              $region_right[$i] = $child;
+              $i++;
+            }
           }
         }
-      }
-      else {
-        $region_right[$i] = $field->group_name;
-        if (!empty($field->children)) {
-          foreach ($field->children as $index => $child) {
-            $i++;
-            $region_right[$i] = $child;
+        else {
+          $region_right[$i] = $field->group_name;
+          if (!empty($field->children)) {
+            foreach ($field->children as $index => $child) {
+              $i++;
+              $region_right[$i] = $child;
+            }
           }
+          $i++;
         }
-        $i++;
+        // Now update the weights of the field_groups.
+        tripal_ds_field_group_update_weight($field->group_name, $bundle_name, $i);
       }
-      // Now update the weights of the field_groups.
-      tripal_ds_field_group_update_weight($field->group_name, $bundle_name, $i);
     }
     foreach($region_right as $index => $field){
       $fields_with_regions[$field] = 'right';
@@ -181,8 +220,6 @@ function _ds_layout_settings_info($bundle_name, $instances) {
     _ds_fields_info_write($bundle_name);
     $region_left = [ 'toc' ];
     $fields_with_regions += [ 'toc' => 'left' ];
-    watchdog('debug', '<pre>$fields_with_regions: '. print_r($fields_with_regions, TRUE) .'</pre>');
-    watchdog('debug', '<pre>$region_right: '. print_r($region_right, TRUE) .'</pre>');
 
     // Build the ds layout.
     $record = new stdClass;
@@ -214,7 +251,7 @@ function _ds_layout_settings_info($bundle_name, $instances) {
     );
     $record->settings = $settings;
     drupal_write_record('ds_layout_settings', $record);
-    // Clear the Drpual chace
+    // Clear the Drupal cache.
     cache_clear_all();
   }
   catch (Exception $e) {
@@ -226,7 +263,13 @@ function _ds_layout_settings_info($bundle_name, $instances) {
 
 
 /**
- *  Implements hook_ds_layout_settings_info().
+ * Builds the tripal_ds layout for Publications.
+ *
+ * @param $bundle_name
+ *  Machine name of bundle, example bio_data_1
+ * @param $instances
+ *
+ * @return bool
  */
 function _ds_layout_pub_settings_info($bundle_name, $instances) {
   $region_right = array();
@@ -235,13 +278,13 @@ function _ds_layout_pub_settings_info($bundle_name, $instances) {
   $all_fields = array();
   $instances_for_field_groups = array();
   $disabled_instances = array();
-
+  watchdog('debug', '<pre>$instances: '. print_r($instances, TRUE) .'</pre>');
   try {
     // Add Abstract, Citation, DB Cross Reference, Properties.
     $all_fields['tpub__abstract']= 'right';
     $all_fields['tpub__citation']= 'right';
     $all_fields['sbo__database_cross_reference']= 'right';
-    $all_fields['tpub__publication_type']= 'right';
+    $all_fields['schema__additional_type']= 'right';
     $all_fields['tpub__doi']= 'right';
     $all_fields['tpub__publication_date']= 'right';
     $all_fields['sio__references']= 'right';
@@ -250,17 +293,19 @@ function _ds_layout_pub_settings_info($bundle_name, $instances) {
     foreach ($instances as $key => $instance) {
       $instance_name = $instance['field_name'];
 
-      if($instance_name == 'tpub__abstract' || $instance_name == 'tpub__citation' || $instance_name == 'sbo__database_cross_reference' || $instance_name == 'sio__references'){
+      if($instance_name == 'tpub__abstract' || $instance_name == 'tpub__citation'
+        || $instance_name == 'sbo__database_cross_reference'
+        || $instance_name == 'sio__references'){
         array_push($instances_for_field_groups, $instance);
         // Update the display settings so that the title is hidden.
         $instance['display']['default']['label'] = 'hidden';
         field_update_instance($instance);
       }
-      elseif($instance_name == 'tpub__publication_type' || $instance_name == 'tpub__doi' || $instance_name == 'tpub__publication_date') {
-        array_push($properties, $instance);
+      elseif($instance_name == 'schema__additional_type' || $instance_name == 'tpub__doi' || $instance_name == 'tpub__publication_date') {
+        array_push($properties, $instance_name);
       }
       else {
-        array_push($disabled_instances, $instance);
+        array_push($disabled_instances, $instance_name);
       }
 
     }
@@ -274,12 +319,12 @@ function _ds_layout_pub_settings_info($bundle_name, $instances) {
       // updating fields here to ensure name consistency.
       $group_field_name = substr($group_field_name, 0, 27);
 
-      // Add randomm numbers to ensure the field name is unique within the 32
+      // Add random numbers to ensure the field name is unique within the 32
       // character limit of the field.
       $group_field_name = $group_field_name.rand(0, 99999);
 
       // Build the field group.
-      _additional_fields_field_group_info($bundle_name, $other_field['label'], $other_field['field_name'], $other_field['field_name']);
+      _additional_fields_field_group_info($bundle_name, $other_field['label'], $group_field_name, $other_field['field_name']);
 
       // Update arrays.
       array_push($temporary_field, $group_field_name, $other_field['field_name']);
@@ -294,6 +339,11 @@ function _ds_layout_pub_settings_info($bundle_name, $instances) {
       $region_right = array_merge($region_right, $properties);
       $all_fields+= [ 'group_prop_tripalpane' => 'right', 'group_prop_table' => 'right' ];
     }
+    if(!empty($all_fields)){
+      foreach ($disabled_instances as $disabled_field) {
+        $all_fields += [$disabled_field => 'disabled'];
+      }
+    }
 
     // Add blocks to $region_left and build the toc field that is placed within.
     _ds_fields_info_write($bundle_name);
@@ -329,6 +379,9 @@ function _ds_layout_pub_settings_info($bundle_name, $instances) {
     );
     $record->settings = $settings;
     drupal_write_record('ds_layout_settings', $record);
+    // Clear the Drpual chace
+    cache_clear_all();
+    watchdog('debug', '<pre>$record: '. print_r($record, TRUE) .'</pre>');
   }
   catch (Exception $e) {
     watchdog_exception('tripal_ds', $e);
@@ -339,6 +392,9 @@ function _ds_layout_pub_settings_info($bundle_name, $instances) {
 
 /**
  * Implements hook_ds_fields_info().
+ * Creates the Table of Contents field.
+ *
+ * $param $entity_type
  */
 function tripal_ds_ds_fields_info($entity_type) {
   $fields = array();
@@ -352,9 +408,10 @@ function tripal_ds_ds_fields_info($entity_type) {
 }
 
 /**
+ * Adds the content the to Table of Contents block.
  *
  * @param $entity_type
- * @return
+ * @return Object
  */
 function tripal_ds_toc_block($entity_type) {
   $bundle_name = $entity_type['bundle'];
@@ -362,6 +419,12 @@ function tripal_ds_toc_block($entity_type) {
   return $toc;
 }
 
+/**
+ * Creates the field_group for the Table of Contents.
+ *
+ * @param $bundle_name
+ *  Machine name of bundle, example bio_data_1
+ */
 function _ds_fields_info_write($bundle_name) {
   $fields = new stdClass;
   $fields->id ='TripalEntity|' . $bundle_name . '|default';

+ 11 - 8
tripal_ds/includes/tripal_ds.field_formatter.inc

@@ -88,7 +88,9 @@ function tripal_ds_field_group_pre_render(&$element, $group, &$form) {
  * Updated the weight of field groups to reflect their order in the layout array.
  *
  * @param $field_name
+ *  Machine readable name of the field.
  * @param $bundle
+ *  Machine name of bundle, example bio_data_1
  * @param $weight
  */
 function tripal_ds_field_group_update_weight($field_name, $bundle, $weight) {
@@ -104,13 +106,14 @@ function tripal_ds_field_group_update_weight($field_name, $bundle, $weight) {
     $data = unserialize($result['data']);
     $data['weight'] = $weight;
     $data = serialize($data);
+
+    // Write the new weight to the field_group entry.
+    db_update('field_group')
+      ->fields(array(
+        'data' => $data
+      ))
+      ->condition('bundle', $bundle,'=')
+      ->condition('group_name', $field_name,'=')
+      ->execute();
   }
-  // Write the new weight to the field_group entry.
-  db_update('field_group')
-    ->fields(array(
-      'data' => $data
-    ))
-    ->condition('bundle', $bundle,'=')
-    ->condition('group_name', $field_name,'=')
-    ->execute();
 }

+ 32 - 4
tripal_ds/includes/tripal_ds.field_group.inc

@@ -1,7 +1,11 @@
 <?php
 /**
+ * Creates the Summary tripal pane and the table within that pane.
+ *
  * @param $bundle_name
+ *  Machine name of bundle, example bio_data_1
  * @param $fields
+ *  Array of the machine names of the children of the field group being created.
  */
 function _summary_field_group_info($bundle_name, $fields){
   //Tripal pane to nest the summary fieldset within.
@@ -69,8 +73,12 @@ function _summary_field_group_info($bundle_name, $fields){
 }
 
 /**
+ * Creates the Properties Table tripal pane and the table within that pane.
+ *
  * @param $bundle_name
+ *  Machine name of bundle, example bio_data_1
  * @param $fields
+ *  Array of the machine names of the children of the field group being created.
  */
 function _prop_field_group_info($bundle_name, $fields){
   //Tripal pane  to nest the fieldset within.
@@ -137,8 +145,12 @@ function _prop_field_group_info($bundle_name, $fields){
 }
 
 /**
+ * Creates the Data Sequence tripal pane and the table within that pane.
+ *
  * @param $bundle_name
+ *  Machine name of bundle, example bio_data_1
  * @param $fields
+ *  Array of the machine names of the children of the field group being created.
  */
 function _data_sequence_field_group_info($bundle_name, $fields){
   //Tripal pane  to nest the fieldset within.
@@ -204,9 +216,19 @@ function _data_sequence_field_group_info($bundle_name, $fields){
   drupal_write_record('field_group', $field_group);
 }
 
+
 /**
+ * Processes all fields other than those that belong in the summary table,
+ * property table, or data sequence table.
+ *
  * @param $bundle_name
- * @param $fields
+ *  Machine name of bundle, example bio_data_1
+ * @param $field_label
+ *  Human readable name of the field.
+ * @param $group_field_name
+ *  Machine name of the field.
+ * @param $field_name
+ *  Machine name of the child element.
  */
 function _additional_fields_field_group_info($bundle_name, $field_label, $group_field_name, $field_name){
   //Write to the tripal_ds table to record the new tripal pane.
@@ -239,11 +261,17 @@ function _additional_fields_field_group_info($bundle_name, $field_label, $group_
       ),
     ),
   );
+  watchdog('debug', '<pre>$field_group_fieldset: '. print_r($field_group_fieldset, TRUE) .'</pre>');
   drupal_write_record('field_group', $field_group_fieldset);
 }
 
 /**
- * Implements hook_field_group_info().
+ * Creates the tripal panes for Publications..
+ *
+ * @param $bundle_name
+ *  Machine name of bundle, example bio_data_1
+ * @param $fields
+ *  Array of the machine names of the children of the field group being created.
  */
 function _publication_prop_field_group_info($bundle_name, $fields){
   //Tripal pane  to nest the fieldset within.
@@ -260,7 +288,7 @@ function _publication_prop_field_group_info($bundle_name, $fields){
     'label' => 'Properties',
     'weight' => '1',
     'children' => array(
-      0 => 'group_prop',
+      0 => 'group_prop_table',
     ),
     'format_type' => 'tripalpane',
     'format_settings' => array(
@@ -293,7 +321,7 @@ function _publication_prop_field_group_info($bundle_name, $fields){
     'children' =>  array(
       0 => 'tpub__doi',
       1 => 'tpub__publication_date',
-      2 => 'tpub__publication_type',
+      2 => 'schema__additional_type',
     ),
     'format_type' => 'table',
     'format_settings' => array(

+ 46 - 4
tripal_ds/tripal_ds.module

@@ -5,6 +5,11 @@ require_once "includes/tripal_ds.ds.inc";
 require_once "includes/tripal_ds.field_group.inc";
 require_once "includes/tripal_ds.field_formatter.inc";
 
+/**
+ * Implements hook_init().
+ *
+ * Injects required javascript and css.
+ */
 function tripal_ds_init() {
   drupal_add_css(drupal_get_path('module', 'tripal_ds') . '/theme/css/tripal_ds.css');
   drupal_add_js(drupal_get_path('module', 'tripal_ds') . '/theme/js/tripal_ds.js');
@@ -53,11 +58,14 @@ function tripal_ds_menu() {
   );
   return $items;
 }
+
 /**
  * Implements hook_bundle_postcreate().
  *
  * This is a Triapl defined hook and is called in the TripalBundle::create()
  * function to allow modules to perform tasks when a bundle is created.
+ *
+ * @param $bundle
  */
 function tripal_ds_bundle_postcreate($bundle) {
   $bundle_name = $bundle->name;
@@ -73,7 +81,10 @@ function tripal_ds_bundle_postcreate($bundle) {
 }
 
 /**
- * Update the tripal_ds table when a tripal pane is deleted.
+ * Update the tripal_ds table when a tripal pane is deleted. This will remove
+ * the link from the table of contents block.
+ *
+ * @param $bundle
  */
 function tripal_ds_table_column_delete($bundle){
     $bundle_name = $bundle->name;
@@ -83,13 +94,23 @@ function tripal_ds_table_column_delete($bundle){
 }
 /**
  * Trigger the update to the tripal_ds table when a tripal pane is deleted.
+ *
+ * @param $bundle
  */
 function tripal_ds_bundle_delete($bundle){
   tripal_ds_table_column_delete($bundle);
 }
 
+
 /**
  * Implements hook_ds_field_settings_alter()
+ *
+ * Upon save field groups are reviewed so that the tripal_ds table is update and
+ * thus the table of contents block is be updated.
+ *
+ * @param $field_settings
+ * @param $form
+ * @param $form_state
  */
 function tripal_ds_ds_field_settings_alter(&$field_settings, $form, $form_state){
   // Get the form info from the bundle about to be saved.
@@ -169,7 +190,10 @@ function tripal_ds_bundle_menu_item($bundle_name, $field_label, $field_name, $en
 
 /**
  * Implements hook_ds_layout_info() to define layouts from code in a module for
- * display suite
+ * display suite.
+ *
+ * Defines the Tripal Feature Layout option.
+ *
  */
 function tripal_ds_ds_layout_info() {
   $path = drupal_get_path('module', 'tripal_ds');
@@ -193,7 +217,7 @@ function tripal_ds_ds_layout_info() {
  * Implements hook_form()
  *
  * Adds a confirmation message to applying default layout option in 'Manage
- * Display'
+ * Display'.
  *
  * @param $form
  * @param $form_state
@@ -223,6 +247,9 @@ function tripal_ds_update_layout_form($form, &$form_state, $bundle_name) {
 /**
  * Implements hook_form_submit()
  *
+ * Deletes all existing settings associated with a bundle's display settings
+ * so that the default layout is applied cleanly.
+ *
  * @param $form_state
  * @param $form
  */
@@ -358,8 +385,17 @@ function tripal_ds_pane_addition_button_form_submit($form, &$form_state) {
   drupal_goto("admin/structure/bio_data/manage/$bundle_name/display");
 }
 
+
 /**
+ * When called the function will add field_groups to the existing tripal_ds
+ * layout in the correct regions.
+ *
  * @param $bundle_name
+ *  The name of the bundle the pane is being added to.
+ * @param $field_name
+ *  The machine name for the field.
+ * @param $tripal_pane_name
+ *  The machine name for the tripal pane.
  */
 function tripal_ds_update_ds_layout($bundle_name, $field_name, $tripal_pane_name) {
   //Build the identifier to check against ds_layout_settings.
@@ -415,7 +451,13 @@ function tripal_ds_update_ds_layout($bundle_name, $field_name, $tripal_pane_name
 */
 
 /**
- *  Implements hook_field_display_alter().
+ * Implements hook_field_display_alter().
+ * Alters the display settings of a field before it gets displayed.
+ *
+ * Hides the empty tripal panes if the content type has been set to hide empty
+ * fields. This option is found in the edit tab of the tripal content type with
+ * a title 'Field Display'.
+ *
  * @param $display
  * @param $context
  */