Răsfoiți Sursa

Added Views Integration for tripal_db & tripal_cv

laceysanderson 14 ani în urmă
părinte
comite
27121bc319
26 a modificat fișierele cu 1809 adăugiri și 1 ștergeri
  1. 37 0
      tripal_core/views_handlers/views_handler_field_dbxref_accession_link.inc
  2. 16 0
      tripal_core/views_handlers/views_handler_field_feature_nid.inc
  3. 16 0
      tripal_core/views_handlers/views_handler_field_library_nid.inc
  4. 16 0
      tripal_core/views_handlers/views_handler_field_organism_nid.inc
  5. 80 0
      tripal_core/views_handlers/views_handler_field_readable_date.inc
  6. 81 0
      tripal_core/views_handlers/views_handler_field_stock_dbxref_all.inc
  7. 147 0
      tripal_core/views_handlers/views_handler_field_stock_dbxref_by_type.inc
  8. 16 0
      tripal_core/views_handlers/views_handler_field_stock_nid.inc
  9. 65 0
      tripal_core/views_handlers/views_handler_field_stockprop_all.inc
  10. 117 0
      tripal_core/views_handlers/views_handler_field_stockprop_by_type.inc
  11. 72 0
      tripal_core/views_handlers/views_handler_field_stockrel_all.inc
  12. 135 0
      tripal_core/views_handlers/views_handler_field_stockrel_by_type.inc
  13. 82 0
      tripal_core/views_handlers/views_handler_field_tf_boolean.inc
  14. 11 0
      tripal_core/views_handlers/views_handler_field_type_name.inc
  15. 268 0
      tripal_core/views_handlers/views_handler_filter_stockprop_id.inc
  16. 9 1
      tripal_cv/tripal_cv.module
  17. 56 0
      tripal_cv/tripal_cv.views.inc
  18. 22 0
      tripal_cv/views/README
  19. 81 0
      tripal_cv/views/cv.views.inc
  20. 139 0
      tripal_cv/views/cvterm.views.inc
  21. 11 0
      tripal_db/tripal_db.module
  22. 52 0
      tripal_db/tripal_db.views.inc
  23. 22 0
      tripal_db/views/README
  24. 120 0
      tripal_db/views/db.views.inc
  25. 137 0
      tripal_db/views/dbxref.views.inc
  26. 1 0
      tripal_db/views/handlers/views_handler_field_dbxref_accession_link.inc

+ 37 - 0
tripal_core/views_handlers/views_handler_field_dbxref_accession_link.inc

@@ -0,0 +1,37 @@
+<?php
+
+class views_handler_field_dbxref_accession_link extends views_handler_field {
+ function construct() {
+   parent::construct();
+   $this->additional_fields['accession'] = 'accession';
+   $this->additional_fields['db_id'] = 'db_id';
+
+ }
+
+ function query() { 
+   $this->ensure_my_table();
+   $this->add_additional_fields(); 
+ }
+
+ function render($values) { 
+
+   $accession = $values->{$this->aliases['accession']}; 
+   $db_id = $values->{$this->aliases['db_id']};
+
+   if (!empty($db_id)) {
+     $previous_db = db_set_active('chado');
+     $result = db_fetch_object(db_query('SELECT urlprefix FROM db WHERE db_id=%d', $db_id));
+     db_set_active($previous_db);   
+     $urlprefix = $result->urlprefix;
+
+     if (!empty($urlprefix)) {
+       $accession_link = $urlprefix . $accession;
+       return($accession_link); 
+     } else {
+       return '';
+     }
+   } else {
+     return '';
+   }
+ } 
+} 

+ 16 - 0
tripal_core/views_handlers/views_handler_field_feature_nid.inc

@@ -0,0 +1,16 @@
+<?php
+
+class views_handler_field_feature_nid extends views_handler_field_numeric {
+	function construct() {
+		parent::construct();
+		$this->additional_fields['feature'] = 'feature_id';   
+	}
+
+	function query() { 
+		$this->add_additional_fields(); 
+	}
+
+	function render($values) { 
+		return $values->nid;
+	}
+} 

+ 16 - 0
tripal_core/views_handlers/views_handler_field_library_nid.inc

@@ -0,0 +1,16 @@
+<?php
+
+class views_handler_field_library_nid extends views_handler_field_numeric {
+ function construct() {
+   parent::construct();
+   $this->additional_fields['library_id'] = 'library_id';   
+ }
+
+ function query() { 
+   $this->add_additional_fields(); 
+ }
+
+ function render($values) { 
+	return $values->nid;
+ } 
+} 

+ 16 - 0
tripal_core/views_handlers/views_handler_field_organism_nid.inc

@@ -0,0 +1,16 @@
+<?php
+
+class views_handler_field_organism_nid extends views_handler_field_numeric {
+ function construct() {
+   parent::construct();
+   $this->additional_fields['organism_id'] = 'organism_id';   
+ }
+
+ function query() { 
+   $this->add_additional_fields(); 
+ }
+
+ function render($values) { 
+	return $values->nid;
+ } 
+} 

+ 80 - 0
tripal_core/views_handlers/views_handler_field_readable_date.inc

@@ -0,0 +1,80 @@
+<?php
+// $Id: views_handler_field_date.inc,v 1.3 2009/06/02 18:20:18 merlinofchaos Exp $
+/**
+ * A handler to provide proper displays for dates.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_readable_date extends views_handler_field {
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['date_format'] = array('default' => 'small');
+    $options['custom_date_format'] = array('default' => '');
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $time = time();
+
+    $form['date_format'] = array(
+      '#type' => 'select',
+      '#title' => t('Date format'),
+      '#options' => array(
+        'small' => format_date($time, 'small'),
+        'medium' => format_date($time, 'medium'),
+        'large' => format_date($time, 'large'),
+        'custom' => t('Custom'),
+        'raw time ago' => t('Time ago'),
+        'time ago' => t('Time ago (with "ago" appended)'),
+        'raw time span' => t('Time span (future dates start with - )'),
+        'time span' => t('Time span (with "ago/hence" appended)'),
+      ),
+      '#default_value' => isset($this->options['date_format']) ? $this->options['date_format'] : 'small',
+    );
+    $form['custom_date_format'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Custom date format'),
+      '#description' => t('If "Custom", see <a href="http://us.php.net/manual/en/function.date.php" target="_blank">the PHP docs</a> for date formats. If "Time ago" this is the the number of different units to display, which defaults to two.'),
+      '#default_value' => isset($this->options['custom_date_format']) ? $this->options['custom_date_format'] : '',
+      '#process' => array('views_process_dependency'),
+      '#dependency' => array('edit-options-date-format' => array('custom', 'raw time ago', 'time ago', 'raw time span', 'time span')),
+    );
+  }
+
+  function render($values) {
+    $value = $values->{$this->field_alias};
+
+    // value is currently a CCYY:MM:DD HH:MM:SS format
+    // change it to unix timestamp so rest works
+    $value = strtotime($value);
+
+    $format = $this->options['date_format'];
+    if (in_array($format, array('custom', 'raw time ago', 'time ago', 'raw time span', 'time span'))) {
+      $custom_format = $this->options['custom_date_format'];
+    }
+    
+    if (!$value) {
+      return theme('views_nodate');
+    }
+    else {
+      $time_diff = time() - $value; // will be positive for a datetime in the past (ago), and negative for a datetime in the future (hence)
+      switch ($format) {
+        case 'raw time ago':
+          return format_interval($time_diff, is_numeric($custom_format) ? $custom_format : 2);
+        case 'time ago':
+          return t('%time ago', array('%time' => format_interval($time_diff, is_numeric($custom_format) ? $custom_format : 2)));
+        case 'raw time span':
+          return ($time_diff < 0 ? '-' : '') . format_interval(abs($time_diff), is_numeric($custom_format) ? $custom_format : 2);
+        case 'time span':
+          return t(($time_diff < 0 ? '%time hence' : '%time ago'), array('%time' => format_interval(abs($time_diff), is_numeric($custom_format) ? $custom_format : 2)));
+        case 'custom':
+          return format_date($value, $format, $custom_format);
+        default:
+          return format_date($value, $format);
+      }
+    }
+  }
+}

+ 81 - 0
tripal_core/views_handlers/views_handler_field_stock_dbxref_all.inc

@@ -0,0 +1,81 @@
+<?php
+// $Id: views_handler_field_term_node_tid.inc,v 1.4 2009/07/01 23:07:14 merlinofchaos Exp $
+
+/**
+ * Field handler for terms.
+ */
+class views_handler_field_stock_dbxref_all extends views_handler_field_prerender_list {
+  function init(&$view, $options) {
+    parent::init($view, $options);
+  }
+
+  /**
+   * Add this term to the query
+   */
+  function query() {
+    $this->add_additional_fields();
+  }
+
+	function pre_render($values) {
+		$this->aliases['dbxref'] = 'dbxref';
+		$this->aliases['stock_id'] = 'stock_id';
+		$this->field_alias = $this->aliases['stock_id'];
+		
+		//for each stock in this view page
+		foreach ($values as $result) {
+			if (!empty($result->{$this->aliases['dbxref']})) {
+				
+				// all dbxrefs including the current stock
+				$dbxrefs = $result->{$this->aliases['dbxref']};
+				foreach ($dbxrefs as $dbxref) {			
+					// Add dbxref to the list of items to be rendered
+					$this->items[$dbxref->stock_id][$dbxref->stock_dbxref_id]['stock_id'] = $dbxref->stock_id;
+					$this->items[$dbxref->stock_id][$dbxref->stock_dbxref_id]['stock_dbxref_id'] = $dbxref->stock_dbxref_id;
+					$this->items[$dbxref->stock_id][$dbxref->stock_dbxref_id]['dbxref_id'] = $dbxref->dbxref_id;
+					$this->items[$dbxref->stock_id][$dbxref->stock_dbxref_id]['is_current'] = $dbxref->is_current;
+					$this->items[$dbxref->stock_id][$dbxref->stock_dbxref_id]['db_id'] = $dbxref->db_id;
+					$this->items[$dbxref->stock_id][$dbxref->stock_dbxref_id]['db_name'] = $dbxref->db_name;
+					$this->items[$dbxref->stock_id][$dbxref->stock_dbxref_id]['urlprefix'] = $dbxref->urlprefix;
+					$this->items[$dbxref->stock_id][$dbxref->stock_dbxref_id]['accession'] = $dbxref->accession;
+					$this->items[$dbxref->stock_id][$dbxref->stock_dbxref_id]['version'] = $dbxref->version;
+					$this->items[$dbxref->stock_id][$dbxref->stock_dbxref_id]['description'] = $dbxref->description;
+				}
+			}
+		}
+	}
+
+  function render_item($count, $item) {
+		if (!empty($item['urlprefix'])) {
+			return l($item['accession'],$item['urlprefix'].$item['accession']).' ('.$item['db_name'].')';
+		} else {
+			return $item['accession'].' ('.$item['db_name'].')';
+		}
+  }
+
+  function document_self_tokens(&$tokens) {
+    $tokens['[' . $this->options['id'] . '-stock_id' . ']'] = t('The Stock ID.');
+		$tokens['[' . $this->options['id'] . '-stock_dbxref_id' . ']'] = t('Stock Database Reference ID');
+		$tokens['[' . $this->options['id'] . '-dbxref_id' . ']'] = t('Database Reference ID');
+		$tokens['[' . $this->options['id'] . '-is_current' . ']'] = t('Is Current');
+		$tokens['[' . $this->options['id'] . '-db_id' . ']'] = t('Database ID');
+		$tokens['[' . $this->options['id'] . '-db_name' . ']'] = t('Database Name');
+		$tokens['[' . $this->options['id'] . '-urlprefix' . ']'] = t('URL Prefix');
+		$tokens['[' . $this->options['id'] . '-accession' . ']'] = t('Accession');
+		$tokens['[' . $this->options['id'] . '-version' . ']'] = t('Version');
+		$tokens['[' . $this->options['id'] . '-description' . ']'] = t('Description');
+  }
+
+  function add_self_tokens(&$tokens, $item) {
+    $tokens['[' . $this->options['id'] . '-stock_id' . ']'] = $item['stock_id'];
+		$tokens['[' . $this->options['id'] . '-stock_dbxref_id' . ']'] = $item['stock_dbxref_id'];
+		$tokens['[' . $this->options['id'] . '-dbxref_id' . ']'] =  $item['dbxref_id'];
+		$tokens['[' . $this->options['id'] . '-is_current' . ']'] = $item['is_current'];
+		$tokens['[' . $this->options['id'] . '-db_id' . ']'] = $item['db_id'];
+		$tokens['[' . $this->options['id'] . '-db_name' . ']'] = $item['db_name'];
+		$tokens['[' . $this->options['id'] . '-urlprefix' . ']'] = $item['urlprefix'];
+		$tokens['[' . $this->options['id'] . '-accession' . ']'] = $item['accession'];
+		$tokens['[' . $this->options['id'] . '-version' . ']'] = $item['version'];
+		$tokens['[' . $this->options['id'] . '-description' . ']'] = $item['description'];
+  }
+}
+

+ 147 - 0
tripal_core/views_handlers/views_handler_field_stock_dbxref_by_type.inc

@@ -0,0 +1,147 @@
+<?php
+// $Id: views_handler_field_term_node_tid.inc,v 1.4 2009/07/01 23:07:14 merlinofchaos Exp $
+
+/**
+ * Field handler for terms.
+ */
+class views_handler_field_stock_dbxref_by_type extends views_handler_field_prerender_list {
+  function init(&$view, $options) {
+    parent::init($view, $options);
+
+    // Boolean to determine whether
+    //    TRUE =>  value (property type)      -more than one property type displayed
+    //    FALSE => or just value is rendered  -only 1 porperty type is displayed    
+    $this->display_type = TRUE;
+
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['stockprop_type_ids'] = array('default' => array());
+		$options['display_options'] = array('default' => array('accession','db_name','link'));
+    return $options;
+  }
+
+  /**
+   * Provide "link to term" option.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+		$form['display_options'] = array(
+			'#type' => 'checkboxes',
+			'#title' => t('Display DB Reference Parts'),
+			'#description' => t('Check each part of the database reference you want displayed where the parts '
+				.'of a database relationship are: <Accession> (<Datbase Name>). You can also specify whether the accession '
+				.'should be linked to the record in the database by checking "Link to External Record".'),
+			'#options' => array(
+				'accession' => 'Accession',
+				'db_name' => 'Database Name',
+				'link' => 'Link to External Record',
+			),
+			'#default_value' => $this->options['display_options'],
+		);
+		
+    $db_options = _get_db_options();
+	  $db_options[0] = 'Select a Database';
+	  ksort($db_options);
+    $form['db_ids'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Database'),
+      '#options' => $db_options,
+      '#default_value' => $this->options['db_ids'],
+    );
+  }
+
+  /**
+   * Add this term to the query
+   */
+  function query() {
+    $this->add_additional_fields();
+  }
+
+	function pre_render($values) {
+		$this->aliases['dbxref'] = 'dbxref';
+		$this->aliases['stock_id'] = 'stock_id';
+		$this->field_alias = $this->aliases['stock_id'];
+		
+		//for each stock in this view page
+		foreach ($values as $result) {
+			if (!empty($result->{$this->aliases['dbxref']})) {
+				
+				// all dbxrefs including the current stock
+				$dbxrefs = $result->{$this->aliases['dbxref']};
+				foreach ($dbxrefs as $dbxref) {
+							
+					// perform filtering
+					if (!empty($this->options['db_ids'])) {
+						$dbs2keep = array_filter($this->options['db_ids']);
+						if (!in_array($dbxref->db_id, $dbs2keep)) {
+							continue;
+						}
+					}
+					
+					// Add dbxref to the list of items to be rendered
+					$this->items[$dbxref->stock_id][$dbxref->stock_dbxref_id]['stock_id'] = $dbxref->stock_id;
+					$this->items[$dbxref->stock_id][$dbxref->stock_dbxref_id]['stock_dbxref_id'] = $dbxref->stock_dbxref_id;
+					$this->items[$dbxref->stock_id][$dbxref->stock_dbxref_id]['dbxref_id'] = $dbxref->dbxref_id;
+					$this->items[$dbxref->stock_id][$dbxref->stock_dbxref_id]['is_current'] = $dbxref->is_current;
+					$this->items[$dbxref->stock_id][$dbxref->stock_dbxref_id]['db_id'] = $dbxref->db_id;
+					$this->items[$dbxref->stock_id][$dbxref->stock_dbxref_id]['db_name'] = $dbxref->db_name;
+					$this->items[$dbxref->stock_id][$dbxref->stock_dbxref_id]['urlprefix'] = $dbxref->urlprefix;
+					$this->items[$dbxref->stock_id][$dbxref->stock_dbxref_id]['accession'] = $dbxref->accession;
+					$this->items[$dbxref->stock_id][$dbxref->stock_dbxref_id]['version'] = $dbxref->version;
+					$this->items[$dbxref->stock_id][$dbxref->stock_dbxref_id]['description'] = $dbxref->description;				}
+			}
+		}
+	}
+
+  function render_item($count, $item) {
+		$text = array();
+		if ($this->options['display_options']['accession']) {
+			if ($this->options['display_options']['link']) {
+				if (!empty($item['urlprefix'])) {
+					$text[] = l($item['accession'],$item['urlprefix'].$item['accession']);
+				}
+			} else {
+				$text[] = $item['accession'];
+			}
+		}
+		if ($this->options['display_options']['db_name']) {
+			$text[] = $item['db_name'];
+		}
+		
+		if (sizeof($text) > 1) {
+			return $text[0].' ('.$text[1].')';
+		} else {
+			return $text[0];
+		}
+  }
+
+  function document_self_tokens(&$tokens) {
+    $tokens['[' . $this->options['id'] . '-stock_id' . ']'] = t('The Stock ID.');
+		$tokens['[' . $this->options['id'] . '-stock_dbxref_id' . ']'] = t('Stock Database Reference ID');
+		$tokens['[' . $this->options['id'] . '-dbxref_id' . ']'] = t('Database Reference ID');
+		$tokens['[' . $this->options['id'] . '-is_current' . ']'] = t('Is Current');
+		$tokens['[' . $this->options['id'] . '-db_id' . ']'] = t('Database ID');
+		$tokens['[' . $this->options['id'] . '-db_name' . ']'] = t('Database Name');
+		$tokens['[' . $this->options['id'] . '-urlprefix' . ']'] = t('URL Prefix');
+		$tokens['[' . $this->options['id'] . '-accession' . ']'] = t('Accession');
+		$tokens['[' . $this->options['id'] . '-version' . ']'] = t('Version');
+		$tokens['[' . $this->options['id'] . '-description' . ']'] = t('Description');
+  }
+
+  function add_self_tokens(&$tokens, $item) {
+    $tokens['[' . $this->options['id'] . '-stock_id' . ']'] = $item['stock_id'];
+		$tokens['[' . $this->options['id'] . '-stock_dbxref_id' . ']'] = $item['stock_dbxref_id'];
+		$tokens['[' . $this->options['id'] . '-dbxref_id' . ']'] =  $item['dbxref_id'];
+		$tokens['[' . $this->options['id'] . '-is_current' . ']'] = $item['is_current'];
+		$tokens['[' . $this->options['id'] . '-db_id' . ']'] = $item['db_id'];
+		$tokens['[' . $this->options['id'] . '-db_name' . ']'] = $item['db_name'];
+		$tokens['[' . $this->options['id'] . '-urlprefix' . ']'] = $item['urlprefix'];
+		$tokens['[' . $this->options['id'] . '-accession' . ']'] = $item['accession'];
+		$tokens['[' . $this->options['id'] . '-version' . ']'] = $item['version'];
+		$tokens['[' . $this->options['id'] . '-description' . ']'] = $item['description'];
+  }
+}
+

+ 16 - 0
tripal_core/views_handlers/views_handler_field_stock_nid.inc

@@ -0,0 +1,16 @@
+<?php
+
+class views_handler_field_stock_nid extends views_handler_field_numeric {
+ function construct() {
+   parent::construct();
+   $this->additional_fields['stock'] = 'stock_id';   
+ }
+
+ function query() { 
+   $this->add_additional_fields(); 
+ }
+
+	function render($values) { 
+		return $values->nid;
+	} 
+} 

+ 65 - 0
tripal_core/views_handlers/views_handler_field_stockprop_all.inc

@@ -0,0 +1,65 @@
+<?php
+// $Id: views_handler_field_term_node_tid.inc,v 1.4 2009/07/01 23:07:14 merlinofchaos Exp $
+
+/**
+ * Field handler for terms.
+ */
+class views_handler_field_stockprop_all extends views_handler_field_prerender_list {
+  function init(&$view, $options) {
+    parent::init($view, $options);
+  }
+
+  /**
+   * Add this term to the query
+   */
+  function query() {
+    $this->add_additional_fields();
+  }
+
+	function pre_render($values) {
+		$this->aliases['properties'] = 'properties';
+		$this->aliases['stock_id'] = 'stock_id';
+		$this->field_alias = $this->aliases['stock_id'];
+		
+		//for each stock in this view page
+		foreach ($values as $result) {
+			if (!empty($result->{$this->aliases['properties']})) {
+				
+				// all properties for the current stock
+				$properties = $result->{$this->aliases['properties']};
+				foreach ($properties as $property) {					
+					// Add property to the list of items to be rendered
+					$this->items[$property->stock_id][$property->stockprop_id]['stock_id'] = $property->stock_id;
+					$this->items[$property->stock_id][$property->stockprop_id]['stockprop_id'] = $property->stockprop_id;
+					$this->items[$property->stock_id][$property->stockprop_id]['type_id'] = $property->type_id;
+					$this->items[$property->stock_id][$property->stockprop_id]['type_name'] = check_plain($property->type_name);
+					$this->items[$property->stock_id][$property->stockprop_id]['value'] = check_plain($property->value);
+					$this->items[$property->stock_id][$property->stockprop_id]['rank'] = $property->rank;
+				}
+			}
+		}
+	}
+
+  function render_item($count, $item) {
+		return $item['value'].' ('.$item['type_name'].')';
+  }
+
+  function document_self_tokens(&$tokens) {
+    $tokens['[' . $this->options['id'] . '-stock_id' . ']'] = t('The Stock ID.');
+    $tokens['[' . $this->options['id'] . '-stockprop_id' . ']'] = t('The Property ID.');
+    $tokens['[' . $this->options['id'] . '-type_id' . ']'] = t('The Property Type ID.');
+    $tokens['[' . $this->options['id'] . '-type_name' . ']'] = t('The Property Type.');
+    $tokens['[' . $this->options['id'] . '-value' . ']'] = t('The Value of the Property.');
+    $tokens['[' . $this->options['id'] . '-rank' . ']'] = t('The Rank of the Property.');
+  }
+
+  function add_self_tokens(&$tokens, $item) {
+    $tokens['[' . $this->options['id'] . '-stock_id' . ']'] = $item['stock_id'];
+    $tokens['[' . $this->options['id'] . '-stockprop_id' . ']'] = $item['stockprop_id'];
+    $tokens['[' . $this->options['id'] . '-type_id' . ']'] = $item['type_id'];
+    $tokens['[' . $this->options['id'] . '-type_name' . ']'] = $item['type_name'];
+    $tokens['[' . $this->options['id'] . '-value' . ']'] = $item['value'];
+    $tokens['[' . $this->options['id'] . '-rank' . ']'] = $item['rank'];
+  }
+}
+

+ 117 - 0
tripal_core/views_handlers/views_handler_field_stockprop_by_type.inc

@@ -0,0 +1,117 @@
+<?php
+// $Id: views_handler_field_term_node_tid.inc,v 1.4 2009/07/01 23:07:14 merlinofchaos Exp $
+
+/**
+ * Field handler for terms.
+ */
+class views_handler_field_stockprop_by_type extends views_handler_field_prerender_list {
+  function init(&$view, $options) {
+    parent::init($view, $options);
+
+    // Boolean to determine whether
+    //    TRUE =>  value (property type)      -more than one property type displayed
+    //    FALSE => or just value is rendered  -only 1 porperty type is displayed    
+    $this->display_type = TRUE;
+
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['stockprop_type_ids'] = array('default' => array());
+    return $options;
+  }
+
+  /**
+   * Provide "link to term" option.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $options = _get_cvterm_options( variable_get('chado_stock_prop_types_cv', 'null') );
+    $form['stockprop_type_ids'] = array(
+      '#prefix' => '<div><div id="edit-options-stockprop_type_ids">',
+      '#suffix' => '</div></div>',
+      '#type' => 'checkboxes',
+      '#title' => t('Property Types'),
+      '#options' => $options,
+      '#default_value' => $this->options['stockprop_type_ids'],
+    );
+  }
+
+  /**
+   * Add this term to the query
+   */
+  function query() {
+    $this->add_additional_fields();
+  }
+
+	function pre_render($values) {
+		$this->aliases['properties'] = 'properties';
+		$this->aliases['stock_id'] = 'stock_id';
+		$this->field_alias = $this->aliases['stock_id'];
+
+		// $this->display_type is used to hide (type name) when only one type is displayed in the column
+		if (sizeof(array_filter($this->options['stockprop_type_ids'])) == 1) {
+			$this->display_type = FALSE;        
+		}
+		
+		//for each stock in this view page
+		foreach ($values as $result) {
+			if (!empty($result->{$this->aliases['properties']})) {
+				
+				// all properties for the current stock
+				$properties = $result->{$this->aliases['properties']};
+				foreach ($properties as $property) {
+					// perform filtering
+					if (!empty($this->options['stockprop_type_ids'])) {
+						$types2keep = array_filter($this->options['stockprop_type_ids']);
+						if (!in_array($property->type_id, $types2keep)) {
+							continue;
+						}
+					}
+					
+					// Add property to the list of items to be rendered
+					$this->items[$property->stock_id][$property->stockprop_id]['stock_id'] = $property->stock_id;
+					$this->items[$property->stock_id][$property->stockprop_id]['stockprop_id'] = $property->stockprop_id;
+					$this->items[$property->stock_id][$property->stockprop_id]['type_id'] = $property->type_id;
+					$this->items[$property->stock_id][$property->stockprop_id]['type_name'] = check_plain($property->type_name);
+					$this->items[$property->stock_id][$property->stockprop_id]['value'] = check_plain($property->value);
+					$this->items[$property->stock_id][$property->stockprop_id]['rank'] = $property->rank;
+				}
+			}
+		}
+	}
+
+  function render_item($count, $item) {
+    if ($this->display_type) {
+      return $item['value'].' ('.$item['type_name'].')';
+    } else {
+      if ($item['value']) {
+        return $item['value'];
+      } else {
+        //display checkmark image
+				$image_path = drupal_get_path('module','chado_views').'/images/checkmark.gif';
+        return '<img border="0" src="'.url($image_path).'" alt="checkmark" />';
+      }
+    }
+  }
+
+  function document_self_tokens(&$tokens) {
+    $tokens['[' . $this->options['id'] . '-stock_id' . ']'] = t('The Stock ID.');
+    $tokens['[' . $this->options['id'] . '-stockprop_id' . ']'] = t('The Property ID.');
+    $tokens['[' . $this->options['id'] . '-type_id' . ']'] = t('The Property Type ID.');
+    $tokens['[' . $this->options['id'] . '-type_name' . ']'] = t('The Property Type.');
+    $tokens['[' . $this->options['id'] . '-value' . ']'] = t('The Value of the Property.');
+    $tokens['[' . $this->options['id'] . '-rank' . ']'] = t('The Rank of the Property.');
+  }
+
+  function add_self_tokens(&$tokens, $item) {
+    $tokens['[' . $this->options['id'] . '-stock_id' . ']'] = $item['stock_id'];
+    $tokens['[' . $this->options['id'] . '-stockprop_id' . ']'] = $item['stockprop_id'];
+    $tokens['[' . $this->options['id'] . '-type_id' . ']'] = $item['type_id'];
+    $tokens['[' . $this->options['id'] . '-type_name' . ']'] = $item['type_name'];
+    $tokens['[' . $this->options['id'] . '-value' . ']'] = $item['value'];
+    $tokens['[' . $this->options['id'] . '-rank' . ']'] = $item['rank'];
+  }
+}
+

+ 72 - 0
tripal_core/views_handlers/views_handler_field_stockrel_all.inc

@@ -0,0 +1,72 @@
+<?php
+// $Id: views_handler_field_term_node_tid.inc,v 1.4 2009/07/01 23:07:14 merlinofchaos Exp $
+
+/**
+ * Field handler for terms.
+ */
+class views_handler_field_stockrel_all extends views_handler_field_prerender_list {
+  function init(&$view, $options) {
+    parent::init($view, $options);
+  }
+
+  /**
+   * Add this term to the query
+   */
+  function query() {
+    $this->add_additional_fields();
+  }
+
+	function pre_render($values) {
+		$this->aliases['relationships'] = 'relationships';
+		$this->aliases['stock_id'] = 'stock_id';
+		$this->field_alias = $this->aliases['stock_id'];
+		
+		//for each stock in this view page
+		foreach ($values as $result) {
+			if (!empty($result->{$this->aliases['relationships']})) {
+				
+				// all relationships including the current stock
+				$relationships = $result->{$this->aliases['relationships']};
+				foreach ($relationships as $relationship) {			
+					// Add relationship to the list of items to be rendered
+					$this->items[$relationship->stock_id][$relationship->stock_relationship_id]['stock_id'] = $relationship->stock_id;
+					$this->items[$relationship->stock_id][$relationship->stock_relationship_id]['stock_relationship_id'] = $relationship->stock_relationship_id;
+					$this->items[$relationship->stock_id][$relationship->stock_relationship_id]['subject_id'] = $relationship->subject_id;
+					$this->items[$relationship->stock_id][$relationship->stock_relationship_id]['subject_name'] = $relationship->subject_name;
+					$this->items[$relationship->stock_id][$relationship->stock_relationship_id]['object_id'] = $relationship->object_id;
+					$this->items[$relationship->stock_id][$relationship->stock_relationship_id]['object_name'] = $relationship->object_name;
+					$this->items[$relationship->stock_id][$relationship->stock_relationship_id]['type_id'] = $relationship->type_id;
+					$this->items[$relationship->stock_id][$relationship->stock_relationship_id]['type_name'] = $relationship->type_name;
+				}
+			}
+		}
+	}
+
+  function render_item($count, $item) {
+		return $item['subject_name'].' '.$item['type_name'].' '.$item['object_name'];
+  }
+
+  function document_self_tokens(&$tokens) {
+    $tokens['[' . $this->options['id'] . '-stock_id' . ']'] = t('The Stock ID.');
+		$tokens['[' . $this->options['id'] . '-stock_relationship_id' . ']'] = t('Relationship ID');
+		$tokens['[' . $this->options['id'] . '-subject_id' . ']'] = t('Subject ID');
+		$tokens['[' . $this->options['id'] . '-subject_name' . ']'] = t('Subject Name');
+		$tokens['[' . $this->options['id'] . '-object_id' . ']'] = t('Object ID');
+		$tokens['[' . $this->options['id'] . '-object_name' . ']'] = t('Object Name');
+		$tokens['[' . $this->options['id'] . '-type_id' . ']'] = t('Type ID');
+		$tokens['[' . $this->options['id'] . '-type_name' . ']'] = t('Type Name');
+  }
+
+  function add_self_tokens(&$tokens, $item) {
+    $tokens['[' . $this->options['id'] . '-stock_id' . ']'] = $item['stock_id'];
+		$tokens['[' . $this->options['id'] . '-stock_relationship_id' . ']'] = $item['stock_relationship_id'];
+		$tokens['[' . $this->options['id'] . '-subject_id' . ']'] = $item['subject_id'];
+		$tokens['[' . $this->options['id'] . '-subject_name' . ']'] = $item['subject_name'];
+		$tokens['[' . $this->options['id'] . '-object_id' . ']'] = $item['object_id'];
+		$tokens['[' . $this->options['id'] . '-object_name' . ']'] = $item['object_name'];
+		$tokens['[' . $this->options['id'] . '-type_id' . ']'] = $item['type_id'];
+		$tokens['[' . $this->options['id'] . '-type_name' . ']'] = $item['type_name'];
+
+  }
+}
+

+ 135 - 0
tripal_core/views_handlers/views_handler_field_stockrel_by_type.inc

@@ -0,0 +1,135 @@
+<?php
+// $Id: views_handler_field_term_node_tid.inc,v 1.4 2009/07/01 23:07:14 merlinofchaos Exp $
+
+/**
+ * Field handler for terms.
+ */
+class views_handler_field_stockrel_by_type extends views_handler_field_prerender_list {
+  function init(&$view, $options) {
+    parent::init($view, $options);
+
+    // Boolean to determine whether
+    //    TRUE =>  value (property type)      -more than one property type displayed
+    //    FALSE => or just value is rendered  -only 1 porperty type is displayed    
+    $this->display_type = TRUE;
+
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['stockprop_type_ids'] = array('default' => array());
+		$options['display_options'] = array('default' => array('subject','type','object'));
+    return $options;
+  }
+
+  /**
+   * Provide "link to term" option.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+		$form['display_options'] = array(
+			'#type' => 'checkboxes',
+			'#title' => t('Display Relationship Parts'),
+			'#description' => t('Check each part of the relationship you want displayed where the part '
+				.'of a relationship are: <Subject> <Relationship Type> <Object>. '
+				.'For example, with the relationship Sarah is the maternal parent of Fred '
+				.'if you checked only Object then "Fred" would be displayed.'),
+			'#options' => array(
+				'subject' => 'Subject',
+				'type' => 'Relationship Type',
+				'object' => 'Object',
+			),
+			'#default_value' => $this->options['display_options'],
+		);
+		
+    $options = _get_cvterm_options( variable_get('chado_stock_relationship_cv', 'null') );
+    $form['stockrel_type_ids'] = array(
+      '#prefix' => '<div><div id="edit-options-stockrel_type_ids">',
+      '#suffix' => '</div></div>',
+      '#type' => 'checkboxes',
+      '#title' => t('Relationship Types'),
+      '#options' => $options,
+      '#default_value' => $this->options['stockrel_type_ids'],
+    );
+  }
+
+  /**
+   * Add this term to the query
+   */
+  function query() {
+    $this->add_additional_fields();
+  }
+
+	function pre_render($values) {
+		$this->aliases['relationships'] = 'relationships';
+		$this->aliases['stock_id'] = 'stock_id';
+		$this->field_alias = $this->aliases['stock_id'];
+		
+		//for each stock in this view page
+		foreach ($values as $result) {
+			if (!empty($result->{$this->aliases['relationships']})) {
+					
+				// all relationships including the current stock
+				$relationships = $result->{$this->aliases['relationships']};
+				foreach ($relationships as $relationship) {			
+					// perform filtering
+					if (!empty($this->options['stockrel_type_ids'])) {
+						$relationships2keep = array_filter($this->options['stockrel_type_ids']);
+						if (!in_array($relationship->type_id, $relationships2keep)) {
+							continue;
+						}
+					}
+					
+					// Add relationship to the list of items to be rendered
+					$this->items[$relationship->stock_id][$relationship->stock_relationship_id]['stock_id'] = $relationship->stock_id;
+					$this->items[$relationship->stock_id][$relationship->stock_relationship_id]['stock_relationship_id'] = $relationship->stock_relationship_id;
+					$this->items[$relationship->stock_id][$relationship->stock_relationship_id]['subject_id'] = $relationship->subject_id;
+					$this->items[$relationship->stock_id][$relationship->stock_relationship_id]['subject_name'] = $relationship->subject_name;
+					$this->items[$relationship->stock_id][$relationship->stock_relationship_id]['object_id'] = $relationship->object_id;
+					$this->items[$relationship->stock_id][$relationship->stock_relationship_id]['object_name'] = $relationship->object_name;
+					$this->items[$relationship->stock_id][$relationship->stock_relationship_id]['type_id'] = $relationship->type_id;
+					$this->items[$relationship->stock_id][$relationship->stock_relationship_id]['type_name'] = $relationship->type_name;
+				}
+			}
+		}
+	}
+
+  function render_item($count, $item) {
+	  $text = array();
+		if ($this->options['display_options']['subject']) {
+			$text[] = $item['subject_name'];
+		}
+		if ($this->options['display_options']['type']) {
+			$text[] = $item['type_name'];
+		}
+		if ($this->options['display_options']['object']) {
+			$text[] = $item['object_name'];
+		}
+		return implode(' ', $text);
+  }
+
+  function document_self_tokens(&$tokens) {
+    $tokens['[' . $this->options['id'] . '-stock_id' . ']'] = t('The Stock ID.');
+		$tokens['[' . $this->options['id'] . '-stock_relationship_id' . ']'] = t('Relationship ID');
+		$tokens['[' . $this->options['id'] . '-subject_id' . ']'] = t('Subject ID');
+		$tokens['[' . $this->options['id'] . '-subject_name' . ']'] = t('Subject Name');
+		$tokens['[' . $this->options['id'] . '-object_id' . ']'] = t('Object ID');
+		$tokens['[' . $this->options['id'] . '-object_name' . ']'] = t('Object Name');
+		$tokens['[' . $this->options['id'] . '-type_id' . ']'] = t('Type ID');
+		$tokens['[' . $this->options['id'] . '-type_name' . ']'] = t('Type Name');
+  }
+
+  function add_self_tokens(&$tokens, $item) {
+    $tokens['[' . $this->options['id'] . '-stock_id' . ']'] = $item['stock_id'];
+		$tokens['[' . $this->options['id'] . '-stock_relationship_id' . ']'] = $item['stock_relationship_id'];
+		$tokens['[' . $this->options['id'] . '-subject_id' . ']'] = $item['subject_id'];
+		$tokens['[' . $this->options['id'] . '-subject_name' . ']'] = $item['subject_name'];
+		$tokens['[' . $this->options['id'] . '-object_id' . ']'] = $item['object_id'];
+		$tokens['[' . $this->options['id'] . '-object_name' . ']'] = $item['object_name'];
+		$tokens['[' . $this->options['id'] . '-type_id' . ']'] = $item['type_id'];
+		$tokens['[' . $this->options['id'] . '-type_name' . ']'] = $item['type_name'];
+
+  }
+}
+

+ 82 - 0
tripal_core/views_handlers/views_handler_field_tf_boolean.inc

@@ -0,0 +1,82 @@
+<?php
+// $Id: views_handler_field_boolean.inc,v 1.3.2.1 2010/03/25 01:14:22 merlinofchaos Exp $
+
+/**
+ * A handler to provide proper displays for booleans.
+ *
+ * Allows for display of true/false, yes/no, on/off.
+ *
+ * Definition terms:
+ *   - output formats: An array where the first entry is displayed on boolean false
+ *      and the second is displayed on boolean true. An example for sticky is:
+ *      @code
+ *      'output formats' => array(
+ *        'sticky' => array('', t('Sticky')),
+ *      ),
+ *      @endcode
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_tf_boolean extends views_handler_field {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['type'] = array('default' => 'yes-no');
+    $options['not'] = array('definition bool' => 'reverse');
+
+    return $options;
+  }
+
+  function init(&$view, $options) {
+    parent::init($view, $options);
+
+    $default_formats = array(
+      'yes-no' => array(t('Yes'), t('No')),
+      'true-false' => array(t('True'), t('False')),
+      'on-off' => array(t('On'), t('Off')),
+    );
+    $output_formats = isset($this->definition['output formats']) ? $this->definition['output formats'] : array();
+    $this->formats = array_merge($default_formats, $output_formats);
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    foreach ($this->formats as $key => $item) {
+      $options[$key] = implode('/', $item);
+    }
+
+    $form['type'] = array(
+      '#type' => 'select',
+      '#title' => t('Output format'),
+      '#options' => $options,
+      '#default_value' => $this->options['type'],
+    );
+    $form['not'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Reverse'),
+      '#description' => t('If checked, true will be displayed as false.'),
+      '#default_value' => $this->options['not'],
+    );
+  }
+
+  function render($values) {
+    $value = $values->{$this->field_alias};
+    if (!empty($this->options['not'])) {
+      $value = !$value;
+    }
+
+    if (isset($this->formats[$this->options['type']])) {
+      if (preg_match('/^t$/', $value)) {
+        return $this->formats[$this->options['type']][0];
+      } else {
+        return $this->formats[$this->options['type']][1];
+      }
+    }
+    else {
+      if (preg_match('/^t$/', $value)) {
+        return $this->formats['yes-no'][0];
+      } else {
+        return $this->formats['yes-no'][1];
+      } 
+    }
+  }
+}

+ 11 - 0
tripal_core/views_handlers/views_handler_field_type_name.inc

@@ -0,0 +1,11 @@
+<?php
+
+class views_handler_field_type_name extends views_handler_field {
+ function construct() {
+   parent::construct();
+ }
+
+ function render($values) { 
+   return $values->property_type_name;
+ } 
+} 

+ 268 - 0
tripal_core/views_handlers/views_handler_filter_stockprop_id.inc

@@ -0,0 +1,268 @@
+<?php
+
+/**
+ * Filter by stockprop type id
+ */
+class views_handler_filter_stockprop_id extends views_handler_filter {
+
+  function init(&$view, $options) {
+    parent::init($view, $options);
+    $this->type = $this->options['type'];
+  }
+
+  function options_form(&$form, &$form_state) {
+    if ($this->can_expose()) {
+      $this->show_expose_button($form, $form_state);
+    }
+
+    $form['op_val_start'] = array('#value' => '<div class="clear-block">');
+
+    $this->types_form($form, $form_state);
+
+    $this->show_operator_form($form, $form_state);
+    $form['operator']['#prefix'] = '<div class="views-right-70">';
+    $this->show_value_form($form, $form_state);
+    $form['op_val_end'] = array('#value' => '</div>');
+
+    if ($this->can_expose()) {
+      $this->show_expose_form($form, $form_state);
+    }
+
+  }
+
+  function options_validate(&$form, &$form_state) {
+    parent::options_validate(&$form, &$form_state);
+
+    if (preg_match('/NULL/',$form_state['values']['options']['operator'])) {
+      $value = $form_state['values']['options']['value'];
+      if (!empty($value)) {
+        drupal_set_message('The Value ('.$value.') will be IGNORED when the Operator is set to "Is Present" or Is Absent".', 'warning');
+      }
+    } else {
+      $value = $form_state['values']['options']['value'];
+      if (empty($value)) {
+        form_error($form['value'], t('Value required. The value will be used in conjunction with the operator. For example, if the '
+				   .'operator="Is equal to" and the value="2010" then only properties with a value of 2010 and the type specified will be displayed.'));
+      }
+    }
+
+    if (empty($form_state['values']['options']['type'])) {
+      drupal_set_message('No Property Type was choosen. As such, any property type whose value '
+      			     .$form_state['values']['options']['operator'].' '.$form_state['values']['options']['value'].' will be displayed', 'warning');
+    }
+  }
+
+  /**
+   * Add this filter to the query.
+   */
+//  function query() {
+//    if (!empty($this->value) || preg_match('/NULL/', $this->operator)) {
+//      if (preg_match('/stockprop/', $this->query->table_queue['stockprop']['table'])) {
+//        //already one stockprop join thus create another one with a different alias
+//        // to ensure no collisions
+//        $original_join = $this->query->table_queue['stockprop'];
+//
+//        $this->query->table_queue['stockprop_'.$this->type] = $original_join;
+//        $this->query->table_queue['stockprop_'.$this->type]['alias'] = 'stockprop_'.$this->type;
+//        $this->query->tables['stockprop']['count']++;
+//        $this->table_alias = 'stockprop_'.$this->type;
+//      } else {
+//        // Add stockprop join to query if it's not already there
+//        $this->ensure_my_table();
+//      }
+//
+//      if (!empty($this->type)) {
+//        $this->query->add_where($this->options['group'], $this->table_alias. '.type_id = '.$this->type);
+//      }
+//
+//      if (preg_match('/NULL/', $this->operator)) {
+//        $this->query->add_where($this->options['group'], $this->table_alias. '.value ' . $this->operator);
+//      } else {
+//        if (!empty($this->value)) {
+//          $this->query->add_where($this->options['group'], $this->table_alias. '.value ' . $this->operator . " '%s'", $this->value);
+//        }
+//      }
+//    }
+//  }
+
+  function types_form(&$form, &$form_state) {
+    $previous_db = db_set_active('chado');
+    $result = db_query("SELECT cvt.cvterm_id as type_id, cvt.name FROM cvterm cvt WHERE cvt.cvterm_id IN (SELECT type_id FROM stockprop)");
+    db_set_active($previous_db);
+
+    $types = array();
+    while ($r = db_fetch_object($result)) { $types[$r->type_id] = $r->name; }
+
+    $form['type'] = array(
+      '#type' => count($options) < 10 ? 'radios' : 'select',
+      '#title' => t('Property Types'),
+      '#options' => $types,
+      '#default_value' => $this->type,
+      '#prefix' => '<div class="views-left-30">',
+      '#suffix' => '</div>',
+    );
+
+  }
+
+  function value_form(&$form, &$form_state) {
+    parent::value_form(&$form, &$form_state);
+
+    $form['value'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Value'),
+      '#default_value' => $this->value,
+    );
+  }
+
+  function operator_options() {
+    return array(
+      '=' => t('Is equal to'),
+      '!=' => t('Is not equal to'),
+      '~' => t('Contains'),
+      '!~' => t('Does not contain'),
+      'IS NOT NULL' => t('Is Present (Not Empty)'),
+      'IS NULL' => t('Is Absent (Empty)'),
+    );
+  }
+
+ /**
+  * Render our chunk of the exposed filter form when selecting
+  */
+  function exposed_form(&$form, &$form_state) {
+    if (empty($this->options['exposed'])) {
+      return;
+    }
+
+    if (!empty($this->options['expose']['use_type']) && !empty($this->options['expose']['type'])) {
+      $type = $this->options['expose']['type'];
+      $form[$type] = array(
+        '#type' => 'select',
+        '#title' => t('Property Types'),
+        '#options' => $this->type_options(),
+        '#default_value' => $this->type,  
+      );
+
+      if (isset($form[$type]['#title'])) {
+        unset($form[$type]['#title']);
+      }
+    }
+
+    if (!empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator'])) {
+      $operator = $this->options['expose']['operator'];
+      $this->operator_form($form, $form_state);
+      $form[$operator] = $form['operator'];
+
+      if (isset($form[$operator]['#title'])) {
+        unset($form[$operator]['#title']);
+      }
+
+      $this->exposed_translate($form[$operator], 'operator');
+
+      unset($form['operator']);
+    }
+
+    if (!empty($this->options['expose']['identifier'])) {
+      $value = $this->options['expose']['identifier'];
+      $this->value_form($form, $form_state);
+      $form[$value] = $form['value'];
+
+      if (isset($form[$value]['#title']) && !empty($form[$value]['#type']) && $form[$value]['#type'] != 'checkbox') {
+        unset($form[$value]['#title']);
+      }
+
+      $this->exposed_translate($form[$value], 'value');
+
+      if (!empty($form['#type']) && ($form['#type'] == 'checkboxes' || ($form['#type'] == 'select' && !empty($form['#multiple'])))) {
+        unset($form[$value]['#default_value']);
+      }
+
+      if (!empty($form['#type']) && $form['#type'] == 'select' && empty($form['#multiple'])) {
+        $form[$value]['#default_value'] = 'All';
+      }
+
+      if ($value != 'value') {
+        unset($form['value']);
+      }
+    }
+  }
+
+  function expose_form_left(&$form, &$form_state) {
+    $form['expose']['label'] = array(
+      '#type' => 'textfield',
+      '#default_value' => $this->options['expose']['label'],
+      '#title' => t('Label'),
+      '#size' => 40,
+    );
+
+    $form['expose']['identifier'] = array(
+      '#type' => 'textfield',
+      '#default_value' => $this->options['expose']['identifier'],
+      '#title' => t('Filter identifier'),
+      '#size' => 40,
+      '#description' => t('This will appear in the URL after the ? to identify this filter. Cannot be blank.'),
+    );
+  }
+
+  function expose_form_right(&$form, &$form_state) {
+    if (!empty($form['type']['#type'])) {
+      $form['expose']['use_type'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Unlock Property Type'),
+        '#description' => t('When checked, the property type will be exposed to the user'),
+        '#default_value' => !empty($this->options['expose']['use_type']),
+      );
+      $form['expose']['type'] = array(
+        '#type' => 'textfield',
+        '#default_value' => $this->options['expose']['type'],
+        '#title' => t('Property Type identifier'),
+        '#size' => 40,
+        '#description' => t('This will appear in the URL after the ? to identify this property type.'),
+        '#process' => array('views_process_dependency'),
+        '#dependency' => array(
+          'edit-options-expose-use-type' => array(1)
+        ),
+      );
+    }
+    else {
+      $form['expose']['type'] = array(
+        '#type' => 'value',
+        '#value' => '',
+      );
+    }
+
+    $form['expose']['identifier'] = array(
+      '#type' => 'textfield',
+      '#default_value' => $this->options['expose']['identifier'],
+      '#title' => t('Filter identifier'),
+      '#size' => 40,
+      '#description' => t('This will appear in the URL after the ? to identify this filter. Cannot be blank.'),
+    );
+
+    if (!empty($form['operator']['#type'])) {
+      $form['expose']['use_operator'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Unlock operator'),
+        '#description' => t('When checked, the operator will be exposed to the user'),
+        '#default_value' => !empty($this->options['expose']['use_operator']),
+      );
+      $form['expose']['operator'] = array(
+        '#type' => 'textfield',
+        '#default_value' => $this->options['expose']['operator'],
+        '#title' => t('Operator identifier'),
+        '#size' => 40,
+        '#description' => t('This will appear in the URL after the ? to identify this operator.'),
+        '#process' => array('views_process_dependency'),
+        '#dependency' => array(
+          'edit-options-expose-use-operator' => array(1)
+        ),
+      );
+    }
+    else {
+      $form['expose']['operator'] = array(
+        '#type' => 'value',
+        '#value' => '',
+      );
+    }
+  }
+
+}

+ 9 - 1
tripal_cv/tripal_cv.module

@@ -168,7 +168,15 @@ function tripal_cv_perm(){
    );
 }
 
-
+/*************************************************************************
+ * Implements hook_views_api()
+ * Purpose: Essentially this hook tells drupal that there is views support for
+ *  for this module which then includes tripal_cv.views.inc where all the
+ *  views integration code is
+ */
+function tripal_cv_views_api() {
+	return array('api' => 2.0);
+}
 
 /*************************************************************************
 *

+ 56 - 0
tripal_cv/tripal_cv.views.inc

@@ -0,0 +1,56 @@
+<?php
+
+/**
+ *  @file
+ *  This file contains the basic functions for views integration of
+ *  chado/tripal db tables. Supplementary functions can be found in
+ *  ./views/
+ *
+ *  Documentation on views integration can be found at 
+ *  http://views2.logrus.com/doc/html/index.html.
+ */
+ 
+/*************************************************************************
+ * Implements hook_views_data()
+ * Purpose: Describe chado/tripal tables & fields to views
+ * @return: a data array which follows the structure outlined in the
+ *   views2 documentation for this hook. Essentially, it's an array of table
+ *   definitions keyed by chado/tripal table name. Each table definition 
+ *   includes basic details about the table, fields in that table and
+ *   relationships between that table and others (joins)
+ */
+require_once('views/cvterm.views.inc');
+require_once('views/cv.views.inc');
+function tripal_cv_views_data() {
+  $data = array();
+  
+  //Function is contained in includes/cvterm.views.inc
+  //Returns the data array for the chado cvterm table
+  $data = array_merge($data, retrieve_cvterm_views_data());
+  
+  //Function is contained in includes/cv.views.inc
+  //Returns the data array for the chado cv table
+  $data = array_merge($data, retrieve_cv_views_data());
+  
+  return $data;
+}
+ 
+/*************************************************************************
+ * Implements hook_views_handlers()
+ * Purpose: Register all custom handlers with views
+ *   where a handler describes either "the type of field", 
+ *   "how a field should be filtered", "how a field should be sorted"
+ * @return: An array of handler definitions
+ */
+function tripal_cv_views_handlers() {
+ return array(
+   'info' => array(
+     'path' => drupal_get_path('module', 'tripal_cv') . '/views/handlers',
+   ),
+   'handlers' => array(
+     'views_handler_field_tf_boolean' => array(
+       'parent' => 'views_handler_field',
+     ),
+   ),
+ );
+}

+ 22 - 0
tripal_cv/views/README

@@ -0,0 +1,22 @@
+This folder contains all supplementary code needed for views integration
+of the chado cvterm and related tables.
+
+File Descriptions:
+========================================================================
+<chado table name>.views.inc:
+	contains a single function retrieve_<chado table name>_views_data()
+	which describes that table to views. This function is called by
+	<tripal module>_views_data() in ../<tripal module>.views.inc.
+	For more information on the form of this data array look up the
+	views2 documentation for hook_views_data() 
+	-http://views2.logrus.com/doc/html/index.html
+	
+handlers/
+	A folder which contains symbolic links to tripal_core/views_handlers/ files.
+	Each file contained within this folder defines a views handler. Only custom
+	handlers are included in this folder and each must be described in 
+	hook_views_handlers() in ../<tripal module>.views.inc.
+	A views handler does one of the following:
+		1) describe the type of a field and how it should be displayed
+		2) describe a method to sort this field
+		3) describe a method to filter this field

+ 81 - 0
tripal_cv/views/cv.views.inc

@@ -0,0 +1,81 @@
+<?php
+
+/**
+ * Prupose: this function returns a portion of the data array 
+ *   which describes the cv table, it's fields and any joins between it and other tables
+ * @see tripal_cv_views_data() --in tripal_cv.views.inc
+ *
+ * TABLE: cv
+ * @code
+ *   create table cv (
+ *       cv_id serial not null,
+ *       primary key (cv_id),
+ *       name varchar(255) not null,
+ *       definition text,
+ *       constraint cv_c1 unique (name)
+ *   );
+ * @endcode
+ */
+function retrieve_cv_views_data() {
+  $data = array();
+
+  // Basic table definition
+  $data['cv']['table'] = array(
+    'field' => 'cv_id',
+    'title' => 'Chado CV (Controlled Vocabulary)',
+    'group' => 'Chado CV',
+    'help' => 'Controlled vocabularies existing in the Chado Database',
+    'database' => 'chado'
+  );
+
+  // Define relationships between this table and others
+  $data['cv']['table']['join'] = array(
+     'cvterm' => array(
+       'left_field' => 'cv_id',
+       'field' => 'cv_id',
+     ),
+  );
+
+  // Table Field Definitions----------------------
+  // Field: cv_id (primary key)
+  //   mentioned as index above but not displayable in a view  
+  
+  //Field: name (varchar -255)
+  $data['cv']['name'] = array(
+    'title' => 'Vocabulary Name',
+    'field' => array(
+       'handler' => 'views_handler_field',
+       'click sortable' => TRUE,
+     ),
+     'sort' => array(
+       'handler' => 'views_handler_sort',
+     ),
+     'filter' => array(
+       'handler' => 'views_handler_filter_string',
+     ),
+     'argument' => array(
+       'handler' => 'views_handler_argument_string',
+     ),
+  );
+
+  //Field: definition (text)
+  $data['cv']['definition'] = array(
+    'title' => 'Vocabulary Definition',
+    'field' => array(
+       'handler' => 'views_handler_field',
+       'click sortable' => TRUE,
+     ),
+     'sort' => array(
+       'handler' => 'views_handler_sort',
+     ),
+     'filter' => array(
+       'handler' => 'views_handler_filter_string',
+     ),
+     'argument' => array(
+       'handler' => 'views_handler_argument_string',
+     ),
+  );
+
+  return $data;
+
+}

+ 139 - 0
tripal_cv/views/cvterm.views.inc

@@ -0,0 +1,139 @@
+<?php
+
+/**
+ * Purpose: this function returns the portion of the data array 
+ *   which describes the cv table, it's fields and any joins between it and other tables
+ * @see tripal_cv_views_data() --in tripal_cv.views.inc
+ *
+ * BASE TABLE: cvterm
+ * @code
+ *   create table cvterm (
+ *       cvterm_id serial not null,
+ *       primary key (cvterm_id),
+ *       cv_id int not null,
+ *       foreign key (cv_id) references cv (cv_id) on delete cascade INITIALLY DEFERRED,
+ *       name varchar(1024) not null,
+ *       definition text,
+ *       dbxref_id int not null,
+ *       foreign key (dbxref_id) references dbxref (dbxref_id) on delete set null INITIALLY DEFERRED,
+ *       is_obsolete int not null default 0,
+ *       is_relationshiptype int not null default 0,
+ *       constraint cvterm_c1 unique (name,cv_id,is_obsolete),
+ *       constraint cvterm_c2 unique (dbxref_id)
+ *   );
+ * @endcode
+ */
+function retrieve_cvterm_views_data() {
+
+  // Basic table definition
+  $data['cvterm']['table']['group'] = 'Chado CV Terms';
+  $data['cvterm']['table']['base'] = array(
+    'field' => 'cvterm_id',
+    'title' => 'Chado CV Terms (Controlled Vocabulary)',
+    'help' => 'Controlled Vocabularies (CVs) are the main way Chado controls content.',
+    'database' => 'chado'
+  );
+
+  // Define relationships between this table and others
+   $data['cvterm']['table']['join'] = array(
+     'feature' => array(
+       'left_field' => 'type_id',
+       'field' => 'cvterm_id',
+     ),
+     'library' => array(
+       'left_field' => 'type_id',
+       'field' => 'cvterm_id',
+     ),
+     'stock' => array(
+       'left_field' => 'type_id',
+       'field' => 'cvterm_id',
+     ),
+   );
+
+ // Table Field Definitions----------------------
+ // Field: cvterm_id (primary key)
+ //   mentioned as index above but not displayable in a view
+ 
+ //Field: cv_id (foreign key: cv)
+ //  join between cv table and this one in cv.views.inc
+ 
+ // Field: Name (varchar 1024)
+  $data['cvterm']['name'] = array(
+     'title' => 'Name',
+     'help' => 'The term name',
+     'field' => array(
+     'handler' => 'views_handler_field',
+       'click sortable' => TRUE,
+     ),
+     'sort' => array(
+       'handler' => 'views_handler_sort',
+     ),
+     'filter' => array(
+       'handler' => 'views_handler_filter_string',
+     ),
+     'argument' => array(
+       'handler' => 'views_handler_argument_string',
+     ),
+   );
+
+   // Field: Definition (text)
+   $data['cvterm']['definition'] = array(
+     'title' => 'Definition',
+     'help' => 'A definition of this term',
+     'field' => array(
+       'handler' => 'views_handler_field',
+       'click sortable' => TRUE,
+     ),
+     'sort' => array(
+       'handler' => 'views_handler_sort',
+     ),
+     'filter' => array(
+       'handler' => 'views_handler_filter_string',
+     ),
+     'argument' => array(
+       'handler' => 'views_handler_argument_string',
+     ),
+   );
+
+   // Field: dbxref_id (foreign key: dbxref)
+   //  join between dbxref table and this one in tripal_db/views/dbxref.views.inc
+   
+   // Field: is_obsolete (integer: 1/0)
+   $data['cvterm']['is_obsolete'] = array(
+     'title' => 'Is Obsolete',
+     'help' => 'Whether this term is obsolete or not.',
+     'field' => array(
+       'handler' => 'views_handler_field_boolean',
+       'click sortable' => TRUE,
+     ),
+     'filter' => array(
+       'handler' => 'views_handler_filter_boolean_operator',
+       'label' => t('Is Obsolete?'),
+       'type' => 'yes-no',
+     ),
+     'sort' => array(
+       'handler' => 'views_handler_sort',
+     ),
+   );
+
+   // Field: is_relationshiptype (integer: 1/0)
+   $data['cvterm']['is_relationshiptype'] = array(
+     'title' => 'Is Relationship',
+     'help' => 'Whether this term describes a relationship or not.',
+     'field' => array(
+       'handler' => 'views_handler_field_boolean',
+       'click sortable' => TRUE,
+     ),
+     'filter' => array(
+       'handler' => 'views_handler_filter_boolean_operator',
+       'label' => t('Published'),
+       'type' => 'yes-no',
+     ),
+     'sort' => array(
+       'handler' => 'views_handler_sort',
+     ),
+    );
+  
+  return $data;
+
+}

+ 11 - 0
tripal_db/tripal_db.module

@@ -55,6 +55,17 @@ function tripal_db_perm(){
       'edit chado_db content',
    );
 }
+
+/*************************************************************************
+ * Implements hook_views_api()
+ * Purpose: Essentially this hook tells drupal that there is views support for
+ *  for this module which then includes tripal_db.views.inc where all the
+ *  views integration code is
+ */
+function tripal_db_views_api() {
+	return array('api' => 2.0);
+}
+
 /*************************************************************************
 *
 */

+ 52 - 0
tripal_db/tripal_db.views.inc

@@ -0,0 +1,52 @@
+<?php
+
+/**
+ *  @file
+ *  This file contains the basic functions for views integration of
+ *  chado/tripal db tables. Supplementary functions can be found in
+ *  ./views/
+ *
+ *  Documentation on views integration can be found at 
+ *  http://views2.logrus.com/doc/html/index.html.
+ */
+ 
+/*************************************************************************
+ * Implements hook_views_data()
+ * Purpose: Describe chado/tripal tables & fields to views
+ * @return: a data array which follows the structure outlined in the
+ *   views2 documentation for this hook. Essentially, it's an array of table
+ *   definitions keyed by chado/tripal table name. Each table definition 
+ *   includes basic details about the table, fields in that table and
+ *   relationships between that table and others (joins)
+ */
+require_once('views/dbxref.views.inc');
+require_once('views/db.views.inc');
+function tripal_db_views_data()  {
+
+   $data = array();
+   $data = array_merge($data, retrieve_dbxref_views_data());
+   $data = array_merge($data, retrieve_db_views_data());
+   return $data;
+
+}
+
+/*************************************************************************
+ * Implements hook_views_handlers()
+ * Purpose: Register all custom handlers with views
+ *   where a handler describes either "the type of field", 
+ *   "how a field should be filtered", "how a field should be sorted"
+ * @return: An array of handler definitions
+ */
+function tripal_db_views_handlers() {
+ return array(
+   'info' => array(
+     'path' => drupal_get_path('module', 'tripal_db') . '/views/handlers',
+   ),
+   'handlers' => array(
+     'views_handler_field_dbxref_accession_link' => array(
+       'parent' => 'views_handler_field',
+     ),
+   ),
+ );
+}
+

+ 22 - 0
tripal_db/views/README

@@ -0,0 +1,22 @@
+This folder contains all supplementary code needed for views integration
+of the chado dbxref and related tables.
+
+File Descriptions:
+========================================================================
+<chado table name>.views.inc:
+	contains a single function retrieve_<chado table name>_views_data()
+	which describes that table to views. This function is called by
+	<tripal module>_views_data() in ../<tripal module>.views.inc.
+	For more information on the form of this data array look up the
+	views2 documentation for hook_views_data() 
+	-http://views2.logrus.com/doc/html/index.html
+	
+handlers/
+	A folder which contains symbolic links to tripal_core/views_handlers/ files.
+	Each file contained within this folder defines a views handler. Only custom
+	handlers are included in this folder and each must be described in 
+	hook_views_handlers() in ../<tripal module>.views.inc.
+	A views handler does one of the following:
+		1) describe the type of a field and how it should be displayed
+		2) describe a method to sort this field
+		3) describe a method to filter this field

+ 120 - 0
tripal_db/views/db.views.inc

@@ -0,0 +1,120 @@
+<?php
+
+  /**
+ * Purpose: this function returns the portion of the data array 
+ *   which describes the cv table, it's fields and any joins between it and other tables
+ * @see tripal_cv_views_data() --in tripal_cv.views.inc
+ *
+ *  TABLE: db
+ * @code
+ * create table db (
+ *    db_id serial not null,
+ *    primary key (db_id),
+ *    name varchar(255) not null,
+ *    description varchar(255) null,
+ *    urlprefix varchar(255) null,
+ *    url varchar(255) null,
+ *    constraint db_c1 unique (name)
+ * );
+ * @endcode
+ */
+function retrieve_db_views_data() {
+  
+  // Basic table definition
+  $data['db']['table'] = array(
+    'field' => 'db_id',
+    'group' => 'Chado Database',
+    'title' => 'Chado Database',
+    'help' => 'Database Records existing in the Chado Database',
+    'database' => 'chado'
+  );
+  
+  // Define relationships between this table and others
+  $data['db']['table']['join'] = array(
+    'dbxref' => array(
+      'left_field' => 'db_id',
+      'field' => 'db_id',
+    ),
+  );
+  
+  // Table Field Definitions----------------------
+  // Field: db_id (primary key)
+  //   mentioned as index above but not displayable in a view
+  
+  // Field: name (varchar 255)
+  $data['db']['name'] = array(
+    'title' => 'Name',
+    'field' => array(
+      'handler' => 'views_handler_field',
+      'click sortable' => TRUE,
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_string',
+    ),
+    'argument' => array(
+      'handler' => 'views_handler_argument_string',
+    ),
+  );
+  
+  // Field: description (varchar 255)
+  $data['db']['description'] = array(
+    'title' => 'Description',
+    'field' => array(
+      'handler' => 'views_handler_field',
+      'click sortable' => TRUE,
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_string',
+    ),
+    'argument' => array(
+      'handler' => 'views_handler_argument_string',
+    ),
+  );
+  
+  // Field: urlprefix (varchar 255)
+  $data['db']['urlprefix'] = array(
+    'title' => 'URL Prefix',
+    'help' => 'The url that when concatenated with the accession of a record in this db produces the url to the record in this database.',
+    'field' => array(
+      'handler' => 'views_handler_field',
+      'click sortable' => TRUE,
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_string',
+    ),
+    'argument' => array(
+      'handler' => 'views_handler_argument_string',
+    ),
+  );
+  
+  // Field: url (varchar 255)
+  $data['db']['url'] = array(
+    'title' => 'URL',
+    'help' => 'The url to the main page of the database',
+    'field' => array(
+      'handler' => 'views_handler_field',
+      'click sortable' => TRUE,
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_string',
+    ),
+    'argument' => array(
+      'handler' => 'views_handler_argument_string',
+    ),
+  );
+  
+  return $data;
+  
+}

+ 137 - 0
tripal_db/views/dbxref.views.inc

@@ -0,0 +1,137 @@
+<?php
+
+/**
+ * Purpose: this function returns the portion of the data array 
+ *   which describes the db table, it's fields and any joins between it and other tables
+ * @see tripal_db_views_data() --in tripal_db.views.inc
+ *
+ * BASE TABLE: dbxref
+ * @code
+ * create table dbxref (
+ *    dbxref_id serial not null,
+ *    primary key (dbxref_id),
+ *    db_id int not null,
+ *    foreign key (db_id) references db (db_id) on delete cascade INITIALLY DEFERRED,
+ *    accession varchar(255) not null,
+ *    version varchar(255) not null default '',
+ *    description text,
+ *    constraint dbxref_c1 unique (db_id,accession,version)
+ * );
+ * @endcode
+ */
+function retrieve_dbxref_views_data() {
+
+  // Basic table definition
+  $data['dbxref']['table']['group'] = 'Chado Database Reference';
+  $data['dbxref']['table']['base'] = array(
+    'field' => 'dbxref_id',
+    'title' => 'Chado Database Reference',
+    'help' => 'A Reference to another database. Allows easy linking between becords in one database to those in another.',
+    'database' => 'chado'
+  );
+
+  // Define relationships between this table and others
+  $data['dbxref']['table']['join'] = array(
+    'cvterm' => array(
+      'left_field' => 'dbxref_id',
+      'field' => 'dbxref_id',
+    ),
+    'feature' => array(
+      'left_field' => 'dbxref_id',
+      'field' => 'dbxref_id',
+    ),
+    'stock' => array(
+      'left_field' => 'dbxref_id',
+      'field' => 'dbxref_id',
+    ),     
+  );
+
+  // Table Field Definitions----------------------
+  // Field: dbxref_id (primary key)
+  //   mentioned as index above but not displayable in a view
+   
+  //Field: cv_id (foreign key: cv)
+  //  join between cv table and this one in cv.views.inc
+
+  // Field: accession (varchar 255)
+  $data['dbxref']['accession'] = array(
+    'title' => 'Accession',
+    'help' => 'The accession from the database.',
+    'field' => array(
+      'handler' => 'views_handler_field',
+      'click sortable' => TRUE,
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_string',
+    ),
+    'argument' => array(
+      'handler' => 'views_handler_argument_string',
+    ),
+  );
+
+  // Field: version (varchar 255)
+  $data['dbxref']['version'] = array(
+    'title' => 'Version',
+    'help' => 'The version of the database reference.',
+    'field' => array(
+      'handler' => 'views_handler_field',
+      'click sortable' => TRUE,
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_string',
+    ),
+    'argument' => array(
+      'handler' => 'views_handler_argument_string',
+    ),
+  );
+
+  // Field: description (text)
+  $data['dbxref']['description'] = array(
+    'title' => 'Description',
+    'help' => 'a description of the database reference.',
+    'field' => array(
+      'handler' => 'views_handler_field',
+      'click sortable' => TRUE,
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_string',
+    ),
+    'argument' => array(
+      'handler' => 'views_handler_argument_string',
+    ),
+  );
+
+  // Calculated Field: Accession Link (varchar 1024)
+  //  uses custom field handler to pull db urlprefix and concatenate with accession
+  //  solves the problem of not being able to add urlprefix to tables which only
+  //  join to dbxref table (not db)
+  $data['dbxref']['accession_link'] = array(
+    'title' => 'Accession Link',
+    'help' => 'Provides a link to the record in the external database.',
+    'field' => array(
+      'handler' => 'views_handler_field_dbxref_accession_link',
+      'click sortable' => TRUE,
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_string',
+    ),
+    'argument' => array(
+      'handler' => 'views_handler_argument_string',
+    ),
+  );
+
+  return $data;
+
+}

+ 1 - 0
tripal_db/views/handlers/views_handler_field_dbxref_accession_link.inc

@@ -0,0 +1 @@
+../../../tripal_core/views_handlers/views_handler_field_dbxref_accession_link.inc