Browse Source

Working on fixing warning/error messages

Stephen Ficklin 8 years ago
parent
commit
29acc0a89d

+ 11 - 0
tripal/includes/TripalFields/TripalField.inc

@@ -324,4 +324,15 @@ class TripalField {
 
   }
 
+  /**
+   * Afte a field instance is created the following function is run.
+   *
+   * This function is equivalent to the hook_field_create_field() hook of
+   * the Drupal Field API. This function is invoked after a new field
+   * instance is created.
+   */
+  public function createInstance() {
+
+  }
+
 }

+ 22 - 8
tripal/includes/tripal.fields.inc

@@ -4,7 +4,12 @@
  * Implements hook_field_create_instance().
  */
 function tripal_field_create_instance($instance) {
-  // When a field is added to an entity and instance are created on
+  $field = field_info_field($instance['field_name']);
+  $field_class = $field['type'];
+  if (tripal_load_include_field_class($field_class)) {
+    $field = new $field_class($field, $instance);
+    return $field->createInstance();
+  }
 }
 /**
  * Implements hook_field_info().
@@ -254,13 +259,16 @@ function tripal_form_field_ui_field_overview_form_alter(&$form, &$form_state, $f
 
 /**
  * A submit function for the field_ui_field_overview_form.
+ *
  */
 function tripal_form_field_ui_field_overview_form_submit($form, &$form_state) {
   $form_values = $form_state['values']['fields'];
   $admin_path = _field_ui_bundle_admin_path('TripalEntity', $form['#bundle']);
-
   $destinations = array();
 
+  // If the form Field UI form is adding a new field to the bundle we want
+  // to preempt Drupal from creating the field in it's field_sql_storage
+  // backend. We want to create it.
   if (!empty($form_values['_add_new_field']['field_name'])) {
     try {
       // Is the field type a TripalField? If so then we want
@@ -268,9 +276,12 @@ function tripal_form_field_ui_field_overview_form_submit($form, &$form_state) {
       $type = $form_values['_add_new_field']['type'];
       if (tripal_load_include_field_class($type)) {
         $module = $type::$module;
-        $function = $module . '_form_field_ui_field_overview_add_new';
+        $function = $module . '_bundle_create_user_field';
         $bundle = tripal_load_bundle_entity(array('name' => $form['#bundle']));
         $field_name = $form_values['_add_new_field']['field_name'];
+
+        // If the module implements the hook then we'll have it create the
+        // field and instance.
         if (function_exists($function)) {
           $function($form_values['_add_new_field'], $bundle);
         }
@@ -278,7 +289,10 @@ function tripal_form_field_ui_field_overview_form_submit($form, &$form_state) {
         $destinations[] = $admin_path . '/fields/' . $field_name;
 
         // Store new field information for any additional submit handlers.
-        $form_state['fields_added']['_add_new_field'] = $field['field_name'];
+        $form_state['fields_added']['_add_new_field'] = $field_name;
+
+        // Unset the the _add_new_field entry so Drupal doesn't try to
+        // Create the field.
         unset($form_state['values']['fields']['_add_new_field']);
         drupal_set_message('Please set the controlled vocabulary that best describes the data of this field. See the "Controlled Vocabulary Term" section below.');
       }
@@ -319,7 +333,7 @@ function tripal_module_implements_alter(&$implementations, $hook) {
  */
 function tripal_field_settings_form($field, $instance, $has_data) {
   $field_class = $field['type'];
-  if (tripal_load_include_field_class($field_type)) {
+  if (tripal_load_include_field_class($field_class)) {
     $field = new $field_class($field, $instance);
     return $field->settingsForm($has_data);
   }
@@ -330,7 +344,7 @@ function tripal_field_settings_form($field, $instance, $has_data) {
  */
 function tripal_field_instance_settings_form($field, $instance) {
   $field_class = $field['type'];
-  if (tripal_load_include_field_class($field_type)) {
+  if (tripal_load_include_field_class($field_class)) {
     $field = new $field_class($field, $instance);
     return $field->instanceSettingsForm();
   }
@@ -347,7 +361,7 @@ function tripal_field_instance_settings_form_validate($element, &$form_state, $f
   $instance = $element['#instance'];
 
   $field_class = $field['type'];
-  if (tripal_load_include_field_class($field_type)) {
+  if (tripal_load_include_field_class($field_class)) {
     $field = new $field_class($field, $instance);
     return $field->instanceSettingsForm();
   }
@@ -652,7 +666,7 @@ function tripal_field_settings_form_validate($element, &$form_state, $form) {
   $instance = $element['#instance'];
 
   $field_class = $field['type'];
-  if (tripal_load_include_field_class($field_type)) {
+  if (tripal_load_include_field_class($field_class)) {
     $field = new $field_class($field, $instance);
     $field->settingsFormValidate($form, $form_state);
   }

+ 22 - 0
tripal_chado/includes/TripalFields/ChadoField.inc

@@ -86,4 +86,26 @@ class ChadoField extends TripalField {
   public function queryOrder($query, $order) {
 
   }
+
+  /**
+   * @see TripalField::instanceSettingsForm()
+   */
+  public function instanceSettingsForm() {
+    // Make sure we don't lose our Chado table mappings when the settings
+    // are updated.  Setting them as values in the form ensures they don't
+    // get accidentally overwritten.
+    $element['base_table'] = array(
+      '#type' => 'value',
+      '#value' => $this->instance['settings']['base_table'],
+    );
+    $element['chado_table'] = array(
+      '#type' => 'value',
+      '#value' => $this->instance['settings']['chado_table'],
+    );
+    $element['chado_column'] = array(
+      '#type' => 'value',
+      '#value' => $this->instance['settings']['chado_column'],
+    );
+    return $element;
+  }
 }

+ 6 - 0
tripal_chado/includes/TripalFields/chado_linker__prop/chado_linker__prop.inc

@@ -35,6 +35,12 @@ class chado_linker__prop extends ChadoField {
     // type. This will create form elements when editing the field instance
     // to allow the site admin to change the term settings above.
     'term_fixed' => FALSE,
+    // The table in Chado that the instance maps to.
+    'chado_table' => '',
+    // The primary key column of hte table in Dhado.
+    'chado_column' => '',
+    // The base table.
+    'base_table' => '',
   );
 
   // The default widget for this field.

+ 1 - 0
tripal_chado/includes/TripalFields/chado_linker__prop/chado_linker__prop_formatter.inc

@@ -22,6 +22,7 @@ class chado_linker__prop_formatter extends ChadoFieldFormatter {
    */
   public function view(&$element, $entity_type, $entity, $langcode, $items, $display) {
     $field_name = $this->field['field_name'];
+    dpm($this->instance);
     $chado_table = $this->instance['settings']['chado_table'];
 
     foreach ($items as $delta => $item) {

+ 27 - 27
tripal_chado/includes/TripalFields/chado_linker__prop/chado_linker__prop_widget.inc

@@ -16,15 +16,15 @@ class chado_linker__prop_widget extends ChadoFieldWidget {
 
     $field_name = $this->field['field_name'];
     $field_type = $this->field['type'];
-    $field_table = $this->instance['settings']['chado_table'];
-    $field_column = $this->instance['settings']['chado_column'];
+    $base_table = $this->instance['settings']['base_table'];
+    $chado_table = $this->instance['settings']['chado_table'];
+    $chado_column = $this->instance['settings']['chado_column'];
     $instance = $this->instance;
 
     // Get the name of the pkey field for this property table and the name
     // of the FK field that links to the base table.
-    $schema = chado_get_schema($field_table);
+    $schema = chado_get_schema($chado_table);
     $pkey = $schema['primary key'][0];
-    $base_table = $this->instance['settings']['base_table'];
     $lfkey_field = key($schema['foreign keys'][$base_table]['columns']);
     $rfkey_field = $schema['foreign keys'][$base_table]['columns'][$lfkey_field];
 
@@ -39,20 +39,20 @@ class chado_linker__prop_widget extends ChadoFieldWidget {
     // array.  This happens when editing an existing record.
     if (count($items) > 0 and array_key_exists($delta, $items)) {
       // Check for element values that correspond to fields in the Chado table.
-      $record_id = tripal_get_field_item_keyval($items, $delta, 'chado-' . $field_table . '__' . $pkey, $record_id);
-      $fk_value = tripal_get_field_item_keyval($items, $delta, 'chado-' . $field_table . '__' . $lfkey_field, $fk_value);
-      $type_id = tripal_get_field_item_keyval($items, $delta, 'chado-' . $field_table . '__type_id', $type_id);
-      $value = tripal_get_field_item_keyval($items, $delta, 'chado-' . $field_table . '__value', $value);
-      $rank = tripal_get_field_item_keyval($items, $delta, 'chado-' . $field_table . '__rank', $rank);
+      $record_id = tripal_get_field_item_keyval($items, $delta, 'chado-' . $chado_table . '__' . $pkey, $record_id);
+      $fk_value = tripal_get_field_item_keyval($items, $delta, 'chado-' . $chado_table . '__' . $lfkey_field, $fk_value);
+      $type_id = tripal_get_field_item_keyval($items, $delta, 'chado-' . $chado_table . '__type_id', $type_id);
+      $value = tripal_get_field_item_keyval($items, $delta, 'chado-' . $chado_table . '__value', $value);
+      $rank = tripal_get_field_item_keyval($items, $delta, 'chado-' . $chado_table . '__rank', $rank);
     }
 
     // Check $form_state['values'] to see if an AJAX call set the values.
     if (array_key_exists('values', $form_state) and array_key_exists($delta, $form_state['values'])) {
-      $record_id = $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__' . $pkey];
-      $fk_value = $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__' . $lfkey_field];
-      $type_id = $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__type_id'];
-      $value = $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__value'];
-      $rank = $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__rank'];
+      $record_id = $form_state['values'][$field_name]['und'][$delta]['chado-' . $chado_table . '__' . $pkey];
+      $fk_value = $form_state['values'][$field_name]['und'][$delta]['chado-' . $chado_table . '__' . $lfkey_field];
+      $type_id = $form_state['values'][$field_name]['und'][$delta]['chado-' . $chado_table . '__type_id'];
+      $value = $form_state['values'][$field_name]['und'][$delta]['chado-' . $chado_table . '__value'];
+      $rank = $form_state['values'][$field_name]['und'][$delta]['chado-' . $chado_table . '__rank'];
     }
 
     $widget['value'] = array(
@@ -60,25 +60,25 @@ class chado_linker__prop_widget extends ChadoFieldWidget {
       '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
     );
 
-    $widget['chado-' . $field_table . '__' . $pkey] = array(
+    $widget['chado-' . $chado_table . '__' . $pkey] = array(
       '#type' => 'hidden',
       '#default_value' => $record_id,
     );
-    $widget['chado-' . $field_table . '__' . $lfkey_field] = array(
+    $widget['chado-' . $chado_table . '__' . $lfkey_field] = array(
       '#type' => 'hidden',
       '#value' => $fk_value,
     );
-    $widget['chado-' . $field_table . '__value'] = array(
+    $widget['chado-' . $chado_table . '__value'] = array(
       '#type' => 'textarea',
       '#default_value' => $value,
       '#title' => $instance['label'] . ' value',
       '#description' => $instance['description'],
     );
-    $widget['chado-' . $field_table . '__type_id'] = array(
+    $widget['chado-' . $chado_table . '__type_id'] = array(
       '#type' => 'hidden',
       '#value' => $type_id,
     );
-    $widget['chado-' . $field_table . '__rank'] = array(
+    $widget['chado-' . $chado_table . '__rank'] = array(
       '#type' => 'hidden',
       '#value' => $rank,
     );
@@ -90,24 +90,24 @@ class chado_linker__prop_widget extends ChadoFieldWidget {
    */
   public function submit($form, &$form_state, $entity_type, $entity, $langcode, $delta) {
     $field_name = $this->field['field_name'];
-    $field_table = $this->instance['settings']['chado_table'];
-    $schema = chado_get_schema($field_table);
+    $chado_table = $this->instance['settings']['chado_table'];
+    $schema = chado_get_schema($chado_table);
     $pkey = $schema['primary key'][0];
     $base_table = $this->instance['settings']['base_table'];
     $lfkey_field = key($schema['foreign keys'][$base_table]['columns']);
     $rfkey_field = $schema['foreign keys'][$base_table]['columns'][$lfkey_field];
 
-    $value = $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__value'];
+    $value = $form_state['values'][$field_name]['und'][$delta]['chado-' . $chado_table . '__value'];
     $form_state['values'][$field_name]['und'][$delta]['value'] = $value;
 
     // If the user removed the property then we want to clear out the other
     // fields so there is no insert.
     if (!$value) {
-      $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__' . $pkey] = '';
-      $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__' . $lfkey_field] = '';
-      $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__type_id'] = '';
-      $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__value'] = '';
-      $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__rank'] = '';
+      $form_state['values'][$field_name]['und'][$delta]['chado-' . $chado_table . '__' . $pkey] = '';
+      $form_state['values'][$field_name]['und'][$delta]['chado-' . $chado_table . '__' . $lfkey_field] = '';
+      $form_state['values'][$field_name]['und'][$delta]['chado-' . $chado_table . '__type_id'] = '';
+      $form_state['values'][$field_name]['und'][$delta]['chado-' . $chado_table . '__value'] = '';
+      $form_state['values'][$field_name]['und'][$delta]['chado-' . $chado_table . '__rank'] = '';
     }
   }
 }

+ 53 - 27
tripal_chado/includes/tripal_chado.field_storage.inc

@@ -227,6 +227,7 @@ function tripal_chado_field_storage_load($entity_type, $entities, $age,
     // that need to be selected from each of the tables represented.
     $tables = array();
     foreach ($fields as $field_id => $ids) {
+
       // By the time this hook runs, the relevant field definitions have been
       // populated and cached in FieldInfo, so calling field_info_field_by_id()
       // on each field individually is more efficient than loading all fields in
@@ -236,11 +237,18 @@ function tripal_chado_field_storage_load($entity_type, $entities, $age,
       $field_type = $field['type'];
       $field_module = $field['module'];
 
-      // Get the instnace for this field
+      // Get the instance for this field.  If no instance exists then skip
+      // loading of this field. This can happen when a field is deleted from
+      // a bundle using the user UI form.
+      // TODO: how to deal with deleted fields?
       $instance = field_info_instance($entity_type, $field_name, $entity->bundle);
+      if (!$instance) {
+        continue;
+      }
 
-      // Skip fields that don't map to a Chado table (e.g. kvproperty_adder).
-      if (!array_key_exists('settings', $instance) or !array_key_exists('chado_table', $instance['settings'])) {
+      // Skip fields that don't map to a Chado table.
+      if (!array_key_exists('settings', $instance) or
+          !array_key_exists('chado_table', $instance['settings'])) {
         continue;
       }
 
@@ -487,39 +495,57 @@ function tripal_chado_field_storage_query($query) {
     $column = $sort['specifier']['column'];
     $direction = $sort['direction'];
 
-    // See if there is a ChadoField class for this instance. If not then do
-    // our best to order the field.
-    $instance = field_info_instance('TripalEntity', $field_name, $bundle_name);
-    if (tripal_load_include_field_class($field_type)) {
-      $field_obj = new $field_type($field, $instance);
-      $field_obj->queryOrder($cquery, array('column' => $column, 'direction' => $direction));
-    }
-    // There is no class so do our best to order the data by this field
-    else {
-      $base_table = $instance['settings']['base_table'];
-      $chado_table = $instance['settings']['chado_table'];
-      $table_column = tripal_get_chado_semweb_column($chado_table, $column);
-      if ($table_column) {
-         if ($chado_table == $base_table) {
-           $cquery->orderBy('base.' . $table_column, $direction);
-         }
-         else {
-           // TODO: how do we handle a field that doesn't map to the base table.
-           // We would expect that all of these would be custom field and
-           // the ChadoField::queryOrder() function would be implemented.
-         }
+    // The Chado settings for a field are part of the instance and each bundle
+    // can have the same field but with different Chado mappings. Therefore,
+    // we need to iterate through the bundles to get the field instances.
+    foreach ($field['bundles']['TripalEntity'] as $bundle_name) {
+
+      // If there is a bundle filter for the entity and if the field is not
+      // associated with the bundle then skip it.
+      if (array_key_exists('bundle', $query->entityConditions)) {
+        if (strtolower($query->entityConditions['bundle']['operator']) == 'in' and
+            !array_key_exists($bundle_name, $query->entityConditions['bundle']['value'])) {
+          continue;
+        }
+        else if ($query->entityConditions['bundle']['value'] != $bundle_name) {
+          continue;
+        }
+      }
+
+      // See if there is a ChadoField class for this instance. If not then do
+      // our best to order the field.
+      $instance = field_info_instance('TripalEntity', $field_name, $bundle_name);
+      if (tripal_load_include_field_class($field_type)) {
+        $field_obj = new $field_type($field, $instance);
+        $field_obj->queryOrder($cquery, array('column' => $column, 'direction' => $direction));
       }
+      // There is no class so do our best to order the data by this field
       else {
-        // TODO: handle when the name can't be matched to a table column.
+        $base_table = $instance['settings']['base_table'];
+        $chado_table = $instance['settings']['chado_table'];
+        $table_column = tripal_get_chado_semweb_column($chado_table, $column);
+        if ($table_column) {
+           if ($chado_table == $base_table) {
+             $cquery->orderBy('base.' . $table_column, $direction);
+           }
+           else {
+             // TODO: how do we handle a field that doesn't map to the base table.
+             // We would expect that all of these would be custom field and
+             // the ChadoField::queryOrder() function would be implemented.
+           }
+        }
+        else {
+          // TODO: handle when the name can't be matched to a table column.
+        }
       }
     }
   }
 
-
   // Now join with the chado_entity table to get published records only.
   $cquery->join('chado_entity', 'CE', "CE.record_id = base.$pkey");
   $cquery->join('tripal_entity', 'TE', "CE.entity_id = TE.id");
   $cquery->fields('CE', array('entity_id'));
+  $cquery->fields('TE', array('bundle'));
   $cquery->condition('CE.data_table', $data_table);
   if (array_key_exists('start', $query->range)) {
     $cquery->range($query->range['start'], $query->range['length']);
@@ -528,7 +554,7 @@ function tripal_chado_field_storage_query($query) {
 
   $result = array();
   while ($record = $records->fetchObject()) {
-    $ids = array($record->entity_id, 0, $bundle_name);
+    $ids = array($record->entity_id, 0, $record->bundle);
     $result['TripalEntity'][$record->entity_id] = entity_create_stub_entity('TripalEntity', $ids);
   }
   return $result;

+ 13 - 31
tripal_chado/includes/tripal_chado.fields.inc

@@ -715,7 +715,7 @@ function tripal_chado_bundle_create_instances_base(&$info, $entity_type, $bundle
     }
     elseif ($table_name == 'analysis' and $column_name == 'sourceversion') {
       $base_info['label'] = 'Source Version';
-      $base_info['description'] = 'If hte source data set has a version include it here.';
+      $base_info['description'] = 'If the source data set has a version include it here.';
     }
     elseif ($table_name == 'analysis' and $column_name == 'algorithm') {
       $base_info['label'] = 'Source Version';
@@ -1447,34 +1447,18 @@ function tripal_chado_bundle_create_instances_linker(&$info, $entity_type, $bund
 }
 
 /**
- * Implements hook_form_FORM_ID_alter().
+ * Implements hook_bundle_create_user_field().
  *
- * The field_ui_field_overview_form is used for ordering and configuring the
- * fields attached to an entity.
- *
- * This function removes the property adder field as that is really not meant
- * for users to show or manage.
+ * A priviledged user has the ability to add new fields to the bundle. The
+ * chado_linker__prop and chado_linker__cvterm fields are allowed to be
+ * added dynamically by the user.  But, Drupal doesn't know whot to deal with
+ * it, so this function is called for any field attached to a TripalEntity
+ * bundle type. Any fields whose TripalField::$module argument is set to
+ * 'tripal_chado' and that can be added dynamically will result in a call
+ * to this function.
  */
-function tripal_chado_form_field_ui_field_overview_form_alter(&$form, &$form_state, $form_id) {
-
-  // Remove the kvproperty_addr field as it isn't ever displayed. It's just used
-  // on the add/edit form of an entity for adding new property fields.
-  $fields_names = element_children($form['fields']);
-  foreach ($fields_names as $field_name) {
-    $field_info = field_info_field($field_name);
-    if ($field_info['type'] == 'kvproperty_adder') {
-      unset($form['fields'][$field_name]);
-    }
-    if ($field_info['type'] == 'cvterm_class_adder') {
-      unset($form['fields'][$field_name]);
-    }
-  }
-}
+function tripal_chado_bundle_create_user_field($new_field, $bundle) {
 
-/**
- * Implements hook_form_field_ui_field_overview_add_new().
- */
-function tripal_chado_form_field_ui_field_overview_add_new($new_field, $bundle) {
   // Get the table this bundle is mapped to.
   $term = tripal_load_term_entity(array('term_id' => $bundle->term_id));
   $vocab = $term->vocab;
@@ -1509,11 +1493,6 @@ function tripal_chado_form_field_ui_field_overview_add_new($new_field, $bundle)
         'storage' => array(
           'type' => 'field_chado_storage',
         ),
-        'settings' => array(
-          'base_table' => $chado_table,
-          'chado_table' => $table_name,
-          'chado_column' => $pkey,
-        ),
       ));
 
       // Now add the instance
@@ -1526,6 +1505,9 @@ function tripal_chado_form_field_ui_field_overview_add_new($new_field, $bundle)
         'required' => FALSE,
         'settings' => array(
           'auto_attach' => TRUE,
+          'base_table' => $chado_table,
+          'chado_table' => $table_name,
+          'chado_column' => $pkey,
         ),
         'widget' => array(
           'type' => 'chado_linker__prop_widget',

+ 1 - 0
tripal_ws/includes/tripal_ws.rest_v0.1.inc

@@ -461,6 +461,7 @@ function tripal_ws_services_v0_1_get_content_type($api_url, &$response, $ws_path
   $cquery = clone $query;
   $cquery->count();
   $num_records = $cquery->execute();
+  $num_records = count($num_records['TripalEntity']);
 
   if (!$num_records) {
     $num_records = 0;