Browse Source

Added new widget, formater and instance classes

Stephen Ficklin 8 years ago
parent
commit
d41dbf1ca8

+ 0 - 48
tripal/api/tripal.entities.api.inc

@@ -243,54 +243,6 @@ function tripal_create_bundle($vocabulary, $accession, $term_name, &$error = '')
     // Get the bundle object.
     $bundle = tripal_load_bundle_entity(array('name' => $bundle_name));
 
-    // Get the list of fields created by Tripal modules and
-    // create them if they don't already exist.
-     foreach (module_implements('create_tripalfields') as $module) {
-      $function = $module . '_create_tripalfields';
-      if (function_exists($function)) {
-        $fields = $function('TripalEntity', $bundle);
-        if (!$fields){
-          continue;
-        }
-        foreach ($fields as $field_name => $info) {
-          $field_type = $info['type'];
-
-          // If the field already exists then skip it.
-          $field = field_info_field($info['field_name']);
-          if ($field) {
-            continue;
-          }
-          // Create the field.
-          $field = field_create_field($info);
-          if (!$field) {
-            tripal_set_message(t("Could not create new field: %field.",
-              array('%field' =>  $info['field_name'])), TRIPAL_ERROR);
-          }
-        }
-      }
-    }
-
-/*     // Now get the list of field instances to add to the bundle.
-    foreach (module_implements('create_tripalfield_instance') as $module) {
-      $function = $module . '_create_tripalfield_instance';
-      if (function_exists($function)) {
-        $fields = $function('TripalEntity', $bundle);
-        if (!$fields){
-          continue;
-        }
-        foreach ($fields as $field_name => $info) {
-          // If the field is already attached to this bundle then skip it.
-          $field = field_info_field($info['field_name']);
-          if ($field and array_key_exists('bundles', $field) and
-              array_key_exists('TripalEntity', $field['bundles']) and
-              in_array($bundle_name, $field['bundles']['TripalEntity'])) {
-            continue;
-          }
-          // Create the field instance.
-          $instance = field_create_instance($info);
-        }
-      }
-    } */
   }
   catch (Exception $e) {
     $transaction->rollback();

+ 69 - 77
tripal/api/tripal.fields.api.inc

@@ -1,71 +1,5 @@
 <?php
 
-/**
- * Adds a new field type to Tripal.
- *
- * Before a new field can be added to an entity, Drupal must know about the
- * field types.  This function is used to add new Tripal field types.
- *
- * @param $term
- *   The term that this field is associated with.  This should be an array as
- *   returned by tripal_get_term_details()
- * @param $options
- */
-function tripal_add_field_type($term, $options) {
-  // TODO: add checks to make sure we have properly formatted options.
-
-  // Add the term in case it doesn't already exist
-  tripal_add_term($term);
-
-  $field_type = $term['vocab']['short_name'] . '__' . $term['accession'];
-
-  // Make sure that the field type doesn't already exist
-  $type_id = db_select('tripal_field_types', 'TFT')
-    ->fields('TFT', array('term'))
-    ->condition('term', $field_type)
-    ->execute()
-    ->fetchField();
-  if ($type_id) {
-    return FALSE;
-  }
-  $type_id = db_insert('tripal_field_types')
-    ->fields(array(
-      'term' => $field_type,
-      'label' => $options['label'],
-      'description' => $options['description'],
-      'settings' => serialize($options['settings']),
-      'instance_settings' => serialize($options['instance_settings']),
-      'default_widget' => $options['default_widget'],
-      'default_formatter' => $options['default_formatter'],
-      'storage' => serialize($options['storage']),
-    ))
-    ->execute();
-}
-/**
- *
- */
-function tripal_get_field_type_info() {
-  // Make sure that the field type doesn't already exist
-  $records = db_select('tripal_field_types', 'TFT')
-    ->fields('TFT')
-    ->execute();
-  $info = array();
-  while($record = $records->fetchObject()) {
-    $info[$record->term] = array(
-      'label' => $record->label,
-      'description' => $record->description,
-      'settings' => unserialize($record->settings),
-      'instance_settings' => unserialize($record->instance_settings),
-      'default_widget' => $record->default_widget,
-      'default_formatter' => $record->default_formatter,
-      'storage' => unserialize($record->storage),
-      // Tripal fields should only be added to entities programmatically
-      // and not through the UI.
-      'no_ui' => TRUE,
-    );
-  }
-  return $info;
-}
 
 /**
  * Executes a TripalFieldQuery using the provided conditions.
@@ -100,16 +34,14 @@ function hook_field_storage_tquery($conditions, $orderBy) {
  * Retrieves a list of TripalField types.
  *
  * The TripalField classes can be added by a site developer and should be
- * placed in the [module]/includes/fields directory.  Tripal will support
+ * placed in the [module]/includes/TripalFields directory.  Tripal will support
  * any field as long as it is in this directory and extends the TripalField
  * class.  To support dynamic inclusion of new fields this function
  * will look for TripalField class files and return a type for
  * each one.
  *
- * @param $module
- *   The module that provides fields.
  * @return
- *   A list of TripalField field type.
+ *   A list of TripalField names.
  */
 function tripal_get_field_types() {
   $types = array();
@@ -123,30 +55,90 @@ function tripal_get_field_types() {
     foreach ($field_files as $file) {
       $field_type = $file->name;
       module_load_include('inc', $module, 'includes/TripalFields/' . $field_type);
-      if (class_exists($field_type)) {
+      if (class_exists($field_type) and get_parent_class($field_type) == 'TripalField') {
         $types[] = $field_type;
       }
     }
   }
   return $types;
 }
+/**
+ * Retrieves a list of TripalFieldWidgets.
+ *
+ * The TripalFieldWidget classes can be added by a site developer and should be
+ * placed in the [module]/includes/TripalFields directory.  Tripal will support
+ * any widget as long as it is in this directory and extends the
+ * TripalFieldWidget class.
+ *
+ * @return
+ *   A list of TripalFieldWidget names.
+ */
+function tripal_get_field_widgets() {
+  $widgets = array();
+
+  $modules = module_list(TRUE);
+  foreach ($modules as $module) {
+    // Find all of the files in the tripal_chado/includes/fields directory.
+    $fields_path = drupal_get_path('module', $module) . '/includes/TripalFields';
+    $field_files = file_scan_directory($fields_path, '/.*\.inc$/');
+    // Iterate through the fields, include the file and run the info function.
+    foreach ($field_files as $file) {
+      $field_type = $file->name;
+      module_load_include('inc', $module, 'includes/TripalFields/' . $field_type);
+      if (class_exists($field_type) and get_parent_class($field_type) == 'TripalFieldWidget') {
+        $widgets[] = $field_type;
+      }
+    }
+  }
+  return $widgets;
+}
+/**
+ * Retrieves a list of TripalFieldFormatters.
+ *
+ * The TripalFieldFormatter classes can be added by a site developer and should
+ * be placed in the [module]/includes/TripalFields directory.  Tripal will
+ * support any widget as long as it is in this directory and extends the
+ * TripalFieldFormatter class.
+ *
+ * @return
+ *   A list of TripalFieldFormatter names.
+ */
+function tripal_get_field_formatters() {
+  $formatters = array();
+
+  $modules = module_list(TRUE);
+  foreach ($modules as $module) {
+    // Find all of the files in the tripal_chado/includes/fields directory.
+    $fields_path = drupal_get_path('module', $module) . '/includes/TripalFields';
+    $field_files = file_scan_directory($fields_path, '/.*\.inc$/');
+    // Iterate through the fields, include the file and run the info function.
+    foreach ($field_files as $file) {
+      $field_type = $file->name;
+      module_load_include('inc', $module, 'includes/TripalFields/' . $field_type);
+      if (class_exists($field_type) and get_parent_class($field_type) == 'TripalFieldFormatter') {
+        $formatters[] = $field_type;
+      }
+    }
+  }
+  return $formatters;
+}
 /**
  * Loads the TripalField class file into scope.
  *
- * @param $field_type
- *   The type of field to instantiate
+ * @param $class
+ *   The class to instantiate
  *
  * @return
  *   TRUE if the field type class file was found, FALSE otherwise.
  */
-function tripal_load_include_field_type($field_type) {
+function tripal_load_include_field_class($class) {
 
   $modules = module_list(TRUE);
   foreach ($modules as $module) {
-    $file_path = realpath(".") . '/' . drupal_get_path('module', $module) . '/includes/TripalFields/' . $field_type . '.inc';
+    $file_path = realpath(".") . '/' . drupal_get_path('module', $module) . '/includes/TripalFields/' . $class . '.inc';
     if (file_exists($file_path)) {
-      module_load_include('inc', $module, 'includes/TripalFields/' . $field_type);
-      if (class_exists($field_type)) {
+      module_load_include('inc', $module, 'includes/TripalFields/' . $class);
+      if (class_exists($class)) {
         return TRUE;
       }
     }

+ 215 - 0
tripal/api/tripal.terms.api.inc

@@ -0,0 +1,215 @@
+<?php
+/**
+ * @section
+ * Vocabulary Hooks.
+ */
+
+/**
+ * A hook for specifying information about the data store for vocabularies.
+ *
+ * The storage backend for controlled vocabularies has traditionally been
+ * the Chado CV term tables. However, Tripal v3.0 introduces APIs for supporting
+ * other backends.  Therefore, this function indicates to Tripal which
+ * data stores are capable of providing support for terms.
+ *
+ * @return
+ *   An array describing the storage backends implemented by the module. The
+ *   keys are storage backend names. To avoid name clashes, storage
+ *   backend names should be prefixed with the name of the module that
+ *   exposes them. The values are arrays describing the storage backend,
+ *   with the following key/value pairs:
+ *
+ *   label: The human-readable name of the storage backend.
+ *   module:  The name of the module providing the support for this backend.
+ *   description: A short description for the storage backend.
+ *   settings: An array whose keys are the names of the settings available for
+ *     the storage backend, and whose values are the default values for
+ *     those settings.
+ */
+function hook_vocab_storage_info() {
+  return array(
+    'term_chado_storage' => array(
+      'label' => t('Chado storage'),
+      'description' => t('Integrates terms stored in the local Chado database with Tripal entities.'),
+      'settings' => array(),
+    ),
+  );
+}
+
+
+/**
+ * Creates a form for specifying a term for TripalEntity creation.
+ *
+ * This hook allows the module that implements a vocabulary storage backend
+ * to provide the form necessary to select a term that will then be used for
+ * creating a new TripalEntity type.  Tripal will expect that a 'vocabulary' and
+ * 'accession' are in the $form_state['storage'] array. The 'vocabulary' and
+ * must be the abbreviated uppercase vocabulary for the vocabulary (e.g. 'RO',
+ * 'SO', 'PATO', etc.).  The 'accession' must be the unique term ID (or
+ * accession) for the term in the vocabulary.
+ *
+ * @param $form
+ * @param $form_state
+ *
+ * @return
+ *   A form object.
+ */
+function hook_vocab_select_term_form(&$form, &$form_state) {
+
+  return $form;
+}
+/**
+ * Validates the hook_vocab_select_term_form().
+ *
+ * @param $name
+ */
+function hook_vocab_select_term_form_validate($form, &$form_state) {
+
+}
+/**
+ * Provides a form for importing vocabularies and their terms.
+ *
+ * Tripal allows for vocabularies to be stored separately from the biological
+ * data. This hook allows the default term storage backend to provide an
+ * approprite form for importing ontologies (either in OBO or OWL format).
+ *
+ * @param $form
+ * @param $form_state
+ *
+ */
+function hook_vocab_import_form($form, &$form_state) {
+  return $form;
+}
+function hook_vocab_import_form_validate($form, &$form_state) {
+
+}
+function hook_vocab_import_form_submit($form, &$form_state) {
+
+}
+
+/**
+ * Hook used by the default term storage backend to provide details for a term.
+ *
+ * This hook is called by the tripal_entity module to retrieve information
+ * about the term from the storage backend.  It must return an array with
+ * a set of keys.
+ *
+ * @param $vocabulary
+ *   The vocabulary of the vocabulary in which the term is found.
+ * @param $accession
+ *   The unique identifier (accession) for this term.
+ *
+ * @return
+ *   An array with at least the following keys:
+ *     -vocabulary : An associative array with the following keys
+ *       -name:  The short name for the vocabulary (e.g. SO, PATO, etc).
+ *       -description: The description of this vocabulary.
+ *       -url: The URL for the vocabulary.
+ *     -accession : The name unique ID of the term.
+ *     -url : The URL for the term.
+ *     -name : The name of the term.
+ *     -definition : The term's description.
+ *   any other keys may be added as desired. Returns NULL if the term
+ *   cannot be found.
+ */
+function hook_vocab_get_term($vocabulary, $accession) {
+  // See the tripal_chado_vocab_get_term() function for an example.
+
+}
+
+/**
+ * Hook used by the default term storage backend to add new terms.
+ *
+ * @param $details
+ *   An array with at least the following keys:
+ *     -vocabulary : An associative array with the following keys
+ *       -name:  The short name for the vocabulary (e.g. SO, PATO, etc).
+ *       -description: The description of this vocabulary.
+ *       -url: The URL for the vocabulary.
+ *     -accession : The name unique ID of the term.
+ *     -url : The URL for the term.
+ *     -name : The name of the term.
+ *     -definition : The term's description.
+ * @return
+ *   TRUE if the term was added, FALSE otherwise.  If the term already exists
+ *   it will be updated and the return value will be TRUE,
+ */
+function hook_vocab_add_term($details) {
+  // See the tripal_chado_vocab_set_term() function for an example.
+}
+
+
+
+/**
+ * Adds a term to the vocabulary storage backend.
+ *
+ * Use this function to add new terms dynamically to the vocabulary storage
+ * backend.  If the term already exists no new term is added.
+ *
+ * @param $details
+ *   An array with at least the following keys:
+ *     -vocabulary : An associative array with the following keys
+ *       -name:  The short name for the vocabulary (e.g. SO, PATO, etc).
+ *       -description: The description of this vocabulary.
+ *       -url: The URL for the vocabulary.
+ *     -accession : The name unique ID of the term.
+ *     -url : The URL for the term.
+ *     -name : The name of the term.
+ *     -definition : The term's description.
+ * @return
+ *   TRUE if the term was added, FALSE otherwise.  If the term already exists
+ *   it will be updated and the return value will be TRUE,
+ */
+function tripal_add_term($details) {
+  // TODO: we need some sort of administrative interface that lets the user
+  // switch to the desired vocabulary type. For now, we'll just use the
+  // first one in the list.
+  $stores = module_invoke_all('vocab_storage_info');
+  if (is_array($stores) and count($stores) > 0) {
+    $keys = array_keys($stores);
+    $module = $stores[$keys[0]]['module'];
+    $function = $module . '_vocab_add_term';
+    if (function_exists($function)) {
+      return $function($details);
+    }
+  }
+}
+
+/**
+ * Retrieves full information about a vocabulary term.
+ *
+ * Vocabularies are stored in a database backend.  Tripal has no requirements
+ * for how terms are stored.  By default, the tripal_chado modules provides
+ * storage for vocabularies and terms. This function will call the
+ * hook_vocab_get_term() function for the database backend that is housing the
+ * vocabularies and allow it to return the details about the term.
+ *
+ * @param $vocabulary
+ *   The vocabulary of the vocabulary in which the term is found.
+ * @param $accession
+ *   The unique identifier (accession) for this term.
+ *
+ * @return
+ *   An array with at least the following keys:
+ *     vocabulary : The short name of the vocabulary (e.g. SO, PATO, foaf).
+ *     accession : The name unique ID of the term.
+ *     url : The URL for the term.
+ *     name : The name of the term.
+ *     definition : The term's description.
+ *   any other keys may be added as desired. Returns NULL if the term
+ *   cannot be found.
+ */
+function tripal_get_term_details($vocabulary, $accession) {
+  // TODO: we need some sort of administrative interface that lets the user
+  // switch to the desired vocabulary type. For now, we'll just use the
+  // first one in the list.
+  $stores = module_invoke_all('vocab_storage_info');
+  if (is_array($stores) and count($stores) > 0) {
+    $keys = array_keys($stores);
+    $module = $stores[$keys[0]]['module'];
+    $function = $module . '_vocab_get_term';
+    if (function_exists($function)) {
+      return $function($vocabulary, $accession);
+    }
+  }
+}

+ 12 - 1
tripal/includes/TripalBundleController.inc

@@ -26,7 +26,16 @@ class TripalBundleController extends EntityAPIControllerExportable {
       'is_new' => TRUE,
       'data' => '',
     );
-    return parent::create($values);
+    $bundle = parent::create($values);
+
+    // Allow modules to make additions to the entity when it's created.
+    $modules = module_implements('bundle_create');
+    foreach ($modules as $module) {
+      $function = $module . '_bundle_create';
+      $function($bundle);
+    }
+
+    return $bundle;
   }
 
   /**
@@ -63,6 +72,8 @@ class TripalBundleController extends EntityAPIControllerExportable {
           }
         }
 
+        // TODO: this Chado sepcific code needs to be moved out of here!
+
         // Remove the entries in the chado_entity and tripal_entity t
         $query = db_select('chado_entity', 'ce');
         $query->join('tripal_entity', 'te', 'te.id = ce.entity_id');

+ 39 - 379
tripal/includes/TripalField.inc

@@ -1,45 +1,8 @@
 <?php
 
-
-/**
- * A base for fields attached Tripal Entities.
- *
- * This class is intended to simplify development of fields for Tripal Entities.
- * The Drupal Field API can still be used if desired, but the hope for this
- * class it to put the necessary functions in one place so that other Tripal
- * developers do not need to suffer the pain of navigating and learning the
- * Drupal Field API.
- *
- * To create a new field that can be attached to a Tripal Entity follow these
- * steps:
- * # Create a new class that inherits from TripalField
- * # Copy the editable constant variables (default_desription, default_label,
- *   default_settings and default_storage) to your class and edit as needed.
- *   Be sure not to rename these variables and be sure to keep the 'static'
- *   qualifier on them.
- * # Copy the functions you want to override. You will not need to copy the
- *   constructor, the static info() functions, or the getters and setters. In
- *   short you'll typically only need to override the Settingsform funtions,
- *   their validators and submitters, the load() function, and the widgetForm
- *   with it's validator and submitter.
- * # In your custom module implement the function hook_create_tripalfields()
- *   This function will be called anytime a new TripalEntity is created. It
- *   allows your module to create the new fields.  See the documentation for
- *   this function for creating the fields.  A field is usually only ever
- *   created once and can be reused on multiple entities.  So, even though
- *   this function is called everytime a new TripalEntity is created the fields
- *   will only be created once.
- * # In your custom module implement the function
- *   hook_create_tripalfield_instance().  This function is called anytime a
- *   new TripalEntity is created. It allows you to specify which fields are
- *   attached to an entity.  See the documentation for this hook function for
- *   more information.
- *
- */
 class TripalField {
 
 
-
   // --------------------------------------------------------------------------
   //                     EDITABLE STATIC CONSTANTS
   //
@@ -48,27 +11,40 @@ class TripalField {
   // the field and it's default widget and formatter.
   // --------------------------------------------------------------------------
 
+  // The term that this field maps to.  The format for the term should be:
+  // [vocab]:[accession] where [vocab] is the short name of the vocabulary
+  // and [acession] is the unique accession number for the term.  This term
+  // must already exist in the vocabulary storage backend. This
+  // value should never be changed once fields exist for this type.
+  public static $term = 'schema:Thing';
+
   // The default lable for this field.
-  public static $default_label = 'Tripal Field.';
+  public static $label = 'Tripal Field.';
 
   // The default description for this field.
-  public static $default_description = 'The generic base class for all
-       Tripal Fields. Replace this text as appropriate for the child implementation.';
+  public static $description = 'The generic base class for all Tripal fields. ' .
+    'Replace this text as appropriate for the child implementation.';
 
   // Provide a list of global settings. These can be accessed witihn the
   // globalSettingsForm.  When the globalSettingsForm is submitted then
   // Drupal will automatically change these settings for all fields.
-  public static $default_settings = array();
+  public static $settings = array();
 
   // Provide a list of instance specific settings. These can be access within
   // the instanceSettingsForm.  When the instanceSettingsForm is submitted
   // then Drupal with automatically change these settings for the instnace.
   // It is recommended to put settings at the instance level whenever possible.
-  public static $default_instance_settings  = array();
+  public static $instance_settings  = array();
 
   // Set this to the name of the storage backend that by default will support
   // this field.
-  public static $default_storage = 'tripal_no_storage';
+  public static $storage = 'tripal_no_storage';
+
+  // The default widget for this field.
+  public static $default_widget = '';
+
+  // The default formatter for this field.
+  public static $default_formatter = '';
 
   // --------------------------------------------------------------------------
   //              PROTECTED CLASS MEMBERS -- DO NOT OVERRIDE
@@ -99,6 +75,15 @@ class TripalField {
   public function __construct($field, $instance = NULL) {
     $this->field = $field;
     $this->instance = $instance;
+
+    $class = get_called_class();
+    // Make sure the term exist.
+    list($vocabulary, $accession) = preg_split('/:/', $class::$term);
+    $term = tripal_get_term_details($vocabulary, $accession);
+    if (!$term) {
+      //throw new Error(t('Cannot create TripalField of type "%term" as that
+      //    term does not exist.', array('%term' => $class::$term)));
+    }
   }
 
   // --------------------------------------------------------------------------
@@ -116,72 +101,23 @@ class TripalField {
    *   describing the field type. The keys are the same as for the
    *   hook_field_info() function.
    */
-  public static function globalInfo() {
-    $field_type = get_called_class();
+  public static function info() {
+    $class = get_called_class();
     return array(
-      'label' => $field_type::$default_label,
-      'description' => $field_type::$default_description,
-      'default_widget' => $field_type . '_widget',
-      'default_formatter' => $field_type . '_formatter',
-      'settings' => $field_type::$default_settings,
-      'instance_settings' => $field_type::$default_instance_settings,
+      'label' => $class::$label,
+      'description' => $class::$description,
+      'default_widget' => $class::$default_widget,
+      'default_formatter' => $class::$default_formatter,
+      'settings' => $class::$settings,
+      'instance_settings' => $class::$instance_settings,
       'storage' => array(
-        'type' => $field_type::$default_storage,
+        'type' => $class::$storage,
         'module' => 'tripal',
         'active' => TRUE
       ),
     );
   }
 
-  /**
-   * Provides information about the widgets provided by this field.
-   *
-   * This function corresponds to the hook_field_widget_info() function of
-   * the Drupal Field API.
-   *
-   * This is a static function as it provides default values for all of the
-   * widgets for this field type, and thus we don't need an instantiated
-   * object to provide this information.
-   *
-   * @return
-   *   An associative array with key/value pairs compatible with those from the
-   *   hook_field_widget_info() function of the Drupal Field API.
-   */
-  public static function widgetInfo() {
-    $field_type = get_called_class();
-    return array(
-      $field_type . '_widget' => array(
-        'label' => $field_type::$default_label,
-        'field types' => array($field_type)
-      ),
-    );
-  }
-
-  /**
-   * Provides information about the formatter for this field.
-   *
-   * This function corresponds to the hook_field_formatter_info() function of
-   * the Drupal Field API.
-   *
-   * This is a static function as it provides default values for all of the
-   * formatters for this field type, and thus we don't need an instantiated
-   * object to provide this information.
-   *
-   * @return
-   *   An associative array with key/value paris compatible with those from the
-   *   hook_field_formatter_info() function of the Drupal Field API.
-   *
-   */
-  public static function formatterInfo() {
-    $field_type = get_called_class();
-    return array(
-      $field_type . '_formatter' => array(
-        'label' => $field_type::$default_label,
-        'field types' => array($field_type),
-        'settings' => array(),
-      ),
-    );
-  }
 
   // --------------------------------------------------------------------------
   //                 GETTERS AND SETTERS -- DO NOT OVERRIDE
@@ -205,185 +141,6 @@ class TripalField {
   }
 
 
-  // --------------------------------------------------------------------------
-  //                 OVERRIDEABLE FUNCTIONS
-  // --------------------------------------------------------------------------
-
-  /**
-   * Provides a summary of the formatter settings.
-   *
-   * This function corresponds to the hook_field_formatter_settings_summary()
-   * function of the Drupal Field API.
-   *
-   * On the 'Manage Display' page of the content type administration page,
-   * fields are allowed to provide a settings form.  This settings form can
-   * be used to allow the site admin to define how the field should be
-   * formatted.  The settings are then available for the formatter()
-   * function of this class.  This function provides a text-based description
-   * of the settings for the site developer to see.  It appears on the manage
-   * display page inline with the field.  A field must always return a
-   * value in this function if the settings form gear button is to appear.
-   *
-   * See the hook_field_formatter_settings_summary() function for more
-   * information.
-   *
-   * @param $field
-   * @param $instance
-   * @param $view_mode
-   *
-   * @return string
-   *   A string that provides a very brief summary of the field settings
-   *   to the user.
-   *
-   */
-  public function formatterSettingsSummary($view_mode) {
-
-  }
-
-  /**
-   * Provides the field's setting form.
-   *
-   * This function corresponds to the hook_field_formatter_settings_form()
-   * function of the Drupal Field API.
-   *
-   * The settings form appears on the 'Manage Display' page of the content
-   * type administration page. This function provides the form that will
-   * appear on that page.
-   *
-   * To add a validate function, please create a static function in the
-   * implementing class, and indicate that this function should be used
-   * in the form array that is returned by this function.
-   *
-   * This form will not be displayed if the formatter_settings_summary()
-   * function does not return anything.
-   *
-   * @param $field
-   * @param $instance
-   * @param $view_mode
-   * @param $form
-   * @param $form_state
-   *
-   * @return
-   *   A Drupal Form array containing the settings form for this field.
-   */
-  public function formatterSettingsForm($view_mode, $form, &$form_state) {
-
-  }
-
-  /**
-   *  Provides the display for a field
-   *
-   * This function corresponds to the hook_field_formatter_view()
-   * function of the Drupal Field API.
-   *
-   *  This function provides the display for a field when it is viewed on
-   *  the web page.  The content returned by the formatter should only include
-   *  what is present in the $items[$delta]['values] array. This way, the
-   *  contents that are displayed on the page, via webservices and downloaded
-   *  into a CSV file will always be identical.  The view need not show all
-   *  of the data in the 'values' array.
-   *
-   *  @param $element
-   *  @param $entity_type
-   *  @param $entity
-   *  @param $langcode
-   *  @param $items
-   *  @param $display
-   *
-   *  @return
-   *    An element array compatible with that returned by the
-   *    hook_field_formatter_view() function.
-   */
-  public function formatterView(&$element, $entity_type, $entity, $langcode, $items, $display) {
-
-    foreach($items as $delta => $item) {
-      $element[$delta] = array(
-        '#type' => 'markup',
-        '#markup' => $item['value'],
-      );
-    }
-  }
-
-  /**
-   * Provides the form for editing of this field.
-   *
-   * This function corresponds to the hook_field_widget_form()
-   * function of the Drupal Field API.
-   *
-   * This form is diplayed when the user creates a new entity or edits an
-   * existing entity.  If the field is attached to the entity then the form
-   * provided by this function will be displayed.
-   *
-   * At a minimum, the form must have a 'value' element.  For Tripal, the
-   * 'value' element of a field always corresponds to the value that is
-   * presented to the end-user either directly on the page (with formatting)
-   * or via web services, or some other mechanism.  However, the 'value' is
-   * sometimes not enough for a field.  For example, the Tripal Chado module
-   * maps fields to table columns and sometimes those columns are foreign keys
-   * therefore, the Tripal Chado modules does not just use the 'value' but adds
-   * additional elements to help link records via FKs.  But even in this case
-   * the 'value' element must always be present in the return form and in such
-   * cases it's value should be set equal to that added in the 'load' function.
-   *
-   * @param $widget
-   * @param $form
-   *   The form structure where widgets are being attached to. This might be a
-   *   full form structure, or a sub-element of a larger form.
-   * @param $form_state
-   *   An associative array containing the current state of the form.
-   * @param $langcode
-   *   The language associated with $items.
-   * @param $items
-   *   Array of default values for this field.
-   * @param $delta
-   *   The order of this item in the array of subelements (0, 1, 2, etc).
-   * @param $element
-   * A form element array containing basic properties for the widget:
-   *  - #entity_type: The name of the entity the field is attached to.
-   *  - #bundle: The name of the field bundle the field is contained in.
-   *  - #field_name: The name of the field.
-   *  - #language: The language the field is being edited in.
-   *  - #field_parents: The 'parents' space for the field in the form. Most
-   *    widgets can simply overlook this property. This identifies the location
-   *    where the field values are placed within $form_state['values'], and is
-   *    used to access processing information for the field through the
-   *    field_form_get_state() and field_form_set_state() functions.
-   *  - #columns: A list of field storage columns of the field.
-   *  - #title: The sanitized element label for the field instance, ready for
-   *    output.
-   *  - #description: The sanitized element description for the field instance,
-   *    ready for output.
-   *  - #required: A Boolean indicating whether the element value is required;
-   *    for required multiple value fields, only the first widget's values are
-   *    required.
-   *  - #delta: The order of this item in the array of subelements; see
-   *    $delta above
-   */
-  public function widgetForm(&$widget, &$form, &$form_state, $langcode, $items, $delta, $element) {
-
-    $widget['value'] = array(
-      '#type' => 'value',
-      '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
-    );
-    $widget['#field'] = $this->field;
-    $widget['#instance'] = $this->instance;
-    $widget['#element_validate'] = array('tripal_field_widget_form_validate');
-  }
-
-  /**
-   * Performs validation of the widgetForm.
-   *
-   * Use this validate to ensure that form values are entered correctly.  Note
-   * this is different from the validate() function which ensures that the
-   * field data meets expectations.
-   *
-   * @param $form
-   * @param $form_state
-   */
-  public function widgetFormValidate($form, &$form_state, $entity_type, $entity, $langcode, $delta) {
-
-  }
-
   /**
    *  Perform validation of the field regardless how it is updated.
    *
@@ -417,45 +174,6 @@ class TripalField {
   }
 
 
-  /**
-   * Performs extra commands when the entity form is submitted.
-   *
-   * Drupal typically does not provide a submit hook for fields.  The
-   * TripalField provides one to allow for behind-the-scenes actions to
-   * occur.   This function should never be used for updates, deletes or
-   * inserts for the Chado table associated with the field.  Rather, the
-   * storage backend should be allowed to handle inserts, updates deletes.
-   * However, it is permissible to perform inserts, updates or deletions within
-   * Chado using this function.  Those operations can be performed if needed but
-   * on other tables not directly associated with the field.
-   *
-   * An example is the chado.feature_synonym table.  The chado_linker__synonym
-   * field allows the user to provide a brand new synonynm and it must add it
-   * to the chado.synonym table prior to the record in the
-   * chado.feature_synonym table.  This insert occurs in the widgetFormSubmit
-   * function.
-   *
-   *  @param $entity_type
-   *    The type of $entity.
-   *  @param $entity
-   *    The entity for the operation.
-   *  @param $field
-   *    The field structure for the operation.
-   *  @param $instance
-   *    The instance structure for $field on $entity's bundle.
-   *  @param $langcode
-   *    The language associated with $items.
-   *  @param $items
-   *    $entity->{$field['field_name']}[$langcode], or an empty array if unset.
-   *  @param $form
-   *    The submitted form array.
-   *  @param $form_state.
-   *    The form state array.
-   */
-  public function widgetFormSubmit($form, &$form_state, $entity_type, $entity, $langcode, $delta) {
-
-  }
-
   /**
    * Loads the field values from the underlying data store.
    *
@@ -488,64 +206,6 @@ class TripalField {
 
   }
 
-  /**
-   * Provides a form for the 'Field Settings' of an instance of this field.
-   *
-   * This function corresponds to the hook_field_instance_settings_form()
-   * function of the Drupal Field API.
-   *
-   * Validation of the instance settings form is not supported by Drupal, but
-   * the TripalField class does provide a mechanism for supporting validation.
-   * To allow for validation of your setting form you must call the parent
-   * in your child class:
-   *
-   * @code
-   *   $element = parent::instanceSettingsForm();
-   * @endcode
-   *
-   * Please note, the form generated with this function does not easily
-   * support AJAX calls in the same way that other Drupal forms do.  If you
-   * need to use AJAX you must manually alter the $form in your ajax call.
-   * The typical way to handle updating the form via an AJAX call is to make
-   * the changes in the form function itself but that doesn't work here.
-   */
-  public function instanceSettingsForm() {
-    $settings = $this->instance['settings'];
-    $element = array();
-
-    //     $element['semantic_web'] = array(
-    //       '#type' => 'textfield',
-    //       '#title' => 'Semantic Web',
-    //       '#description' => t('Each field must be associated with a term
-    //           from a controlled vocabulary.  This allows computer programs to understand
-    //           the data provided on this site.  Please be cautions changing these
-    //           values.  Defaults are set by Tripal and sites that use the same
-    //           terms can exchange information.'),
-    //       '#collapsed' => TRUE,
-    //       '#collapsible' => TRUE,
-    //       '#tree' => TRUE,
-    //     );
-    $element['#field'] = $this->field;
-    $element['#instance'] = $this->instance;
-    $element['#element_validate'][] = 'tripal_field_instance_settings_form_validate';
-
-    return $element;
-  }
-  /**
-   * Provides validation of the instance settings form.
-   *
-   * There is no equivalent function in the Drupal Field API. Validation
-   * of instance settings forms in Drupal is not supported. However, the
-   * TripalField provides this function to fill the gap.  See the
-   * documentation for the instanceSettingsForm() function for instructions
-   * to support use of this function.
-   *
-   * @param $form
-   * @param $form_state
-   */
-  public function instanceSettingsFormValidate($form, &$form_state) {
-
-  }
 
   /**
    * Provides a form for the 'Field Settings' of the field management page.
@@ -560,7 +220,7 @@ class TripalField {
    * @param $has_data
    *   TRUE if the field already has data, FALSE if not.
    */
-  public function globalSettingsForm($has_data) {
+  public function settingsForm($has_data) {
     $settings = $this->field['settings'];
     $element = array();
 
@@ -587,7 +247,7 @@ class TripalField {
    * @param unknown $form
    * @param unknown $form_state
    */
-  public function globalSettingsFormValidate($form, &$form_state) {
+  public function settingsFormValidate($form, &$form_state) {
 
   }
 

+ 148 - 0
tripal/includes/TripalFieldFormatter.inc

@@ -0,0 +1,148 @@
+<?php
+
+class TripalFieldFormatter {
+  // The default lable for this field.
+  public static $label = 'Tripal Field.';
+
+  // The list of field types for which this formatter is appropriate.
+  public static $field_types = array();
+
+  // The list of default settings for this formatter.
+  public static $settings = array();
+
+  /**
+   * Instantiates a new TripalFieldFormatter object.
+   *
+   * @param $field
+   *   An array containing the field data as returned by field_info_field()
+   * @param $instance
+   *   (Optional). Set the instance of this field when one is available. This
+   *   is necessary when working with instance specific functions such as the
+   *   formatterSettingsForm, widgetForm, etc.
+   */
+  public function __construct($field, $instance = NULL) {
+    $this->field = $field;
+    $this->instance = $instance;
+  }
+
+  /**
+   * Provides information about the formatter for this field.
+   *
+   * This function corresponds to the hook_field_formatter_info() function of
+   * the Drupal Field API.
+   *
+   * This is a static function as it provides default values for all of the
+   * formatters for this field type, and thus we don't need an instantiated
+   * object to provide this information.
+   *
+   * @return
+   *   An associative array with key/value paris compatible with those from the
+   *   hook_field_formatter_info() function of the Drupal Field API.
+   *
+   */
+  public static function info() {
+    $class = get_called_class();
+    return array(
+      'label' => $class::$label,
+      'field types' => $class::$field_types,
+      'settings' => $class::$settings,
+    );
+  }
+
+  /**
+   * Provides the field's setting form.
+   *
+   * This function corresponds to the hook_field_formatter_settings_form()
+   * function of the Drupal Field API.
+   *
+   * The settings form appears on the 'Manage Display' page of the content
+   * type administration page. This function provides the form that will
+   * appear on that page.
+   *
+   * To add a validate function, please create a static function in the
+   * implementing class, and indicate that this function should be used
+   * in the form array that is returned by this function.
+   *
+   * This form will not be displayed if the formatter_settings_summary()
+   * function does not return anything.
+   *
+   * @param $field
+   * @param $instance
+   * @param $view_mode
+   * @param $form
+   * @param $form_state
+   *
+   * @return
+   *   A Drupal Form array containing the settings form for this field.
+   */
+  public function settingsForm($view_mode, $form, &$form_state) {
+
+  }
+
+  /**
+   *  Provides the display for a field
+   *
+   * This function corresponds to the hook_field_formatter_view()
+   * function of the Drupal Field API.
+   *
+   *  This function provides the display for a field when it is viewed on
+   *  the web page.  The content returned by the formatter should only include
+   *  what is present in the $items[$delta]['values] array. This way, the
+   *  contents that are displayed on the page, via webservices and downloaded
+   *  into a CSV file will always be identical.  The view need not show all
+   *  of the data in the 'values' array.
+   *
+   *  @param $element
+   *  @param $entity_type
+   *  @param $entity
+   *  @param $langcode
+   *  @param $items
+   *  @param $display
+   *
+   *  @return
+   *    An element array compatible with that returned by the
+   *    hook_field_formatter_view() function.
+   */
+  public function view(&$element, $entity_type, $entity, $langcode, $items, $display) {
+
+    foreach($items as $delta => $item) {
+      $element[$delta] = array(
+        '#type' => 'markup',
+        '#markup' => $item['value'],
+      );
+    }
+  }
+
+  /**
+   * Provides a summary of the formatter settings.
+   *
+   * This function corresponds to the hook_field_formatter_settings_summary()
+   * function of the Drupal Field API.
+   *
+   * On the 'Manage Display' page of the content type administration page,
+   * fields are allowed to provide a settings form.  This settings form can
+   * be used to allow the site admin to define how the field should be
+   * formatted.  The settings are then available for the formatter()
+   * function of this class.  This function provides a text-based description
+   * of the settings for the site developer to see.  It appears on the manage
+   * display page inline with the field.  A field must always return a
+   * value in this function if the settings form gear button is to appear.
+   *
+   * See the hook_field_formatter_settings_summary() function for more
+   * information.
+   *
+   * @param $field
+   * @param $instance
+   * @param $view_mode
+   *
+   * @return string
+   *   A string that provides a very brief summary of the field settings
+   *   to the user.
+   *
+   */
+  public function settingsSummary($view_mode) {
+
+  }
+
+
+}

+ 62 - 0
tripal/includes/TripalFieldInstance.inc

@@ -0,0 +1,62 @@
+<?php
+
+class TripalFieldInstance {
+  /**
+   * Provides a form for the 'Field Settings' of an instance of this field.
+   *
+   * This function corresponds to the hook_field_instance_settings_form()
+   * function of the Drupal Field API.
+   *
+   * Validation of the instance settings form is not supported by Drupal, but
+   * the TripalField class does provide a mechanism for supporting validation.
+   * To allow for validation of your setting form you must call the parent
+   * in your child class:
+   *
+   * @code
+   *   $element = parent::instanceSettingsForm();
+   * @endcode
+   *
+   * Please note, the form generated with this function does not easily
+   * support AJAX calls in the same way that other Drupal forms do.  If you
+   * need to use AJAX you must manually alter the $form in your ajax call.
+   * The typical way to handle updating the form via an AJAX call is to make
+   * the changes in the form function itself but that doesn't work here.
+   */
+  public function instanceSettingsForm() {
+    $settings = $this->instance['settings'];
+    $element = array();
+
+    //     $element['semantic_web'] = array(
+    //       '#type' => 'textfield',
+    //       '#title' => 'Semantic Web',
+    //       '#description' => t('Each field must be associated with a term
+    //           from a controlled vocabulary.  This allows computer programs to understand
+    //           the data provided on this site.  Please be cautions changing these
+    //           values.  Defaults are set by Tripal and sites that use the same
+    //           terms can exchange information.'),
+    //       '#collapsed' => TRUE,
+    //       '#collapsible' => TRUE,
+    //       '#tree' => TRUE,
+    //     );
+    $element['#field'] = $this->field;
+    $element['#instance'] = $this->instance;
+    $element['#element_validate'][] = 'tripal_field_instance_settings_form_validate';
+
+    return $element;
+  }
+  /**
+  * Provides validation of the instance settings form.
+  *
+  * There is no equivalent function in the Drupal Field API. Validation
+  * of instance settings forms in Drupal is not supported. However, the
+  * TripalField provides this function to fill the gap.  See the
+  * documentation for the instanceSettingsForm() function for instructions
+  * to support use of this function.
+  *
+  * @param $form
+  * @param $form_state
+  */
+  public function instanceSettingsFormValidate($form, &$form_state) {
+
+  }
+}

+ 167 - 0
tripal/includes/TripalFieldWidget.inc

@@ -0,0 +1,167 @@
+<?php
+
+class TripalFieldWidget {
+  // The default lable for this field.
+  public static $label = 'Tripal Field.';
+
+  // The list of field types for which this formatter is appropriate.
+  public static $field_types = array('no_widget');
+
+
+  /**
+   * Instantiates a new TripalFieldWidget object.
+   *
+   * @param $field
+   *   An array containing the field data as returned by field_info_field()
+   * @param $instance
+   *   (Optional). Set the instance of this field when one is available. This
+   *   is necessary when working with instance specific functions such as the
+   *   formatterSettingsForm, widgetForm, etc.
+   */
+  public function __construct($field, $instance = NULL) {
+    $this->field = $field;
+    $this->instance = $instance;
+  }
+
+  /**
+   * Provides information about the widgets provided by this field.
+   *
+   * This function corresponds to the hook_field_widget_info() function of
+   * the Drupal Field API.
+   *
+   * This is a static function as it provides default values for all of the
+   * widgets for this field type, and thus we don't need an instantiated
+   * object to provide this information.
+   *
+   * @return
+   *   An associative array with key/value pairs compatible with those from the
+   *   hook_field_widget_info() function of the Drupal Field API.
+   */
+  public static function info() {
+    $class = get_called_class();
+    return array(
+      'label' => $class::$label,
+      'field types' => $class::$field_types,
+    );
+  }
+
+  /**
+   * Provides the form for editing of this field.
+   *
+   * This function corresponds to the hook_field_widget_form()
+   * function of the Drupal Field API.
+   *
+   * This form is diplayed when the user creates a new entity or edits an
+   * existing entity.  If the field is attached to the entity then the form
+   * provided by this function will be displayed.
+   *
+   * At a minimum, the form must have a 'value' element.  For Tripal, the
+   * 'value' element of a field always corresponds to the value that is
+   * presented to the end-user either directly on the page (with formatting)
+   * or via web services, or some other mechanism.  However, the 'value' is
+   * sometimes not enough for a field.  For example, the Tripal Chado module
+   * maps fields to table columns and sometimes those columns are foreign keys
+   * therefore, the Tripal Chado modules does not just use the 'value' but adds
+   * additional elements to help link records via FKs.  But even in this case
+   * the 'value' element must always be present in the return form and in such
+   * cases it's value should be set equal to that added in the 'load' function.
+   *
+   * @param $widget
+   * @param $form
+   *   The form structure where widgets are being attached to. This might be a
+   *   full form structure, or a sub-element of a larger form.
+   * @param $form_state
+   *   An associative array containing the current state of the form.
+   * @param $langcode
+   *   The language associated with $items.
+   * @param $items
+   *   Array of default values for this field.
+   * @param $delta
+   *   The order of this item in the array of subelements (0, 1, 2, etc).
+   * @param $element
+   * A form element array containing basic properties for the widget:
+   *  - #entity_type: The name of the entity the field is attached to.
+   *  - #bundle: The name of the field bundle the field is contained in.
+   *  - #field_name: The name of the field.
+   *  - #language: The language the field is being edited in.
+   *  - #field_parents: The 'parents' space for the field in the form. Most
+   *    widgets can simply overlook this property. This identifies the location
+   *    where the field values are placed within $form_state['values'], and is
+   *    used to access processing information for the field through the
+   *    field_form_get_state() and field_form_set_state() functions.
+   *  - #columns: A list of field storage columns of the field.
+   *  - #title: The sanitized element label for the field instance, ready for
+   *    output.
+   *  - #description: The sanitized element description for the field instance,
+   *    ready for output.
+   *  - #required: A Boolean indicating whether the element value is required;
+   *    for required multiple value fields, only the first widget's values are
+   *    required.
+   *  - #delta: The order of this item in the array of subelements; see
+   *    $delta above
+   */
+  public function form(&$widget, &$form, &$form_state, $langcode, $items, $delta, $element) {
+
+    $widget['value'] = array(
+      '#type' => 'value',
+      '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
+    );
+    $widget['#field'] = $this->field;
+    $widget['#instance'] = $this->instance;
+    $widget['#element_validate'] = array('tripal_field_widget_form_validate');
+  }
+
+  /**
+   * Performs validation of the widgetForm.
+   *
+   * Use this validate to ensure that form values are entered correctly.  Note
+   * this is different from the validate() function which ensures that the
+   * field data meets expectations.
+   *
+   * @param $form
+   * @param $form_state
+   */
+  public function validate($form, &$form_state, $entity_type, $entity, $langcode, $delta) {
+
+  }
+
+
+  /**
+   * Performs extra commands when the entity form is submitted.
+   *
+   * Drupal typically does not provide a submit hook for fields.  The
+   * TripalField provides one to allow for behind-the-scenes actions to
+   * occur.   This function should never be used for updates, deletes or
+   * inserts for the Chado table associated with the field.  Rather, the
+   * storage backend should be allowed to handle inserts, updates deletes.
+   * However, it is permissible to perform inserts, updates or deletions within
+   * Chado using this function.  Those operations can be performed if needed but
+   * on other tables not directly associated with the field.
+   *
+   * An example is the chado.feature_synonym table.  The chado_linker__synonym
+   * field allows the user to provide a brand new synonynm and it must add it
+   * to the chado.synonym table prior to the record in the
+   * chado.feature_synonym table.  This insert occurs in the widgetFormSubmit
+   * function.
+   *
+   *  @param $entity_type
+   *    The type of $entity.
+   *  @param $entity
+   *    The entity for the operation.
+   *  @param $field
+   *    The field structure for the operation.
+   *  @param $instance
+   *    The instance structure for $field on $entity's bundle.
+   *  @param $langcode
+   *    The language associated with $items.
+   *  @param $items
+   *    $entity->{$field['field_name']}[$langcode], or an empty array if unset.
+   *  @param $form
+   *    The submitted form array.
+   *  @param $form_state.
+   *    The form state array.
+   */
+  public function submit($form, &$form_state, $entity_type, $entity, $langcode, $delta) {
+
+  }
+}

+ 79 - 0
tripal/includes/TripalFields/rdfs__type.inc

@@ -0,0 +1,79 @@
+<?php
+
+class rdfs__type extends TripalField {
+
+  // The term that this field maps to.  The format for the term should be:
+  // [vocab]:[accession] where [vocab] is the short name of the vocabulary
+  // and [acession] is the unique accession number for the term.  This
+  // value should never be changed once fields exist for this type.
+  public static $term = 'rdfs:type';
+
+  // The default lable for this field.
+  public static $label = 'Content Type';
+
+  // The default description for this field.
+  public static $description = 'The resource content type.';
+
+  // Provide a list of global settings. These can be accessed witihn the
+  // globalSettingsForm.  When the globalSettingsForm is submitted then
+  // Drupal will automatically change these settings for all fields.
+  public static $settings = array();
+
+  // Provide a list of instance specific settings. These can be access within
+  // the instanceSettingsForm.  When the instanceSettingsForm is submitted
+  // then Drupal with automatically change these settings for the instnace.
+  // It is recommended to put settings at the instance level whenever possible.
+  public static $instance_settings  = array();
+
+  // Set this to the name of the storage backend that by default will support
+  // this field.
+  public static $storage = 'tripal_no_storage';
+
+  // The default widget for this field.
+  public static $default_widget = 'rdfs__type_widget';
+
+  // The default formatter for this field.
+  public static $default_formatter = 'rdfs__type_formatter';
+
+  /**
+   * @see TripalField::load()
+   */
+  public function load($entity, $details = array()) {
+    $bundle = tripal_load_bundle_entity(array('name' => $entity->bundle));
+    $entity->{$this->field['field_name']}['und'][0]['value'] = $bundle->label;
+  }
+
+
+  /**
+   *  @see TripalField::settingsForm()
+   */
+  public function settingsForm($has_data) {
+    $settings = $this->field['settings'];
+    $element = array();
+
+//     $element['semantic_web'] = array(
+//       '#type' => 'textfield',
+//       '#title' => 'Semantic Web',
+//       '#description' => t('Each field must be associated with a term
+//           from a controlled vocabulary.  This allows computer programs to understand
+//           the data provided on this site.  Please be cautions changing these
+//           values.  Defaults are set by Tripal and sites that use the same
+//           terms can exchange information.'),
+//       '#collapsed' => TRUE,
+//       '#collapsible' => TRUE,
+//       '#tree' => TRUE,
+//     );
+    $element['#field'] = $this->field;
+    $element['#instance'] = $this->instance;
+    $element['#element_validate'][] = 'tripal_field_settings_form_validate';
+
+    return $element;
+  }
+  /**
+   *  @see TripalField::settingsFormValidate()
+   */
+  public function settingsFormValidate($form, &$form_state) {
+
+  }
+
+}

+ 24 - 0
tripal/includes/TripalFields/rdfs__type_formatter.inc

@@ -0,0 +1,24 @@
+<?php
+
+class rdfs__type_formatter extends TripalFieldFormatter {
+  // The default lable for this field.
+  public static $label = 'Content Type';
+
+  // The list of field types for which this formatter is appropriate.
+  public static $field_types = array('rdfs__type');
+
+  // The list of default settings for this formatter.
+  public static $settings = array();
+
+  /**
+   * @see TripalFieldFormatter::view()
+   */
+  public function view(&$element, $entity_type, $entity, $langcode, $items, $display) {
+    foreach ($items as $delta => $item) {
+      $element[$delta] = array(
+        '#type' => 'markup',
+        '#markup' => $item['value'],
+      );
+    }
+  }
+}

+ 23 - 0
tripal/includes/TripalFields/rdfs__type_widget.inc

@@ -0,0 +1,23 @@
+<?php
+
+class rdfs__type_widget extends TripalFieldWidget {
+  // The default lable for this field.
+  public static $label = 'Content Type';
+
+  // The list of field types for which this formatter is appropriate.
+  public static $field_types = array('rdfs__type');
+
+  /**
+   * @see TripalFieldWidget::form()
+   */
+  public function form(&$widget, &$form, &$form_state, $langcode, $items,
+      $delta, $element) {
+
+    parent::form($widget, $form, $form_state, $langcode, $items, $delta, $element);
+
+    $widget['value'] = array(
+      '#type' => 'value',
+      '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
+    );
+  }
+}

+ 3 - 3
tripal/includes/tripal.entity.inc

@@ -46,10 +46,10 @@ function tripal_entity_info() {
     'access callback' => 'tripal_entity_access',
 
     // FALSE disables caching. Caching functionality is handled by Drupal core.
-//    'static cache' => FALSE,
+    'static cache' => TRUE,
 
-    // Disable caching of fields
-//    'field cache' => FALSE,
+    // Caching of fields
+    'field cache' => TRUE,
 
     // This entity doesn't support bundles.
     'bundles' => array (),

+ 3 - 1
tripal/includes/tripal.field_storage.inc

@@ -51,8 +51,10 @@ function tripal_field_storage_load($entity_type, $entities, $age,
       // Allow the creating module to alter the value if desired.  The
       // module should do this if the field has any other form elements
       // that need populationg besides the value which was set above.
-      tripal_load_include_field_type($field_type);
+      tripal_load_include_field_class($field_type);
       if (class_exists($field_type)) {
+
+
         $tfield = new $field_type($field);
         $tfield->load($entity);
       }

+ 79 - 108
tripal/includes/tripal.fields.inc

@@ -10,9 +10,13 @@
  * discovered and listed for Drupal by this function.
  */
 function tripal_field_info() {
-   $info = tripal_get_field_type_info();
-   dpm($info);
-   return $info;
+
+  $info = array();
+  $field_types = tripal_get_field_types();
+  foreach ($field_types as $field_type) {
+    $info[$field_type] = $field_type::info();
+  }
+  return $info;
 }
 
 /**
@@ -37,107 +41,76 @@ function tripal_field_info_alter(&$info) {
  * Implements hook_field_widget_info();
  */
 function tripal_field_widget_info() {
-//   $info = array();
+  $info = array();
+  $widgets = tripal_get_field_widgets();
+  foreach ($widgets as $widget) {
+    $info[$widget] = $widget::info();
+  }
+  return $info;
+}
+/**
+ * Implements hook_field_widget_info_alter();
+ */
+function tripal_field_widget_info_alter(&$info) {
 
-//   $field_types = tripal_get_field_types();
-//   foreach ($field_types as $field_type) {
-//     $info += $field_type::widgetInfo();
-//   }
-//   return $info;
-  return array(
-    'tripal_generic_key_value_widget' => array(
-      'label' => 'Generic key/value',
-      'field types' => array('tripal_key_value')
-    ),
-  );
 }
 
 /**
  * Implements hook_field_formatter_info().
  */
 function tripal_field_formatter_info() {
-//   $info = array();
-
-//   $field_types = tripal_get_field_types();
-//   foreach ($field_types as $field_type) {
-//     $info += $field_type::formatterInfo();
-//   }
-//   return $info;
-  return array(
-    'tripal_generic_key_value_formatter' => array(
-      'label' => 'Values',
-      'field types' => array('tripal_key_value'),
-      'settings' => array(),
-    ),
-  );
+  $info = array();
+  $formatters = tripal_get_field_formatters();
+  foreach ($formatters as $formatter) {
+    $info[$formatter] = $formatter::info();
+  }
+  return $info;
 }
 
 /**
- *
+ * Implements hook_field_formatter_info_alter();
  */
-function tripal_create_tripalfields($entity_type, $bundle) {
-
-  // Make sure the rdfs:type term exists.
-  $term = array(
-    'vocab' => array(
-      'name' => 'rdfs',
-      'short_name' => 'rdfs',
-      'description' => 'Resource Description Framework Schema',
-      'url' => 'https://www.w3.org/TR/rdf-schema/'
-    ),
-    'name' => 'type',
-    'accession' => 'type',
-    'definition' => 'The type of resource.',
-    'url' => 'https://www.w3.org/TR/rdf-schema/#ch_type',
-  );
-  $options = array(
-    'label' => 'Content Type',
-    'description' => 'The Tripal content type.',
-    'settings' => array(),
-    'instance_settings' => array(),
-    'default_widget' => 'rdfs_type_widget',
-    'default_formatter' => 'rdfs_type_formatter',
-    'storage' => 'tripal_no_storage',
-  );
-  tripal_add_field_type($term, $options);
-
-//   $field_name = 'content_type';
-//   $info = array();
-//   $info[$field_name] = array(
-//     'field_name' => $field_name,
-//     'type' => 'content_type',
-//     'cardinality' => 1,
-//     'locked' => FALSE,
-//     'storage' => array(
-//       'type' => 'tripal_no_storage'
-//     ),
-//     'settings' => array(
-//       'semantic_web' => 'rdfs:type',
-//     ),
-//   );
-  return $info;
+function tripal_field_formatter_info_alter(&$info) {
+
 }
 
 /**
+ * Implements hook_bundle_create().
  *
- * @param unknown $entity_type
- * @param unknown $bundle
+ * 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.
  */
-function tripal_create_tripalfield_instance($entity_type, $bundle) {
-  $field_name = 'content_type';
-  $info = array();
-  $info[$field_name] = array(
+function tripal_bundle_create($bundle) {
+  $field_type = 'rdfs__type';
+
+  // Add a field to this bundle for the content type.
+  $field_name = $bundle->name . '_' . $field_type;
+  $field = field_create_field(array(
+    'field_name' => $field_name,
+    'type' => $field_type,
+    'cardinality' => 1,
+    'locked' => FALSE,
+    'storage' => array(
+      'type' => 'tripal_no_storage'
+    ),
+    'settings' => array(
+    ),
+  ));
+
+
+  // Add an instance of the field to the bundle.
+  $instance = field_create_instance(array(
     'field_name' => $field_name,
     'entity_type' => 'TripalEntity',
     'bundle' => $bundle->name,
     'label' => 'Resource Type',
-    'description' => '',
+    'description' => 'The resource type',
     'required' => FALSE,
     'settings' => array(
       'auto_attach' => TRUE,
     ),
     'widget' => array(
-      'type' => 'tripal_content_type_widget',
+      'type' => 'rdfs__type_widget',
       'settings' => array(
         'display_label' => 1,
       ),
@@ -145,27 +118,27 @@ function tripal_create_tripalfield_instance($entity_type, $bundle) {
     'display' => array(
       'default' => array(
         'label' => 'inline',
-        'type' => 'tripal_content_type_formatter',
+        'type' => 'rdfs__type_formatter',
         'settings' => array(),
       ),
     ),
-  );
-  return $info;
+  ));
 }
+
 /**
  * Implements hook_field_formatter_view().
  */
 function tripal_field_formatter_view($entity_type, $entity, $field,
     $instance, $langcode, $items, $display) {
 
-//   $element = array();
-//   $field_type = $field['type'];
-//   $is_loaded = tripal_load_include_field_type($field_type);
-//   if ($is_loaded) {
-//     $tfield = new $field_type($field, $instance);
-//     $tfield->formatterView($element, $entity_type, $entity, $langcode, $items, $display);
-//   }
-//   return $element;
+   $element = array();
+   $formatter_class = $display['type'];
+   $is_loaded = tripal_load_include_field_class($formatter_class);
+   if ($is_loaded) {
+     $formatter = new $formatter_class($field, $instance);
+     $formatter->view($element, $entity_type, $entity, $langcode, $items, $display);
+   }
+   return $element;
 }
 
 /**
@@ -274,8 +247,8 @@ function tripal_module_implements_alter(&$implementations, $hook) {
 function tripal_field_settings_form($field, $instance, $has_data) {
 //   $form = array();
 //   $field_type = $field['type'];
-//   //$is_loaded = tripal_load_include_field_type($field_type);
-//   tripal_load_include_field_type($field_type);
+//   //$is_loaded = tripal_load_include_field_class($field_type);
+//   tripal_load_include_field_class($field_type);
 //   if (class_exists($field_type)) {
 //     $tfield = new $field_type($field, $instance);
 //     $form = $tfield->globalSettingsForm($field, $instance, $has_data);
@@ -318,7 +291,7 @@ function tripal_field_instance_settings_form_alter(&$form, $form_state) {
 function tripal_field_instance_settings_form($field, $instance) {
 //   $form = array();
 //   $field_type = $field['type'];
-//   tripal_load_include_field_type($field_type);
+//   tripal_load_include_field_class($field_type);
 //   if (class_exists($field_type)) {
 //     $tfield = new $field_type($field, $instance);
 //     $form = $tfield->instanceSettingsForm();
@@ -332,7 +305,7 @@ function tripal_field_instance_settings_form_validate($form, &$form_state) {
 //   $field = $form['#field'];
 //   $instance = $form['#instance'];
 //   $field_type = $field['type'];
-//   tripal_load_include_field_type($field_type);
+//   tripal_load_include_field_class($field_type);
 //   if (class_exists($field_type)) {
 //     $tfield = new $field_type($field, $instance);
 //     $form = $tfield->instanceSettingsFormValidate($form, $form_state);
@@ -349,7 +322,7 @@ function tripal_field_widget_form_validate($form, &$form_state) {
 //   $delta = $form['#delta'];
 //   $field = $form['#field'];
 //   $field_type = $field['type'];
-//   tripal_load_include_field_type($field_type);
+//   tripal_load_include_field_class($field_type);
 //   if (class_exists($field_type)) {
 //     $instance = $form['#instance'];
 //     $tfield = new $field_type($field, $instance);
@@ -369,7 +342,7 @@ function tripal_field_settings_form_validate($form, &$form_state) {
 //   $field = $form['#field'];
 //   $instance = $form['#instance'];
 //   $field_type = $field['type'];
-//   tripal_load_include_field_type($field_type);
+//   tripal_load_include_field_class($field_type);
 //   if (class_exists($field_type)) {
 //     $tfield = new $field_type($field, $instance);
 //     $form = $tfield->globalSettingsFormValidate($field, $instance, $form, $form_state);
@@ -384,7 +357,7 @@ function tripal_field_formatter_settings_summary($field, $instance, $view_mode)
 
 //   $summary = '';
 //   $field_type = $field['type'];
-//   tripal_load_include_field_type($field_type);
+//   tripal_load_include_field_class($field_type);
 //   if (class_exists($field_type)) {
 //     $tfield = new $field_type($field, $instance);
 //     $form = $tfield->formatterSettingsSummary($view_mode);
@@ -400,7 +373,7 @@ function tripal_formatter_settings_form($field, $instance,
 
 //   $form = array();
 //   $field_type = $field['type'];
-//   tripal_load_include_field_type($field_type);
+//   tripal_load_include_field_class($field_type);
 //   if (class_exists($field_type)) {
 //     $tfield = new $field_type($field, $instance);
 //     $form = $tfield->formatterSettingsForm($view_mode, $form, $form_state);
@@ -414,16 +387,14 @@ function tripal_formatter_settings_form($field, $instance,
  */
 function tripal_field_widget_form(&$form, &$form_state, $field,
     $instance, $langcode, $items, $delta, $element) {
-//   $widget = $element;
-//   $field_type = $field['type'];
-//   tripal_load_include_field_type($field_type);
-//   if (class_exists($field_type)) {
-//     $tfield = new $field_type($field, $instance);
-//     $tfield->widgetForm($widget, $form, $form_state, $langcode, $items, $delta, $element);
-//   }
-//   return $widget;
-
 
+   $widget_class = $instance['widget']['type'];
+   tripal_load_include_field_class($widget_class);
+   if (class_exists($widget_class)) {
+     $widget = new $widget_class($field, $instance);
+     $widget->form($element, $form, $form_state, $langcode, $items, $delta, $element);
+   }
+   return $element;
 }
 
 
@@ -469,7 +440,7 @@ function tripal_field_validate($entity_type, $entity, $field, $instance,
     $langcode, $items, &$errors) {
 
 //   $field_type = $field['type'];
-//   $is_loaded = tripal_load_include_field_type($field_type);
+//   $is_loaded = tripal_load_include_field_class($field_type);
 //   if ($is_loaded) {
 //     $tfield = new $field_type($field, $instance);
 //     $tfield->validate($entity_type, $entity, $langcode,

+ 1 - 66
tripal/tripal.install

@@ -189,9 +189,6 @@ function tripal_schema() {
   $schema['tripal_entity'] = tripal_tripal_entity_schema();
   $schema['tripal_bundle'] = tripal_tripal_bundle_schema();
 
-  // Adds a table for managing fields created by the Tripal modules
-  $schema['tripal_field_types'] = tripal_tripal_field_types_schema();
-
   // Adds a table for additional information related to bundles.
   $schema['tripal_bundle_variables'] = tripal_tripal_bundle_variables_schema();
 
@@ -642,69 +639,7 @@ function tripal_tripal_bundle_schema() {
   return $schema;
 }
 
-/**
- * The table for storing fields created by the Tripal module.
- */
-function tripal_tripal_field_types_schema() {
-  $schema = array(
-    'description' => 'Stores field types created by Tripal. Field types are
-       vocabulary terms.',
-    'fields' => array (
-      'field_type_id' => array (
-        'type' => 'serial',
-        'not null' => TRUE,
-      ),
-      'term' => array(
-        'type' => 'varchar',
-        'not null' => TRUE,
-        'length' => 1024,
-      ),
-      'label' => array(
-        'type' => 'text',
-        'not null' => TRUE,
-      ),
-      'description' => array(
-        'type' => 'text',
-        'not null' => TRUE,
-      ),
-      'settings' => array(
-        'type' => 'text',
-        'not null' => TRUE,
-      ),
-      'instance_settings' => array(
-        'type' => 'text'
-      ),
-      'default_widget' => array(
-        'type' => 'varchar',
-        'length' => 1024,
-        'not null' => TRUE,
-      ),
-      'default_formatter' => array(
-        'type' => 'varchar',
-        'length' => 1024,
-        'not null' => TRUE,
-      ),
-      'storage' => array(
-        'type' => 'text',
-        'not null' => TRUE,
-      ),
-    ),
-    'primary key' => array (
-      0 => 'field_type_id',
-    ),
-    'unique keys' => array (
-      'tripal_field_types_c1' => array (
-        0 => 'term',
-      ),
-    ),
-    'indexes' => array (
-      'tripal_field_types_idx1' => array (
-        0 => 'term',
-      ),
-    ),
-  );
-  return $schema;
-}
+
 /**
  * Additional Tripal Bundle Information.
  *

+ 2 - 0
tripal/tripal.module

@@ -25,6 +25,8 @@ require_once "includes/TripalBundle.inc";
 require_once "includes/TripalBundleController.inc";
 require_once "includes/TripalBundleUIController.inc";
 require_once "includes/TripalField.inc";
+require_once "includes/TripalFieldWidget.inc";
+require_once "includes/TripalFieldFormatter.inc";
 require_once "includes/TripalFieldQuery.inc";
 
 /**

+ 7 - 4
tripal_chado/includes/tripal_chado.entity.inc

@@ -69,6 +69,7 @@ function tripal_chado_entity_postsave($entity, $type) {
  * Implements hook_entity_load().
  */
 function tripal_chado_entity_load($entities, $type) {
+
   if ($type == 'TripalEntity') {
     foreach ($entities as $entity) {
 
@@ -105,10 +106,12 @@ function tripal_chado_entity_load($entities, $type) {
           ->condition('ce.entity_id', $entity->id)
           ->execute()
           ->fetchObject();
-        $schema = chado_get_schema($chado_table);
-        $record = chado_generate_var($chado_table, array($schema['primary key'][0] => $chado_entity->record_id));
-        $entity->chado_record = $record;
-        $entity->chado_record_id = $chado_entity->record_id;
+        if ($chado_entity) {
+          $schema = chado_get_schema($chado_table);
+          $record = chado_generate_var($chado_table, array($schema['primary key'][0] => $chado_entity->record_id));
+          $entity->chado_record = $record;
+          $entity->chado_record_id = $chado_entity->record_id;
+        }
       }
     }
   }

+ 3 - 3
tripal_chado/includes/tripal_chado.setup.inc

@@ -410,19 +410,19 @@ function tripal_chado_prepare_chado() {
     // Create the 'Organism' entity type. This uses the obi:organism term.
     $error = '';
     if (!tripal_create_bundle('OBI', '0100026', 'organism', $error)) {
-      throw new Exception($error);
+      throw new Exception($error['!message']);
     }
 
     // Create the 'Analysis' entity type. This uses the local:analysis term.
     $error = '';
     if (!tripal_create_bundle('local', 'analysis', 'analysis', $error)) {
-      throw new Exception($error);
+      throw new Exception($error['!message']);
     }
 
     // Create the 'Project' entity type. This uses the local:project term.
     $error = '';
     if (!tripal_create_bundle('local', 'project', 'project', $error)) {
-      throw new Exception($error);
+      throw new Exception($error['!message']);
     }
 
     // Initialize the population of the tripal_cvterm_mapping table.