Browse Source

Continued working on kvproperty style tables

Stephen Ficklin 9 years ago
parent
commit
6e8d267615

+ 16 - 1
tripal_entities/includes/tripal_entities.chado_entity.inc

@@ -23,7 +23,22 @@ function tripal_entities_entity_postsave($entity, $type) {
  * Implements hook_entity_load().
  */
 function tripal_entities_entity_load($entities, $type) {
-
+  foreach ($entities as $entity) {
+
+    // For Tripal created entities add in the chado_entity details.
+    $dbs = tripal_entities_get_db_names_for_published_vocabularies();
+    if (in_array($entity->type, $dbs)) {
+      $details = db_select('chado_entity', 'ce')
+        ->fields('ce')
+        ->condition('entity_id', $entity->id)
+        ->execute()
+        ->fetchObject();
+
+      // Add teh chado entity details to the entity in case it's needed
+      // downstream (e.g. in field widget construction).
+      $entity->chado_entity = $details;
+    }
+  }
 }
 
 /**

+ 0 - 2
tripal_entities/tripal_entities.info

@@ -6,8 +6,6 @@ package = Tripal
 version = 7.x-2.0
 configure = admin/tripal/chado/tripal_entities
 
-stylesheets[all][] = theme/css/tripal_entities.css
-
 dependencies[] = tripal_core
 dependencies[] = tripal_views
 dependencies[] = tripal_db

+ 1 - 1
tripal_entities/tripal_entities.module

@@ -190,7 +190,7 @@ function tripal_entities_entity_info() {
       'access callback' => 'tripal_entity_access',
 
       // FALSE disables caching. Caching functionality is handled by Drupal core.
-      //'static cache' => FALSE,
+      'static cache' => FALSE,
 
       // Bundles are added in the hook_entities_info_alter() function.
       'bundles' => array (),

+ 47 - 24
tripal_fields/includes/fields/kvproperty.inc

@@ -37,33 +37,30 @@ function tripal_fields_kvproperty_formatter(&$element, $entity_type, $entity, $f
  */
 function tripal_fields_kvproperty_widget($form, $form_state, $field, $instance, $langcode, $items, $delta, $element) {
 
+  $chado_entity = $form['#entity']->chado_entity;
   $field_name = $field['field_name'];
-  $widget = array();
-  $element += array(
-    '#element_validate' => array('tripal_fields_kvproperty_widget_validate'),
-    '#type' => 'textfield',
-    '#delta' => $delta,
-  );
+  $widget = $element;
 
-  if ($field['cardinality'] == 1) {
-    $element['#default_value'] = !empty($items) ? $items[0] : '';
-    $widget = array($element);
-  }
-  else {
-    foreach ($items as $item) {
-      $widget[$delta] = $element;
-      $widget[$delta]['#default_value'] = $item;
-      $widget[$delta]['#weight'] = $delta;
-      $delta++;
-    }
-  }
-  // Add one more row if delta is less than the cardinality.
-  if ($field['cardinality'] == FIELD_CARDINALITY_UNLIMITED || $delta < $field['cardinality']){
-    $widget[$delta] = $element;
-    $widget[$delta]['#default_value'] = '';
-    $widget[$delta]['#weight'] = $delta;
-    $widget[$delta]['#required'] = ($element['#required'] && $delta == 0);
+  $matches = array();
+  preg_match('/(.*?)__(\d+)/', $field_name, $matches);
+  // If the field name is not properly formatted then we can't tell what
+  // table and type this is.  So just return.
+  if (count($matches) != 3) {
+    return $widget;
   }
+  $table_name = $matches[1];
+  $cvterm_id = $matches[2];
+
+  // Get the name of the pkey field for this property table.
+  $schema = chado_get_schema($table_name);
+  $pkey = $schema['primary key'][0];
+
+  // Get the name of the FK field that links to the base data table.
+  $schema = chado_get_schema($chado_entity->data_table);
+  $fk = $schema['primary key'][0];
+
+  $pkey_value = '';
+  $fk_value = $chado_entity->record_id;
 
   // The group of elements all-together need some extra functionality
   // after building up the full list (like draggable table rows).
@@ -73,7 +70,33 @@ function tripal_fields_kvproperty_widget($form, $form_state, $field, $instance,
   $widget['#field_name'] = $element['#field_name'];
   $widget['#language'] = $element['#language'];
   $widget['#weight'] = isset($element['#weight']) ? $element['#weight'] : 0;
+  $widget['#element_validate'] = array('tripal_fields_kvproperty_widget_validate');
   $widget['#cardinality'] = 1;
+
+  $widget[$delta] = $element;
+  $widget[$delta] += array(
+    $table_name . '__' . $pkey => array(
+      '#type' => 'hidden',
+      '#value' => $pkey_value,
+    ),
+    $table_name . '__' . $fk => array(
+      '#type' => 'hidden',
+      '#value' => $fk_value,
+    ),
+    $table_name . '__value' => array(
+      '#type' => 'textfield',
+      '#default_value' => !empty($items) ? $items[0] : '',
+    ),
+    $table_name . '__type_id' => array(
+      '#type' => 'hidden',
+      '#value' => $cvterm_id,
+    ),
+    $table_name . '__rank' => array(
+      '#type' => 'hidden',
+      '#value' => $delta,
+    ),
+  );
+
   return $widget;
 }
 

+ 2 - 2
tripal_fields/includes/fields/kvproperty_adder.inc

@@ -96,13 +96,13 @@ function tripal_fields_kvproperty_adder_widget_validate($element, &$form_state)
      $kvproperty = tripal_fields_get_field_form_values($field_name, $form_state, 'kvproperty_adder');
      $term = chado_generate_var('cvterm', array('name' => $kvproperty), $options = array('return_array' => TRUE));
      if (count($term) == 1) {
-       $prop_field_name = $field_name . '__' . strtolower($term[0]->dbxref_id->db_id->name) . '_' . $term[0]->dbxref_id->accession;
+       $prop_field_name = $field_name . '__' . $term[0]->cvterm_id;
        $field_info = array(
          'field_type' => 'kvproperty',
          'widget_type' => 'tripal_fields_kvproperty_widget',
          'field_settings' => array(),
          'widget_settings' => array(),
-         'description' => '',
+         'description' => $term[0]->definition ? $term[0]->definition : '',
          'label' => ucfirst(preg_replace('/_/', ' ', $term[0]->name)),
          'is_required' => FALSE,
          // All properties are unlimited.

+ 17 - 18
tripal_fields/includes/fields/organism_id.inc

@@ -2,13 +2,13 @@
 
 /**
  *
- * @param unknown $entity_type
- * @param unknown $entity
- * @param unknown $field
- * @param unknown $instance
- * @param unknown $langcode
- * @param unknown $items
- * @param unknown $display
+ * @param $entity_type
+ * @param $entity
+ * @param $field
+ * @param $instance
+ * @param $langcode
+ * @param $items
+ * @param $display
  * @return string
  */
 function tripal_fields_organism_select_formatter(&$element, $entity_type, $entity, $field,
@@ -24,16 +24,16 @@ function tripal_fields_organism_select_formatter(&$element, $entity_type, $entit
 }
 /**
  *
- * @param unknown $field_name
- * @param unknown $widget
- * @param unknown $form
- * @param unknown $form_state
- * @param unknown $field
- * @param unknown $instance
- * @param unknown $langcode
- * @param unknown $items
- * @param unknown $delta
- * @param unknown $element
+ * @param $field_name
+ * @param $widget
+ * @param $form
+ * @param $form_state
+ * @param $field
+ * @param $instance
+ * @param $langcode
+ * @param $items
+ * @param $delta
+ * @param $element
  */
 function tripal_fields_organism_select_widget($form, $form_state, $field, $instance, $langcode, $items, $delta, $element) {
   $field_name = $field['field_name'];
@@ -57,7 +57,6 @@ function tripal_fields_organism_select_widget($form, $form_state, $field, $insta
  * Callback function for validating the tripal_fields_organism_select_widget.
  */
 function tripal_fields_organism_select_widget_validate($element, &$form_state) {
-  //dpm($element);
   $field_name = $element['#field_name'];
 
   // If the form ID is field_ui_field_edit_form, then the user is editing the

+ 13 - 0
tripal_fields/includes/fields/primary_dbxref.inc

@@ -72,6 +72,9 @@ function tripal_fields_primary_dbxref_widget($form, $form_state, $field, $instan
       $form_state['triggering_element']['#parents'][0] == $field_name) {
     $collapsed = FALSE;
   }
+  if ($dbxref_id) {
+    $collapsed = FALSE;
+  }
 
   $schema = chado_get_schema('dbxref');
   $options = tripal_get_db_select_options();
@@ -178,6 +181,7 @@ function tripal_fields_primary_dbxref_widget_validate($element, &$form_state) {
   }
 
   // Get the field values.
+  $dbxref_id = tripal_fields_get_field_form_values($field_name, $form_state, $field_name);
   $db_id = tripal_fields_get_field_form_values($field_name, $form_state, "dbxref__db_id");
   $accession = tripal_fields_get_field_form_values($field_name, $form_state, "dbxref__accession");
   $version = tripal_fields_get_field_form_values($field_name, $form_state, "dbxref__version");
@@ -202,6 +206,15 @@ function tripal_fields_primary_dbxref_widget_validate($element, &$form_state) {
   if (count($db_id) == 0) {
     tripal_fields_set_field_form_values($field_name, $form_state, '__NULL__', $field_name);
   }
+  // If the dbxref_id does not match the db_id + accession then the user
+  // has selected a new dbxref record and we need to update the hidden
+  // value accordingly.
+  if (count($db_id) == 1 and count($accession) == 1) {
+    $dbxref = chado_generate_var('dbxref', array('db_id' => $db_id[0], 'accession' => $accession[0]));
+    if ($dbxref->dbxref_id != $dbxref_id[0]) {
+      tripal_fields_set_field_form_values($field_name, $form_state, $dbxref->dbxref_id, $field_name);
+    }
+  }
 }
 /**
  * Theme function for the primary_dbxref_widget.

+ 88 - 19
tripal_fields/includes/tripal_fields.field_storage.inc

@@ -27,7 +27,9 @@ function tripal_fields_field_storage_write($entity_type, $entity, $op, $fields)
 
   // Convert the fields into a key/value list of fields and their values.
   $field_vals = tripal_fields_field_storage_unnest_fields($fields, $entity_type, $entity);
-
+  $data_table = NULL;
+  $type_field = NULL;
+  $record_id = NULL;
   switch ($op) {
     case FIELD_STORAGE_INSERT:
       // Use the cvterm_id to look up tables where this term is used
@@ -43,8 +45,21 @@ function tripal_fields_field_storage_write($entity_type, $entity, $op, $fields)
         $data_table = $usage->data_table;
         //$type_table = $usage->type_table;
         $type_field = $usage->field;
+
+        // Recursively write fields for the base table.
         tripal_fields_field_storage_write_recursive($entity_type, $entity,
           $op, $field_vals, $data_table, $type_field);
+
+        // Now get the new chado_entity that was just added.
+        $details = db_select('chado_entity', 'ce')
+          ->fields('ce')
+          ->condition('entity_id', $entity->id)
+          ->execute()
+          ->fetchObject();
+        $data_table = $details->data_table;
+        $type_field = $details->field;
+        $record_id = $details->record_id;
+
       }
       break;
 
@@ -56,17 +71,31 @@ function tripal_fields_field_storage_write($entity_type, $entity, $op, $fields)
         ->condition('entity_id', $entity->id)
         ->execute()
         ->fetchObject();
-      $tablename = $details->data_table;
+      $data_table = $details->data_table;
       $type_field = $details->field;
       $record_id = $details->record_id;
 
       tripal_fields_field_storage_write_recursive($entity_type, $entity,
-        $op, $field_vals, $tablename, $type_field, $record_id);
+        $op, $field_vals, $data_table, $type_field, $record_id);
       if (!$details) {
         // TODO: what to do if record is missing!
       }
       break;
   }
+
+  // Recursively write fields for any referring tables that have
+  // values in the $field_vals array.  There should be a key for each
+  // FK table in the $field_vals array.
+  $schema = chado_get_schema($data_table);
+  $rtables = $schema['referring_tables'];
+  dpm($schema);
+  foreach ($rtables as $rtable) {
+    dpm($rtable);
+    if (array_key_exists($rtable, $field_vals)) {
+      tripal_fields_field_storage_write_recursive($entity_type, $entity,
+          $op, $field_vals, $rtable, $type_field, $record_id, 1);
+    }
+  }
 }
 
 /**
@@ -86,7 +115,7 @@ function tripal_fields_field_storage_write_recursive($entity_type, $entity,
   $fkey_fields_list = array();
 
   // STEP 1: Recurse on the FK fields.
-  // Loop through the foreign keys os that we can recurse on those first.
+  // Loop through the foreign keys so that we can recurse on those first.
   foreach ($fkey_fields as $fk_table => $details) {
     foreach ($details['columns'] as $local_id => $remote_id) {
       // If this is the base table then do not recurse on the type_id.  The
@@ -96,6 +125,7 @@ function tripal_fields_field_storage_write_recursive($entity_type, $entity,
         $values[$local_id] = $entity->cvterm_id;
         continue;
       }
+
       // Keep track of the FK fields so that in STEP 2 we don't have to
       // loop through the $fk_fields again.
       $fkey_fields_list[] = $local_id;
@@ -103,7 +133,22 @@ function tripal_fields_field_storage_write_recursive($entity_type, $entity,
       // Get the value of the FK field as provided by the user.
       $fk_val = NULL;
       $fk_field_name = $tablename . '__' . $local_id;
-      $fk_val = array_key_exists($fk_field_name, $field_vals) ? $field_vals[$fk_field_name] : NULL;
+
+      // If this is the base table then we'll find any values for the FK
+      // fields as any other field.  IF we are not at the base table,
+      // then the FK values are in a sub element of the array where the
+      // key of the field is the table name. Because we are looping
+      // on FKs that are members of the current table we should always only
+      // have one value.
+      if ($depth == 0) {
+        $fk_val = array_key_exists($fk_field_name, $field_vals) ? $field_vals[$fk_field_name] : NULL;
+      }
+      else {
+        if (array_key_exists($fk_table, $field_vals) and
+            array_key_exists($fk_field_name, $field_vals[$fk_table])) {
+          $fk_val = $field_vals[$fk_table][$fk_field_name];
+        }
+      }
 
       // Don't recurse if the value of the FK field is set to NULL.  The
       // Tripal Chado API value for NULL is '__NULL__'.
@@ -214,12 +259,13 @@ function tripal_fields_field_storage_load($entity_type, $entities, $age, $fields
 
   foreach ($entities as $id => $entity) {
 
-   // Get the base table and record id for the fields of this entity.
-   $details = db_select('chado_entity', 'ce')
+    // Get the base table and record id for the fields of this entity.
+    $details = db_select('chado_entity', 'ce')
       ->fields('ce')
       ->condition('entity_id', $entity->id)
       ->execute()
       ->fetchObject();
+
     if (!$details) {
       // TODO: what to do if record is missing!
     }
@@ -275,32 +321,55 @@ function tripal_fields_field_storage_load($entity_type, $entities, $age, $fields
  */
 function tripal_fields_field_storage_unnest_fields($fields, $entity_type, $entity) {
   $new_fields = array();
+
   foreach ($fields as $field_id => $ids) {
     $field = field_info_field_by_id($field_id);
     $field_name = $field['field_name'];
+
     // Currently, we only support one language, but for for the sake of
     // thoroughness we'll iterate through all possible languages.
     $all_languages = field_available_languages($entity_type, $field);
     $field_languages = array_intersect($all_languages, array_keys((array) $entity->$field_name));
     foreach ($field_languages as $langcode) {
-      $items = (array) $entity->{$field_name}[$langcode];
+
       // The number of items is related to the cardinatily of the field.
-      // We should always only have one item because this is a field in a
-      // table. But we loop anyway.
+      $items = (array) $entity->{$field_name}[$langcode];
       foreach ($items as $delta => $item) {
-        // If the $value is an array then this field has nested fields. We
-        // want to add those to our $new_fields list.
-        if (is_array($item['value'])) {
-          foreach ($item['value'] as $children) {
-            foreach ($children as $child_field_name => $child_value) {
-              if (preg_match('/^.*?__.*?$/', $child_field_name)) {
+        // There must be a 'value' field.
+        if (!array_key_exists('value', $item)) {
+          continue;
+        }
+
+        // Case 1: base table fields.
+        // If the value is not an array then we can just use the value as is.
+        // This occurs for fields of the base table.
+        if (!is_array($item['value'])) {
+          $new_fields[$field_name] = $item['value'];
+          continue;
+        }
+
+        // Case 2: foreign key fields.
+        // If the value is an array then there are sub fields. This occurs
+        // for fields that represent FKs with the base table.
+        $i = 0;
+        foreach ($item['value'] as $children) {
+          foreach ($children as $child_field_name => $child_value) {
+            $matches = array();
+            if (preg_match('/^(.*?)__.*?$/', $child_field_name, $matches)) {
+              $table_name = $matches[1];
+              // Case 2a: the FK field is in the basee table.
+              if ($table_name == $entity->chado_entity->data_table) {
                 $new_fields[$child_field_name] = $child_value;
               }
+              // Case 2b: the fields of the FK relationship are in the non
+              // base table. We store these in an array with the key being
+              // the table name.
+              else {
+                $new_fields[$table_name][$i][$child_field_name] = $child_value;
+              }
             }
           }
-        }
-        else {
-          $new_fields[$field_name] = $item['value'];
+          $i++;
         }
       }
     }

+ 0 - 0
tripal_entities/theme/css/tripal_entities.css → tripal_fields/theme/css/tripal_fields.css


+ 2 - 0
tripal_fields/tripal_fields.info

@@ -5,5 +5,7 @@ project = tripal
 package = Tripal
 version = 7.x-2.0
 
+stylesheets[all][] = theme/css/tripal_fields.css
+
 dependencies[] = tripal_core
 dependencies[] = date