From 074811bcc991032c7d91551688c5bd33b86b2b5c Mon Sep 17 00:00:00 2001 From: Reynold Tan Date: Wed, 19 Jun 2019 14:58:30 -0600 Subject: [PATCH 1/8] Phenotype Ontology field file structure --- .../analyzedphenotypes.fields.inc | 51 ++++++ .../ncit__synonym/ncit__synonym.inc | 151 ++++++++++++++++++ .../ncit__synonym/ncit__synonym_formatter.inc | 57 +++++++ .../ncit__synonym/ncit__synonym_widget.inc | 126 +++++++++++++++ 4 files changed, 385 insertions(+) create mode 100644 includes/TripalFields/ncit__synonym/ncit__synonym.inc create mode 100644 includes/TripalFields/ncit__synonym/ncit__synonym_formatter.inc create mode 100644 includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc diff --git a/includes/TripalFields/analyzedphenotypes.fields.inc b/includes/TripalFields/analyzedphenotypes.fields.inc index 57cdae4..892836a 100644 --- a/includes/TripalFields/analyzedphenotypes.fields.inc +++ b/includes/TripalFields/analyzedphenotypes.fields.inc @@ -135,6 +135,25 @@ function analyzedphenotypes_bundle_fields_info($entity_type, $bundle) { 'type' => 'field_chado_storage', ), ); + + // Phenotype Ontology. + tripal_insert_cvterm(array( + 'id' => 'NCIT:c52469', + 'name' => 'Synonym', + 'cv_name' => 'NCIT', + 'definition' => 'A word having the same or nearly the same meaning as another word or other words in a language; a word or an expression that serves as a figurative or symbolic substitute for another', + )); + $field_name = 'ncit__synonym'; + $field_type = 'ncit__synonym'; + $fields[$field_name] = array( + 'field_name' => $field_name, + 'type' => $field_type, + 'cardinality' => 1, + 'locked' => FALSE, + 'storage' => array( + 'type' => 'field_chado_storage', + ), + ); } // IN GERMPLASM PAGE ONLY: @@ -433,6 +452,38 @@ function analyzedphenotypes_bundle_instances_info($entity_type, $bundle) { ), ), ); + + // Phenotype Ontology - Synonym. + $field_name = 'ncit__synonym'; + $field_type = 'ncit__synonym'; + $instances[$field_name] = array( + 'field_name' => $field_name, + 'entity_type' => $entity_type, + 'bundle' => $bundle->name, + 'label' => 'Phenotype Ontology', + 'description' => 'Phenotype Ontology.', + 'required' => FALSE, + 'settings' => array( + 'term_vocabulary' => 'NCIT', + 'term_name' => 'Synonym', + 'term_accession' => 'c52469', + 'auto_attach' => FALSE, + 'chado_table' => $bundle->data_table, + 'chado_column' => 'cvterm_id', + 'base_table' => $bundle->data_table, + ), + 'widget' => array( + 'type' => 'ncit__synonym_widget', + 'settings' => array(), + ), + 'display' => array( + 'default' => array( + 'label' => 'hidden', + 'type' => 'ncit__synonym_formatter', + 'settings' => array(), + ), + ), + ); } // IN GERMPLASM PAGE ONLY: diff --git a/includes/TripalFields/ncit__synonym/ncit__synonym.inc b/includes/TripalFields/ncit__synonym/ncit__synonym.inc new file mode 100644 index 0000000..5052f3e --- /dev/null +++ b/includes/TripalFields/ncit__synonym/ncit__synonym.inc @@ -0,0 +1,151 @@ + 'tripal_no_storage', + // It is expected that all fields set a 'value' in the load() function. + // In many cases, the value may be an associative array of key/value pairs. + // In order for Tripal to provide context for all data, the keys should + // be a controlled vocabulary term (e.g. rdfs:type). Keys in the load() + // function that are supported by the query() function should be + // listed here. + 'browseable_keys' => 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 instance. + // It is recommended to put settings at the instance level whenever possible. + // If you override this variable in a child class be sure to replicate the + // term_name, term_vocab, term_accession and term_fixed keys as these are + // required for all TripalFields. + public static $default_instance_settings = array( + // The short name for the vocabulary (e.g. schema, SO, GO, PATO, etc.). + 'term_vocabulary' => 'NCIT', + // The name of the term. + 'term_name' => 'Synonym', + // The unique ID (i.e. accession) of the term. + 'term_accession' => 'c52469', + // Set to TRUE if the site admin is not allowed to change the term + // type, otherwise the admin can change the term mapped to a field. + 'term_fixed' => FALSE, + // Indicates if this field should be automatically attached to display + // or web services or if this field should be loaded separately. This + // is convenient for speed. Fields that are slow should for loading + // should have auto_attach set to FALSE so tha their values can be + // attached asynchronously. + 'auto_attach' => FALSE, + // The table where the options for this specific field are stored. + // This can be one of trpfancy_browse_options or trpfancy_browse_options_per_entity + // based on admin configuration. Default: trpfancy_browse_options. + 'option_storage' => '', + // A list of browser types this field intends to provide. + 'browser_types' => '', + ); + + // A boolean specifying that users should not be allowed to create + // fields and instances of this field type through the UI. Such + // fields can only be created programmatically with field_create_field() + // and field_create_instance(). + public static $no_ui = FALSE; + // A boolean specifying that the field will not contain any data. This + // should exclude the field from web services or downloads. An example + // could be a quick browse field that appears on the page that redirects + // the user but otherwise provides no data. + public static $no_data = TRUE; + + /** + * Loads the field values from the underlying data store. + * + * @param $entity + * + * @return + * An array of the following format: + * $entity->{$field_name}['und'][0]['value'] = $value; + * where: + * - $entity is the entity object to which this field is attached. + * - $field_name is the name of this field + * - 'und' is the language code (in this case 'und' == undefined) + * - 0 is the cardinality. Increment by 1 when more than one item is + * available. + * - 'value' is the key indicating the value of this field. It should + * always be set. The value of the 'value' key will be the contents + * used for web services and for downloadable content. The value + * should be of the follow format types: 1) A single value (text, + * numeric, etc.) 2) An array of key value pair. 3) If multiple entries + * then cardinality should incremented and format types 1 and 2 should + * be used for each item. + * The array may contain as many other keys at the same level as 'value' + * but those keys are for internal field use and are not considered the + * value of the field. + * + * + */ + public function load($entity) { + $field_name = $this->instance['field_name']; + + $entity->{$field_name}['und'][0]['value']['local:number of experiments'] = 1; + } + + /** + * 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() { + + // Retrieve the current settings. + // If this field was just created these will contain the default values. + $settings = $this->instance['settings']; + + // Allow the parent Tripal Field to set up the form element for us. + $element = parent::instanceSettingsForm(); + + return $element; + } +} diff --git a/includes/TripalFields/ncit__synonym/ncit__synonym_formatter.inc b/includes/TripalFields/ncit__synonym/ncit__synonym_formatter.inc new file mode 100644 index 0000000..261fdbb --- /dev/null +++ b/includes/TripalFields/ncit__synonym/ncit__synonym_formatter.inc @@ -0,0 +1,57 @@ + 'markup', + '#markup' => 'lorem', + ); + + + return $element; + } +} diff --git a/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc b/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc new file mode 100644 index 0000000..a7f1528 --- /dev/null +++ b/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc @@ -0,0 +1,126 @@ +{$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) { + } +} From 7e45b5793849c85a951b484433191a3f74140186 Mon Sep 17 00:00:00 2001 From: Reynold Tan Date: Fri, 21 Jun 2019 14:36:40 -0600 Subject: [PATCH 2/8] Working on ontology update form --- .../ncit__synonym/ncit__synonym.inc | 63 ++++++++++----- .../ncit__synonym/ncit__synonym_formatter.inc | 9 ++- .../ncit__synonym/ncit__synonym_widget.inc | 78 ++++++++++++++++++- 3 files changed, 124 insertions(+), 26 deletions(-) diff --git a/includes/TripalFields/ncit__synonym/ncit__synonym.inc b/includes/TripalFields/ncit__synonym/ncit__synonym.inc index 5052f3e..a6c023d 100644 --- a/includes/TripalFields/ncit__synonym/ncit__synonym.inc +++ b/includes/TripalFields/ncit__synonym/ncit__synonym.inc @@ -6,7 +6,7 @@ * Data: No data. * Assumptions: */ -class ncit__synonym extends TripalField { +class ncit__synonym extends ChadoField { // -------------------------------------------------------------------------- // EDITABLE STATIC CONSTANTS // @@ -31,14 +31,14 @@ class ncit__synonym extends TripalField { // Once instances exist for a field type then these settings cannot be // changed. public static $default_settings = array( - 'storage' => 'tripal_no_storage', + 'storage' => 'field_chado_storage', // It is expected that all fields set a 'value' in the load() function. // In many cases, the value may be an associative array of key/value pairs. // In order for Tripal to provide context for all data, the keys should // be a controlled vocabulary term (e.g. rdfs:type). Keys in the load() // function that are supported by the query() function should be // listed here. - 'browseable_keys' => array(), + 'searchable_keys' => array(), ); // Provide a list of instance specific settings. These can be access within @@ -64,12 +64,6 @@ class ncit__synonym extends TripalField { // should have auto_attach set to FALSE so tha their values can be // attached asynchronously. 'auto_attach' => FALSE, - // The table where the options for this specific field are stored. - // This can be one of trpfancy_browse_options or trpfancy_browse_options_per_entity - // based on admin configuration. Default: trpfancy_browse_options. - 'option_storage' => '', - // A list of browser types this field intends to provide. - 'browser_types' => '', ); // A boolean specifying that users should not be allowed to create @@ -81,7 +75,7 @@ class ncit__synonym extends TripalField { // should exclude the field from web services or downloads. An example // could be a quick browse field that appears on the page that redirects // the user but otherwise provides no data. - public static $no_data = TRUE; + public static $no_data = FALSE; /** * Loads the field values from the underlying data store. @@ -111,9 +105,45 @@ class ncit__synonym extends TripalField { * */ public function load($entity) { - $field_name = $this->instance['field_name']; + // Trait/cvterm record. + $record = $entity->chado_record; - $entity->{$field_name}['und'][0]['value']['local:number of experiments'] = 1; + if ($record) { + // Has record. + $settings = $this->instance['settings']; + + // Define relationship between trait and ontology term by + // creating entry in cvterm_relationhip where subject id is the ontology term + // and object id being the trait. Relation is of type related (as configured). + $field_table = array( + 'table' => 'cvterm_relationship', + 'field' => 'subject_id' + ); + + $field_name = $this->field['field_name']; + + // Set some defaults for the empty record. + $entity->{$field_name}['und'][0] = array( + 'value' => array(), + ); + + // Requires ontology term for this trait in both Tripal Engine and End-user. + // @see api/ontology.api + $traitprop = ap_get_cvterm( + array('cvterm_id' => $entity->chado_record_id), + array('dataset' => 'fullset') + ); + + // To user (formmater): + if ($traitprop['crop_ontology']) { + $term_rel_subject = tripal_get_chado_semweb_term($field_table['table'], $field_table['field']); + $entity->{$field_name}['und'][0]['value'][ $term_rel_subject ] = $traitprop['crop_ontology']; + } + + // To Tripal engine (widget): + $linker_field = 'chado-' . $field_table['table'] . '__' . $field_table['field']; + $entity->{$field_name}['und'][ $linker_field ] = 1;// $traitprop['crop_ontology']; + } } /** @@ -138,14 +168,5 @@ class ncit__synonym extends TripalField { * the changes in the form function itself but that doesn't work here. */ public function instanceSettingsForm() { - - // Retrieve the current settings. - // If this field was just created these will contain the default values. - $settings = $this->instance['settings']; - - // Allow the parent Tripal Field to set up the form element for us. - $element = parent::instanceSettingsForm(); - - return $element; } } diff --git a/includes/TripalFields/ncit__synonym/ncit__synonym_formatter.inc b/includes/TripalFields/ncit__synonym/ncit__synonym_formatter.inc index 261fdbb..4759e1f 100644 --- a/includes/TripalFields/ncit__synonym/ncit__synonym_formatter.inc +++ b/includes/TripalFields/ncit__synonym/ncit__synonym_formatter.inc @@ -12,13 +12,19 @@ * - search button text. * - autocomplete path. */ -class ncit__synonym_formatter extends TripalFieldFormatter { +class ncit__synonym_formatter extends ChadoFieldFormatter { // The default label for this field. public static $default_label = 'Phenotype Ontology'; // The list of field types for which this formatter is appropriate. public static $field_types = array('ncit__synonym'); + + + public function settingsForm($view_mode, $form, &$form_state) { + + } + /** * Provides the display for a field * @@ -44,7 +50,6 @@ class ncit__synonym_formatter extends TripalFieldFormatter { * hook_field_formatter_view() function. */ public function view(&$element, $entity_type, $entity, $langcode, $items, $display) { - // All set, render items. $element[0] = array( '#type' => 'markup', diff --git a/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc b/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc index a7f1528..6bbe619 100644 --- a/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc +++ b/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc @@ -7,7 +7,7 @@ * * Allowing edit? No */ -class ncit__synonym_widget extends TripalFieldWidget { +class ncit__synonym_widget extends ChadoFieldWidget { // The default lable for this field. public static $default_label = 'No Edits'; @@ -71,7 +71,78 @@ class ncit__synonym_widget extends TripalFieldWidget { * $delta above */ public function form(&$widget, &$form, &$form_state, $langcode, $items, $delta, $element) { - parent::form($widget, $form, $form_state, $langcode, $items, $delta, $element); + if (count($delta) == 1) { + // Create field element to allow user to modify trait ontology term. + $field_name = $this->field['field_name']; + $field_table = array( + 'table' => 'cvterm_relationship', + 'field' => 'subject_id' + ); + + $linker_field = 'chado-' . $field_table['table'] . '__' . $field_table['field']; + + // Create or upldate. + + // The value presented to the user via load. + // If $items['delta']['value'] is set then we are updating and already have this + // information. As such, simply save it again. + $widget['value'] = array( + '#type' => 'value', + '#value' => array_key_exists($delta, $items) ? $items[ $delta ]['value'] : '', + ); + + // Pull out the value previously saved to be used as the default. + $ontology_term = ''; + if (count($items) > 0 && array_key_exists($linker_field, $items[0])) { + $ontology_term = $items[0][ $linker_field ]; + } + + // Autocomplete field - instance the same as the ontology field in upload. + // @see api/ontology api + // upload.inc + + // Search ontology terms in genus configuration: + $widget['ap_fieldset'] = array( + '#type' => 'fieldset', + '#title' => t('Crop Ontology'), + ); + + // Fetch all genus with ontology value set. + $cv_options = array(); + $genus = ap_get_genus(); + foreach($genus as $g) { + $genus_key = strtolower(str_replace(' ', '_', $g)); + $conf = variable_get('analyzedphenotypes_systemvar_' . $genus_key . '_ontology'); + if ($conf) { + $term_name = ap_get_cv( + array('cv_id' => $conf) + ); + + $cv_options[ $g ] = $g . ' : ' . $term_name['name']; + } + } + + $widget['ap_fieldset']['ap_source_cv'] = array( + '#type' => 'select', + '#title' => t('CV'), + '#description' => t('Select ontology terms in Genus-CV configuration to limit/filter terms only to this option.'), + '#options' => array('Select') + $cv_options, + ); + + $widget['ap_fieldset'][ $linker_field ] = array( + '#type' => 'textfield', + '#title' => t('Trait Ontology'), + //'#default_value' => $ontology_term, + '#autocomplete_path' => 'admin/tripal/extension/analyzedphenotypes/json/ontology/Lens', + ); + } + else { + // This field can only process one field per trait. + drupal_set_message('Please set the maximum number of values user can enter for this field to 1 in manage field.', 'status', FALSE); + $widget['no_field'] = array( + '#markup' => 'Field not available.', + ); + } } /** @@ -84,7 +155,8 @@ class ncit__synonym_widget extends TripalFieldWidget { * fields must be used to set the 'value' field. */ public function validate($element, $form, &$form_state, $langcode, $delta) { - } + + } /** * Performs extra commands when the entity form is submitted. From 1e1dd2e372e704b6bb6cf1149340db3c5cbdf94a Mon Sep 17 00:00:00 2001 From: Reynold Tan Date: Wed, 26 Jun 2019 14:17:29 -0600 Subject: [PATCH 3/8] Yes! this is a working field - it does save now --- .../analyzedphenotypes.fields.inc | 2 +- .../ncit__synonym/ncit__synonym.inc | 86 +++++------ .../ncit__synonym/ncit__synonym_formatter.inc | 30 ++-- .../ncit__synonym/ncit__synonym_widget.inc | 136 ++++++++---------- 4 files changed, 126 insertions(+), 128 deletions(-) diff --git a/includes/TripalFields/analyzedphenotypes.fields.inc b/includes/TripalFields/analyzedphenotypes.fields.inc index 892836a..9b5ce9e 100644 --- a/includes/TripalFields/analyzedphenotypes.fields.inc +++ b/includes/TripalFields/analyzedphenotypes.fields.inc @@ -469,7 +469,7 @@ function analyzedphenotypes_bundle_instances_info($entity_type, $bundle) { 'term_accession' => 'c52469', 'auto_attach' => FALSE, 'chado_table' => $bundle->data_table, - 'chado_column' => 'cvterm_id', + 'chado_column' => $bundle->data_table . '_id', 'base_table' => $bundle->data_table, ), 'widget' => array( diff --git a/includes/TripalFields/ncit__synonym/ncit__synonym.inc b/includes/TripalFields/ncit__synonym/ncit__synonym.inc index a6c023d..7af3daf 100644 --- a/includes/TripalFields/ncit__synonym/ncit__synonym.inc +++ b/includes/TripalFields/ncit__synonym/ncit__synonym.inc @@ -15,9 +15,9 @@ class ncit__synonym extends ChadoField { // the field and it's default widget and formatter. // -------------------------------------------------------------------------- // The default label for this field. - public static $default_label = 'Phenotype Ontology'; + public static $default_label = 'Crop Ontology'; // The default description for this field. - public static $default_description = 'Phenotype Ontology'; + public static $default_description = 'Crop Ontology'; // The default widget for this field. public static $default_widget = 'ncit__synonym_widget'; // The default formatter for this field. @@ -31,14 +31,14 @@ class ncit__synonym extends ChadoField { // Once instances exist for a field type then these settings cannot be // changed. public static $default_settings = array( - 'storage' => 'field_chado_storage', + 'storage' => 'tripal_no_storage', // It is expected that all fields set a 'value' in the load() function. // In many cases, the value may be an associative array of key/value pairs. // In order for Tripal to provide context for all data, the keys should // be a controlled vocabulary term (e.g. rdfs:type). Keys in the load() // function that are supported by the query() function should be // listed here. - 'searchable_keys' => array(), + 'browseable_keys' => array(), ); // Provide a list of instance specific settings. These can be access within @@ -64,6 +64,17 @@ class ncit__synonym extends ChadoField { // should have auto_attach set to FALSE so tha their values can be // attached asynchronously. 'auto_attach' => FALSE, + // The table where the options for this specific field are stored. + // This can be one of trpfancy_browse_options or trpfancy_browse_options_per_entity + // based on admin configuration. Default: trpfancy_browse_options. + 'option_storage' => '', + // A list of browser types this field intends to provide. + 'browser_types' => '', + + 'chado_table' => 'cvterm_relationship', + 'chado_column' => 'cvterm_relationship_id', + 'base_table' => 'cvterm_relationship' + ); // A boolean specifying that users should not be allowed to create @@ -75,7 +86,7 @@ class ncit__synonym extends ChadoField { // should exclude the field from web services or downloads. An example // could be a quick browse field that appears on the page that redirects // the user but otherwise provides no data. - public static $no_data = FALSE; + public static $no_data = TRUE; /** * Loads the field values from the underlying data store. @@ -105,45 +116,29 @@ class ncit__synonym extends ChadoField { * */ public function load($entity) { - // Trait/cvterm record. - $record = $entity->chado_record; - - if ($record) { - // Has record. - $settings = $this->instance['settings']; - - // Define relationship between trait and ontology term by - // creating entry in cvterm_relationhip where subject id is the ontology term - // and object id being the trait. Relation is of type related (as configured). - $field_table = array( - 'table' => 'cvterm_relationship', - 'field' => 'subject_id' - ); - - $field_name = $this->field['field_name']; + // We need the term configuration for term Related used when creating relationship. + $sysvar = ap_get_variablenames( + array('variablename' => 'related'), + array('set' => 'terms') + ); + $sysvar_related = variable_get($sysvar); - // Set some defaults for the empty record. - $entity->{$field_name}['und'][0] = array( - 'value' => array(), - ); + $m = chado_query("SELECT cvterm_relationship_id AS id, subject_id AS synonym_id + FROM {cvterm_relationship} WHERE type_id = :type_id AND object_id = :trait_id limit 1", + array(':type_id' => $sysvar_related, ':trait_id' => $entity->chado_record_id)) + ->fetchObject(); - // Requires ontology term for this trait in both Tripal Engine and End-user. - // @see api/ontology.api - $traitprop = ap_get_cvterm( - array('cvterm_id' => $entity->chado_record_id), - array('dataset' => 'fullset') - ); + $this->instance['settings']['chado_table'] = 'cvterm_relationship'; + $field_table = $this->instance['settings']['chado_table']; - // To user (formmater): - if ($traitprop['crop_ontology']) { - $term_rel_subject = tripal_get_chado_semweb_term($field_table['table'], $field_table['field']); - $entity->{$field_name}['und'][0]['value'][ $term_rel_subject ] = $traitprop['crop_ontology']; - } - - // To Tripal engine (widget): - $linker_field = 'chado-' . $field_table['table'] . '__' . $field_table['field']; - $entity->{$field_name}['und'][ $linker_field ] = 1;// $traitprop['crop_ontology']; - } + $field_name = $this->field['field_name']; + $entity->{$field_name}['und'][0] = array( + 'value' => '', + 'chado-' . $field_table . '__cvterm_relationship_id' => $m->id, + 'chado-' . $field_table . '__type_id' => $sysvar_related, + 'chado-' . $field_table . '__object_id' => $entity->chado_record_id, + 'chado-' . $field_table . '__subject_id' => $m->synonym_id + ); } /** @@ -168,5 +163,14 @@ class ncit__synonym extends ChadoField { * the changes in the form function itself but that doesn't work here. */ public function instanceSettingsForm() { + + // Retrieve the current settings. + // If this field was just created these will contain the default values. + $settings = $this->instance['settings']; + + // Allow the parent Tripal Field to set up the form element for us. + $element = parent::instanceSettingsForm(); + + return $element; } } diff --git a/includes/TripalFields/ncit__synonym/ncit__synonym_formatter.inc b/includes/TripalFields/ncit__synonym/ncit__synonym_formatter.inc index 4759e1f..87f1449 100644 --- a/includes/TripalFields/ncit__synonym/ncit__synonym_formatter.inc +++ b/includes/TripalFields/ncit__synonym/ncit__synonym_formatter.inc @@ -12,19 +12,13 @@ * - search button text. * - autocomplete path. */ -class ncit__synonym_formatter extends ChadoFieldFormatter { +class ncit__synonym_formatter extends TripalFieldFormatter { // The default label for this field. - public static $default_label = 'Phenotype Ontology'; + public static $default_label = 'Crop Ontology'; // The list of field types for which this formatter is appropriate. public static $field_types = array('ncit__synonym'); - - - public function settingsForm($view_mode, $form, &$form_state) { - - } - /** * Provides the display for a field * @@ -50,13 +44,25 @@ class ncit__synonym_formatter extends ChadoFieldFormatter { * hook_field_formatter_view() function. */ public function view(&$element, $entity_type, $entity, $langcode, $items, $display) { - // All set, render items. - $element[0] = array( - '#type' => 'markup', - '#markup' => 'lorem', + $trait_id = $items[0]['chado-cvterm_relationship__object_id']; + dpm($trait_id); + + // Requires ontology term for this trait in both Tripal Engine and End-user. + // @see api/ontology.api + $traitprop = ap_get_cvterm( + array('cvterm_id' => $trait_id), + array('dataset' => 'fullset') ); + if ($traitprop[0]['crop_ontology']) { + $element[0] = array( + '#type' => 'markup', + '#markup' => $traitprop[0]['crop_ontology'], + ); + } + + return $element; } } diff --git a/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc b/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc index 6bbe619..fd9a075 100644 --- a/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc +++ b/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc @@ -7,7 +7,7 @@ * * Allowing edit? No */ -class ncit__synonym_widget extends ChadoFieldWidget { +class ncit__synonym_widget extends TripalFieldWidget { // The default lable for this field. public static $default_label = 'No Edits'; @@ -71,78 +71,55 @@ class ncit__synonym_widget extends ChadoFieldWidget { * $delta above */ public function form(&$widget, &$form, &$form_state, $langcode, $items, $delta, $element) { - if (count($delta) == 1) { - // Create field element to allow user to modify trait ontology term. - $field_name = $this->field['field_name']; - $field_table = array( - 'table' => 'cvterm_relationship', - 'field' => 'subject_id' - ); - - $linker_field = 'chado-' . $field_table['table'] . '__' . $field_table['field']; - - // Create or upldate. - - // The value presented to the user via load. - // If $items['delta']['value'] is set then we are updating and already have this - // information. As such, simply save it again. - $widget['value'] = array( - '#type' => 'value', - '#value' => array_key_exists($delta, $items) ? $items[ $delta ]['value'] : '', - ); - - // Pull out the value previously saved to be used as the default. - $ontology_term = ''; - if (count($items) > 0 && array_key_exists($linker_field, $items[0])) { - $ontology_term = $items[0][ $linker_field ]; - } - - // Autocomplete field - instance the same as the ontology field in upload. - // @see api/ontology api - // upload.inc - - // Search ontology terms in genus configuration: - $widget['ap_fieldset'] = array( - '#type' => 'fieldset', - '#title' => t('Crop Ontology'), - ); - - // Fetch all genus with ontology value set. - $cv_options = array(); - $genus = ap_get_genus(); - foreach($genus as $g) { - $genus_key = strtolower(str_replace(' ', '_', $g)); - $conf = variable_get('analyzedphenotypes_systemvar_' . $genus_key . '_ontology'); - if ($conf) { - $term_name = ap_get_cv( - array('cv_id' => $conf) - ); - - $cv_options[ $g ] = $g . ' : ' . $term_name['name']; - } - } - - $widget['ap_fieldset']['ap_source_cv'] = array( - '#type' => 'select', - '#title' => t('CV'), - '#description' => t('Select ontology terms in Genus-CV configuration to limit/filter terms only to this option.'), - '#options' => array('Select') + $cv_options, - ); - - $widget['ap_fieldset'][ $linker_field ] = array( - '#type' => 'textfield', - '#title' => t('Trait Ontology'), - //'#default_value' => $ontology_term, - '#autocomplete_path' => 'admin/tripal/extension/analyzedphenotypes/json/ontology/Lens', - ); - } - else { - // This field can only process one field per trait. - drupal_set_message('Please set the maximum number of values user can enter for this field to 1 in manage field.', 'status', FALSE); - $widget['no_field'] = array( - '#markup' => 'Field not available.', - ); - } + parent::form($widget, $form, $form_state, $langcode, $items, $delta, $element); + + $field_name = $this->field['field_name']; + $field_type = $this->field['type']; + + $this->instance['settings']['chado_table'] = 'cvterm_relationship'; + $field_table = $this->instance['settings']['chado_table']; + + $this->instance['settings']['chado_column'] = 'cvterm_relationship_id'; + $field_column = $this->instance['settings']['chado_column']; + + $this->instance['settings']['base_table'] = 'cvterm_relationship'; + $base_table = $this->instance['settings']['base_table']; + + $widget['#table_name'] = $field_table; + + $widget['value'] = array( + '#type' => 'value', + '#value' => $items[$delta]['chado-cvterm__cvterm_relationship_id'], + ); + + $widget['chado-cvterm_relationship__cvterm_relationship_id'] = array( + '#type' => 'value', + '#value' => $items[$delta]['chado-cvterm_relationship__cvterm_relationship_id'], + ); + + $widget['chado-cvterm_relationship__type_id'] = array( + '#type' => 'value', + '#value' => $items[$delta]['chado-cvterm_relationship__type_id'], + ); + + $widget['chado-cvterm_relationship__object_id'] = array( + '#type' => 'value', + '#value' => $items[$delta]['chado-cvterm_relationship__object_id'], + ); + + $widget['chado-cvterm_relationship__subject_id'] = array( + '#type' => 'value', + '#value' => $items[$delta]['chado-cvterm_relationship__subject_id'], + ); + + + $widget['new_term'] = array( + '#type' => 'select', + '#title' => 'Trait Ontology', + '#options' => array(4010=>'Subset Traits: # Pods (count)', 6086 => 'Chickpea Traits', 5705 => 'Lentil Traits'), + //'#autocomplete_path' => 'admin/tripal/storage/chado/auto_name/cvterm/2', + '#default_value' => $m->subject_id, + ); } /** @@ -155,8 +132,19 @@ class ncit__synonym_widget extends ChadoFieldWidget { * fields must be used to set the 'value' field. */ public function validate($element, $form, &$form_state, $langcode, $delta) { + $field_name = $this->field['field_name']; - } + + /////////////// + $this->instance['settings']['chado_table'] = 'cvterm_relationship'; + $field_table = $this->instance['settings']['chado_table']; + + $form_state['values'][$field_name][$langcode][$delta]['value'] = $form_state['values'][$field_name][$langcode][$delta]['value']; + $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__cvterm_relationship_id'] = $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__cvterm_relationship_id']; + $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__object_id'] = $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__object_id']; + $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__subject_id'] = $form_state['values'][$field_name][$langcode][$delta]['new_term']; + $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__type_id'] = $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__type_id']; + } /** * Performs extra commands when the entity form is submitted. From ba0a269cbf4da276024c5fde580ed7b07b1e371d Mon Sep 17 00:00:00 2001 From: Reynold Tan Date: Tue, 2 Jul 2019 14:47:59 -0600 Subject: [PATCH 4/8] Create and Update work --- .../ncit__synonym/ncit__synonym.inc | 74 +++++-- .../ncit__synonym/ncit__synonym_formatter.inc | 17 +- .../ncit__synonym/ncit__synonym_widget.inc | 199 ++++++++++++++---- 3 files changed, 208 insertions(+), 82 deletions(-) diff --git a/includes/TripalFields/ncit__synonym/ncit__synonym.inc b/includes/TripalFields/ncit__synonym/ncit__synonym.inc index 7af3daf..d7e9557 100644 --- a/includes/TripalFields/ncit__synonym/ncit__synonym.inc +++ b/includes/TripalFields/ncit__synonym/ncit__synonym.inc @@ -116,29 +116,57 @@ class ncit__synonym extends ChadoField { * */ public function load($entity) { - // We need the term configuration for term Related used when creating relationship. - $sysvar = ap_get_variablenames( - array('variablename' => 'related'), - array('set' => 'terms') - ); - $sysvar_related = variable_get($sysvar); - - $m = chado_query("SELECT cvterm_relationship_id AS id, subject_id AS synonym_id - FROM {cvterm_relationship} WHERE type_id = :type_id AND object_id = :trait_id limit 1", - array(':type_id' => $sysvar_related, ':trait_id' => $entity->chado_record_id)) - ->fetchObject(); - - $this->instance['settings']['chado_table'] = 'cvterm_relationship'; - $field_table = $this->instance['settings']['chado_table']; - - $field_name = $this->field['field_name']; - $entity->{$field_name}['und'][0] = array( - 'value' => '', - 'chado-' . $field_table . '__cvterm_relationship_id' => $m->id, - 'chado-' . $field_table . '__type_id' => $sysvar_related, - 'chado-' . $field_table . '__object_id' => $entity->chado_record_id, - 'chado-' . $field_table . '__subject_id' => $m->synonym_id - ); + $record = $entity->chado_record_id; + + if ($record) { + // We need the term configuration for term Related used when creating relationship. + $sysvar = ap_get_variablenames( + array('variablename' => 'related'), + array('set' => 'terms') + ); + $sysvar_related = variable_get($sysvar); + + if ($sysvar_related) { + $identifiers = array( + 'column' => array('cvterm_relationship_id', 'subject_id'), + 'value' => array('type_id' => $sysvar_related, 'object_id' => $record) + ); + $rel = chado_select_record('cvterm_relationship', $identifiers['column'], $identifiers['value']); + + $field_name = $this->field['field_name']; + $field_table = 'cvterm_relationship'; + + if ($rel) { + // Has crop ontology. + + // For chado mechnanism. + $entity->{$field_name}['und'][0] = array( + 'chado-' . $field_table . '__cvterm_relationship_id' => $rel[0]->cvterm_relationship_id, + 'chado-' . $field_table . '__type_id' => $sysvar_related, + 'chado-' . $field_table . '__object_id' => $entity->chado_record_id, + 'chado-' . $field_table . '__subject_id' => $rel[0]->subject_id + ); + + // For end user. + $relationship_term = tripal_get_chado_semweb_term('cvterm_relationship', 'subject_id'); + + $traitprop = ap_get_cvterm( + array('cvterm_id' => $record), + array('dataset' => 'fullset') + ); + + $entity->{$field_name}['und'][0]['value'][ $relationship_term ] = $traitprop[0]['crop_ontology']; + } + else { + // Crop ontology not set. + $entity->{$field_name}['und'][0] = array( + 'value' => array(), + 'chado-' . $field_table . '__object_id' => $entity->chado_record_id, + 'chado-' . $field_table . '__type_id' => $sysvar_related, + ); + } + } + } } /** diff --git a/includes/TripalFields/ncit__synonym/ncit__synonym_formatter.inc b/includes/TripalFields/ncit__synonym/ncit__synonym_formatter.inc index 87f1449..ca7133b 100644 --- a/includes/TripalFields/ncit__synonym/ncit__synonym_formatter.inc +++ b/includes/TripalFields/ncit__synonym/ncit__synonym_formatter.inc @@ -44,25 +44,14 @@ class ncit__synonym_formatter extends TripalFieldFormatter { * hook_field_formatter_view() function. */ public function view(&$element, $entity_type, $entity, $langcode, $items, $display) { - $trait_id = $items[0]['chado-cvterm_relationship__object_id']; - dpm($trait_id); - - // Requires ontology term for this trait in both Tripal Engine and End-user. - // @see api/ontology.api - $traitprop = ap_get_cvterm( - array('cvterm_id' => $trait_id), - array('dataset' => 'fullset') - ); - - - if ($traitprop[0]['crop_ontology']) { + // Render crop ontology for this trait. + if ($items[0]['value']) { $element[0] = array( '#type' => 'markup', - '#markup' => $traitprop[0]['crop_ontology'], + '#markup' => current($items[0]['value']), ); } - return $element; } } diff --git a/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc b/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc index fd9a075..2b0f475 100644 --- a/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc +++ b/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc @@ -71,55 +71,115 @@ class ncit__synonym_widget extends TripalFieldWidget { * $delta above */ public function form(&$widget, &$form, &$form_state, $langcode, $items, $delta, $element) { - parent::form($widget, $form, $form_state, $langcode, $items, $delta, $element); + if (count($delta) == 1) { + // By the default, field allows for multiple/unlimited values to be entered. AP only + // supports 1 and only 1 crop ontology term per trait name. - $field_name = $this->field['field_name']; - $field_type = $this->field['type']; + parent::form($widget, $form, $form_state, $langcode, $items, $delta, $element); + + // Field name. + $field_name = $this->field['field_name']; + + // Elements of chado.cvterm_relationship table: + $chado_table = 'chado-cvterm_relationship__'; + + // Column - cvterm_relationship_id primary key. + $widget['value'] = array( + '#type' => 'value', + '#value' => $items[$delta][ $chado_table . 'cvterm_relationship_id' ] ?? '', + ); + + // Column - cvterm_relationship_id primary key. + $widget[ $chado_table . 'cvterm_relationship_id' ] = array( + '#type' => 'value', + '#value' => $items[$delta][ $chado_table . 'cvterm_relationship_id' ] ?? '', + ); + + // Column - object_id, the trait id (cvterm_id) # the crop ontology term maps to. + // Has value even when trait has no crop ontology. + $widget[ $chado_table . 'object_id' ] = array( + '#type' => 'value', + '#value' => $items[$delta][ $chado_table . 'object_id' ], + ); - $this->instance['settings']['chado_table'] = 'cvterm_relationship'; - $field_table = $this->instance['settings']['chado_table']; + // Column - subject_id, the crop ontology id (cvterm_id) that maps to a trait. + $widget[ $chado_table . 'subject_id' ] = array( + '#type' => 'value', + '#value' => $items[$delta][ $chado_table . 'subject_id' ] ?? '', + ); - $this->instance['settings']['chado_column'] = 'cvterm_relationship_id'; - $field_column = $this->instance['settings']['chado_column']; + // Column - type_id, refers to ontology term Related in AP configuration. + // Has value even when trait has no crop ontology. + $widget[ $chado_table . 'type_id' ] = array( + '#type' => 'value', + '#value' => $items[$delta][ $chado_table . 'type_id' ], + ); - $this->instance['settings']['base_table'] = 'cvterm_relationship'; - $base_table = $this->instance['settings']['base_table']; + // FORM ELEMENTS: + // Current crop ontology. + $relationship_term = tripal_get_chado_semweb_term('cvterm_relationship', 'subject_id'); + $ontology = $items[$delta]['value'][ $relationship_term ] ?? 'Crop ontology not set'; - $widget['#table_name'] = $field_table; + // FIELDSET - Main fieldset - search ontology terms. + $widget['ap_fieldset'] = array( + '#type' => 'fieldset', + '#title' => t('Crop Ontology'), + ); - $widget['value'] = array( - '#type' => 'value', - '#value' => $items[$delta]['chado-cvterm__cvterm_relationship_id'], - ); + // MARKUP - Show current record if any. + $widget['ap_fieldset']['ap_ontology'] = array( + '#type' => 'markup', + '#markup' => '

' . $ontology . '

', + ); - $widget['chado-cvterm_relationship__cvterm_relationship_id'] = array( - '#type' => 'value', - '#value' => $items[$delta]['chado-cvterm_relationship__cvterm_relationship_id'], - ); + $vocs = []; + $vocs = chado_get_cv_select_options(); + $cv_id = isset($form_state['values'][$field_name][$langcode][$delta]['ap_fieldset']['ap_ajax_response']['ap_source_cv']) + ? $form_state['values'][$field_name][$langcode][$delta]['ap_fieldset']['ap_ajax_response']['ap_source_cv'] : 0; - $widget['chado-cvterm_relationship__type_id'] = array( - '#type' => 'value', - '#value' => $items[$delta]['chado-cvterm_relationship__type_id'], - ); + // ITEM - Describe both CV field and CV Term field. + $widget['ap_fieldset']['ap_describe'] = array( + '#type' => 'item', + '#title' => t('CV and Term'), + '#description' => t('Select CV and Term to change the ontology term for this trait.'), + ); - $widget['chado-cvterm_relationship__object_id'] = array( - '#type' => 'value', - '#value' => $items[$delta]['chado-cvterm_relationship__object_id'], - ); + // MARKUP - AJAX response wrapper. Update CV id filter in autocomplete field below. + $widget['ap_fieldset']['ap_ajax_response'] = array( + '#prefix' => '
', + '#suffix' => '
', + ); - $widget['chado-cvterm_relationship__subject_id'] = array( - '#type' => 'value', - '#value' => $items[$delta]['chado-cvterm_relationship__subject_id'], - ); + // FIELD SELECT - Select CV. + $widget['ap_fieldset']['ap_ajax_response']['ap_source_cv'] = array( + '#type' => 'select', + '#options' => $vocs, + '#theme_wrappers' => array(), + '#ajax' => array( + 'callback' => 'analyzedphentypes_synonym_callback', + 'wrapper' => 'ap-ajax-response', + 'method' => 'replace', + ), + ); - $widget['new_term'] = array( - '#type' => 'select', - '#title' => 'Trait Ontology', - '#options' => array(4010=>'Subset Traits: # Pods (count)', 6086 => 'Chickpea Traits', 5705 => 'Lentil Traits'), - //'#autocomplete_path' => 'admin/tripal/storage/chado/auto_name/cvterm/2', - '#default_value' => $m->subject_id, - ); + // FIELD AUTOCOMPLETE - Search term in a CV. + $widget['ap_fieldset']['ap_ajax_response']['ap_ontology_term'] = array( + '#type' => 'textfield', + '#size' => 60, + '#autocomplete_path' => 'admin/tripal/storage/chado/auto_name/cvterm/' . $cv_id, + '#disabled' => TRUE, + '#theme_wrappers' => array(), + '#attributes' => array( + 'style' => 'margin: 0 10px;' + ), + ); + + if (isset($cv_id)) { + // Enable field when a cv selected. + $widget['ap_fieldset']['ap_ajax_response']['ap_ontology_term']['#disabled'] = FALSE; + } + } } /** @@ -134,16 +194,46 @@ class ncit__synonym_widget extends TripalFieldWidget { public function validate($element, $form, &$form_state, $langcode, $delta) { $field_name = $this->field['field_name']; + if (isset($form_state['values'][$field_name][$langcode][$delta])) { + $form_values = $form_state['values'][$field_name][$langcode][$delta]; + + if (isset($form_values['ap_fieldset']['ap_ajax_response']['ap_source_cv']) + && isset($form_values['ap_fieldset']['ap_ajax_response']['ap_ontology_term'])) { + + $termprop = chado_generate_var('cvterm', array( + 'cv_id' => $form_values['ap_fieldset']['ap_ajax_response']['ap_source_cv'], + 'name' => $form_values['ap_fieldset']['ap_ajax_response']['ap_ontology_term'], + )); + + if ($termprop && $termprop->cvterm_id > 0) { + // Term is valid. + + // From this point on, set the chado_table settings to cvterm_relationship from cvterm. + $this->instance['settings']['chado_table'] = 'cvterm_relationship'; + $field_table = $this->instance['settings']['chado_table']; - /////////////// - $this->instance['settings']['chado_table'] = 'cvterm_relationship'; - $field_table = $this->instance['settings']['chado_table']; - $form_state['values'][$field_name][$langcode][$delta]['value'] = $form_state['values'][$field_name][$langcode][$delta]['value']; - $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__cvterm_relationship_id'] = $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__cvterm_relationship_id']; - $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__object_id'] = $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__object_id']; - $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__subject_id'] = $form_state['values'][$field_name][$langcode][$delta]['new_term']; - $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__type_id'] = $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__type_id']; + // Create or Update? + + if (empty($form_values['value'])) { + // Create. + $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__object_id'] = $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__object_id']; + $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__type_id'] = $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__type_id']; + + // As entered in the autocomplete field. + $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__subject_id'] = $termprop->cvterm_id; + } + else { + // Update. + // As entered in the autocomplete field. + $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__subject_id'] = $termprop->cvterm_id; + } + + // After create or update, restore chado_table setting to original value (cvterm). + $this->instance['settings']['chado_table'] = 'cvterm'; + } + } + } } /** @@ -184,3 +274,22 @@ class ncit__synonym_widget extends TripalFieldWidget { public function submit($form, &$form_state, $entity_type, $entity, $langcode, $delta) { } } + + +/** + * Function callback - AJAX response. + * @credits to Tripal developer - sbo relationship. + */ +function analyzedphentypes_synonym_callback($form, $form_state) { + // Get the triggering element + $form_element_name = $form_state['triggering_element']['#name']; + preg_match('/(.+?)\[(.+?)\]\[(.+?)\]/', $form_element_name, $matches); + $field = $matches[1]; + $lang = $matches[2]; + $delta = $matches[3]; + + // Return the widget that triggered the AJAX call, but only the ontology section. + if (isset($form[$field][$lang][$delta])) { + return $form[$field][$lang][$delta]['ap_fieldset']['ap_ajax_response']; + } +} From 5bd2c986fef0d083be378c9b6d4738e79c1b39ea Mon Sep 17 00:00:00 2001 From: Reynold Tan Date: Wed, 3 Jul 2019 10:43:42 -0600 Subject: [PATCH 5/8] Ready for review --- .../ncit__synonym/ncit__synonym.inc | 42 +++++-- .../ncit__synonym/ncit__synonym_formatter.inc | 14 ++- .../ncit__synonym/ncit__synonym_widget.inc | 117 ++++++++++++------ .../ncit__synonym/theme/.DS_Store | Bin 0 -> 6148 bytes .../theme/style_cp_synonym_field.css | 27 ++++ 5 files changed, 145 insertions(+), 55 deletions(-) create mode 100644 includes/TripalFields/ncit__synonym/theme/.DS_Store create mode 100644 includes/TripalFields/ncit__synonym/theme/style_cp_synonym_field.css diff --git a/includes/TripalFields/ncit__synonym/ncit__synonym.inc b/includes/TripalFields/ncit__synonym/ncit__synonym.inc index d7e9557..999e606 100644 --- a/includes/TripalFields/ncit__synonym/ncit__synonym.inc +++ b/includes/TripalFields/ncit__synonym/ncit__synonym.inc @@ -127,6 +127,10 @@ class ncit__synonym extends ChadoField { $sysvar_related = variable_get($sysvar); if ($sysvar_related) { + // Inspect to see if this trait has crop ontology set in chado.cvterm_relationship + // using what is known - type_id of ontology Related (in configuration) and the object_id + // which is the current trait. + $identifiers = array( 'column' => array('cvterm_relationship_id', 'subject_id'), 'value' => array('type_id' => $sysvar_related, 'object_id' => $record) @@ -134,31 +138,43 @@ class ncit__synonym extends ChadoField { $rel = chado_select_record('cvterm_relationship', $identifiers['column'], $identifiers['value']); $field_name = $this->field['field_name']; - $field_table = 'cvterm_relationship'; + $field_table = 'chado-cvterm_relationship__'; if ($rel) { // Has crop ontology. // For chado mechnanism. $entity->{$field_name}['und'][0] = array( - 'chado-' . $field_table . '__cvterm_relationship_id' => $rel[0]->cvterm_relationship_id, - 'chado-' . $field_table . '__type_id' => $sysvar_related, - 'chado-' . $field_table . '__object_id' => $entity->chado_record_id, - 'chado-' . $field_table . '__subject_id' => $rel[0]->subject_id + // Row id #. + $field_table . 'cvterm_relationship_id' => $rel[0]->cvterm_relationship_id, + // Relationship details. + $field_table . 'type_id' => $sysvar_related, + $field_table . 'object_id' => $entity->chado_record_id, + $field_table . 'subject_id' => $rel[0]->subject_id ); // For end user. - $relationship_term = tripal_get_chado_semweb_term('cvterm_relationship', 'subject_id'); - - $traitprop = ap_get_cvterm( - array('cvterm_id' => $record), - array('dataset' => 'fullset') - ); - - $entity->{$field_name}['und'][0]['value'][ $relationship_term ] = $traitprop[0]['crop_ontology']; + // Sending the term, accession and cv name. Last two items are used to constuct + // direct link to vocabulary lookup to a more details about a term. + $termprop = chado_generate_var('cvterm', array( + 'cvterm_id' => $rel[0]->subject_id + )); + + // Term. + $relationship_term = tripal_get_chado_semweb_term('cvterm_relationship', 'subject_id'); + $entity->{$field_name}['und'][0]['value'][ $relationship_term ] = $termprop->name; + + // Accession. + $accession = tripal_get_chado_semweb_term('dbxref', 'accession'); + $entity->{$field_name}['und'][0]['value'][ $accession ] = $termprop->dbxref_id->accession; + + // CV. + $cv_term = tripal_get_chado_semweb_term('cv', 'name'); + $entity->{$field_name}['und'][0]['value'][ $cv_term ] = $termprop->cv_id->name; } else { // Crop ontology not set. + // Nothing here, just forward what we know so far, Related term and the trait id. $entity->{$field_name}['und'][0] = array( 'value' => array(), 'chado-' . $field_table . '__object_id' => $entity->chado_record_id, diff --git a/includes/TripalFields/ncit__synonym/ncit__synonym_formatter.inc b/includes/TripalFields/ncit__synonym/ncit__synonym_formatter.inc index ca7133b..7be8301 100644 --- a/includes/TripalFields/ncit__synonym/ncit__synonym_formatter.inc +++ b/includes/TripalFields/ncit__synonym/ncit__synonym_formatter.inc @@ -44,11 +44,23 @@ class ncit__synonym_formatter extends TripalFieldFormatter { * hook_field_formatter_view() function. */ public function view(&$element, $entity_type, $entity, $langcode, $items, $display) { + // No show when no crop ontology for a trait. + $element = null; + // Render crop ontology for this trait. if ($items[0]['value']) { + // Style information. + drupal_add_css(drupal_get_path('module', 'analyzedphenotypes') . '/includes/TripalFields/ncit__synonym/theme/style_cp_synonym_field.css'); + + // Refer to this ID for CSS styling. + $id = 'ap-field-crop_ontology_synonym'; + + list($term, $accession, $cv) = array_values($items[0]['value']); + $cvterm_lookup = l('Vocabulary Details', 'cv/lookup/' . $cv . '/' . $accession, array('attributes' => array('target' => '_blank'))); + $element[0] = array( '#type' => 'markup', - '#markup' => current($items[0]['value']), + '#markup' => '
' . $term . '
' . $cvterm_lookup, ); } diff --git a/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc b/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc index 2b0f475..fcf070a 100644 --- a/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc +++ b/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc @@ -83,6 +83,8 @@ class ncit__synonym_widget extends TripalFieldWidget { // Elements of chado.cvterm_relationship table: $chado_table = 'chado-cvterm_relationship__'; + + // FOR CHADO MECHNANISM: // Column - cvterm_relationship_id primary key. $widget['value'] = array( '#type' => 'value', @@ -115,10 +117,25 @@ class ncit__synonym_widget extends TripalFieldWidget { '#value' => $items[$delta][ $chado_table . 'type_id' ], ); - // FORM ELEMENTS: + + // CURRENT SETTINGS: + // Style information. + drupal_add_css(drupal_get_path('module', 'analyzedphenotypes') . '/includes/TripalFields/ncit__synonym/theme/style_cp_synonym_field.css'); + // Current crop ontology. - $relationship_term = tripal_get_chado_semweb_term('cvterm_relationship', 'subject_id'); - $ontology = $items[$delta]['value'][ $relationship_term ] ?? 'Crop ontology not set'; + list($term, $accession, $cv) = array_values($items[0]['value']); + + if (empty($term)) { + $crop_ontology = 'Crop ontology not set '; + $cvterm_lookup = ''; + } + else { + // Refer to this ID for CSS styling. + $id = 'ap-field-crop_ontology_synonym'; + + $crop_ontology = '
' . $term . '
'; + $cvterm_lookup = l('Vocabulary Details', 'cv/lookup/' . $cv . '/' . $accession, array('attributes' => array('target' => '_blank'))) . ' | '; + } // FIELDSET - Main fieldset - search ontology terms. $widget['ap_fieldset'] = array( @@ -129,9 +146,12 @@ class ncit__synonym_widget extends TripalFieldWidget { // MARKUP - Show current record if any. $widget['ap_fieldset']['ap_ontology'] = array( '#type' => 'markup', - '#markup' => '

' . $ontology . '

', + '#markup' => $crop_ontology . $cvterm_lookup . l('Update term', '#', array('attributes' => array('class' => 'ap-link-form-revel'))), ); + + // FORM ELEMENTS: + // @credits to Tripal developer - sbo relationship. $vocs = []; $vocs = chado_get_cv_select_options(); $cv_id = isset($form_state['values'][$field_name][$langcode][$delta]['ap_fieldset']['ap_ajax_response']['ap_source_cv']) @@ -142,43 +162,55 @@ class ncit__synonym_widget extends TripalFieldWidget { '#type' => 'item', '#title' => t('CV and Term'), '#description' => t('Select CV and Term to change the ontology term for this trait.'), + // + // Wrap. + '#prefix' => '
', ); - // MARKUP - AJAX response wrapper. Update CV id filter in autocomplete field below. - $widget['ap_fieldset']['ap_ajax_response'] = array( - '#prefix' => '
', - '#suffix' => '
', - ); - - - // FIELD SELECT - Select CV. - $widget['ap_fieldset']['ap_ajax_response']['ap_source_cv'] = array( - '#type' => 'select', - '#options' => $vocs, - '#theme_wrappers' => array(), - '#ajax' => array( - 'callback' => 'analyzedphentypes_synonym_callback', - 'wrapper' => 'ap-ajax-response', - 'method' => 'replace', - ), - ); - - // FIELD AUTOCOMPLETE - Search term in a CV. - $widget['ap_fieldset']['ap_ajax_response']['ap_ontology_term'] = array( - '#type' => 'textfield', - '#size' => 60, - '#autocomplete_path' => 'admin/tripal/storage/chado/auto_name/cvterm/' . $cv_id, - '#disabled' => TRUE, - '#theme_wrappers' => array(), - '#attributes' => array( - 'style' => 'margin: 0 10px;' - ), - ); - - if (isset($cv_id)) { - // Enable field when a cv selected. - $widget['ap_fieldset']['ap_ajax_response']['ap_ontology_term']['#disabled'] = FALSE; - } + // MARKUP - AJAX response wrapper. Update CV id filter in autocomplete field below. + $widget['ap_fieldset']['ap_ajax_response'] = array( + '#prefix' => '
', + '#suffix' => '
', + ); + + // FIELD SELECT - Select CV. + $widget['ap_fieldset']['ap_ajax_response']['ap_source_cv'] = array( + '#type' => 'select', + '#options' => $vocs, + '#theme_wrappers' => array(), + '#ajax' => array( + 'callback' => 'analyzedphentypes_synonym_callback', + 'wrapper' => 'ap-ajax-response', + 'method' => 'replace', + ), + ); + + // FIELD AUTOCOMPLETE - Search term in a CV. + $widget['ap_fieldset']['ap_ajax_response']['ap_ontology_term'] = array( + '#type' => 'textfield', + '#size' => 60, + '#autocomplete_path' => 'admin/tripal/storage/chado/auto_name/cvterm/' . $cv_id, + '#disabled' => TRUE, + '#theme_wrappers' => array(), + '#attributes' => array('style' => 'margin: 0 10px;'), + // + // Wrap. + '#suffix' => '
', + ); + + if (isset($cv_id)) { + // Enable field when a cv selected. + $widget['ap_fieldset']['ap_ajax_response']['ap_ontology_term']['#disabled'] = FALSE; + } + + // Listen to link to update ontology term. + drupal_add_js("jQuery('.ap-link-form-revel').click(function(e) { + e.preventDefault(); + jQuery('#ap-crop-ontology-form-fields').fadeIn(); + })", array('type' => 'inline', 'scope' => 'footer')); + } + else { + drupal_set_message('Crop ontology configuration can only be set to a single value. Please set the allowed value to one in mange field.', 'warning'); } } @@ -217,8 +249,11 @@ class ncit__synonym_widget extends TripalFieldWidget { if (empty($form_values['value'])) { // Create. - $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__object_id'] = $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__object_id']; - $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__type_id'] = $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__type_id']; + $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__object_id'] + = $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__object_id']; + + $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__type_id'] + = $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__type_id']; // As entered in the autocomplete field. $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__subject_id'] = $termprop->cvterm_id; diff --git a/includes/TripalFields/ncit__synonym/theme/.DS_Store b/includes/TripalFields/ncit__synonym/theme/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..b21d3a41c40c7013b11eb5437fc7b4cd6a3f4342 GIT binary patch literal 6148 zcmeHKJx{|x41IAKvL*Z7 z`TXvZH^eyrvOMgrfdzm$T@mjZrl#xa6FZ5F5b50G5%<{Qm9d*t|DI6p1*_lCqZ#pg z?9tMDyl}rKJae_d4p%&(LwDP>+fCDM$k&Izp${qynixDv%1K0>>24-bCjnmCo{REaBwIGy3%!#(*^B;9Z$6T+0gQL-zH##wY1XP!_RNyZZ F_yjABA)WvL literal 0 HcmV?d00001 diff --git a/includes/TripalFields/ncit__synonym/theme/style_cp_synonym_field.css b/includes/TripalFields/ncit__synonym/theme/style_cp_synonym_field.css new file mode 100644 index 0000000..83fa488 --- /dev/null +++ b/includes/TripalFields/ncit__synonym/theme/style_cp_synonym_field.css @@ -0,0 +1,27 @@ +/** + * @file + * Style NCIT synonym - crop ontology. + */ + +/* Term wrapper */ +#ap-field-crop_ontology_synonym { + background-color: #3A7f21; + color: #FFFFFF; + display: inline-block; + font-family: sans-serif; + margin-right: 20px; + padding: 10px; + + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + + letter-spacing: 1px; + word-spacing: 1px; +} + +/* Update ontology formset wrapper */ +#ap-crop-ontology-form-fields { + display: none; + margin: 15px 0 0 0; +} From f2fa2ce28e6ad4637c95c23515df0f032559a329 Mon Sep 17 00:00:00 2001 From: Reynold Tan Date: Wed, 3 Jul 2019 13:45:12 -0600 Subject: [PATCH 6/8] Limit # of allowed values --- .../ncit__synonym/ncit__synonym_widget.inc | 10 +++++----- .../ncit__synonym/theme/style_cp_synonym_field.css | 5 +++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc b/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc index fcf070a..dd0e944 100644 --- a/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc +++ b/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc @@ -71,12 +71,12 @@ class ncit__synonym_widget extends TripalFieldWidget { * $delta above */ public function form(&$widget, &$form, &$form_state, $langcode, $items, $delta, $element) { - if (count($delta) == 1) { + parent::form($widget, $form, $form_state, $langcode, $items, $delta, $element); + + if ($delta == 0) { // By the default, field allows for multiple/unlimited values to be entered. AP only // supports 1 and only 1 crop ontology term per trait name. - parent::form($widget, $form, $form_state, $langcode, $items, $delta, $element); - // Field name. $field_name = $this->field['field_name']; @@ -126,7 +126,7 @@ class ncit__synonym_widget extends TripalFieldWidget { list($term, $accession, $cv) = array_values($items[0]['value']); if (empty($term)) { - $crop_ontology = 'Crop ontology not set '; + $crop_ontology = 'Crop ontology not set | '; $cvterm_lookup = ''; } else { @@ -210,7 +210,7 @@ class ncit__synonym_widget extends TripalFieldWidget { })", array('type' => 'inline', 'scope' => 'footer')); } else { - drupal_set_message('Crop ontology configuration can only be set to a single value. Please set the allowed value to one in mange field.', 'warning'); + drupal_set_message('Crop ontology configuration can only be set to a single value. Please set the allowed value to one in mange field.', 'warning', FALSE); } } diff --git a/includes/TripalFields/ncit__synonym/theme/style_cp_synonym_field.css b/includes/TripalFields/ncit__synonym/theme/style_cp_synonym_field.css index 83fa488..2cc13bc 100644 --- a/includes/TripalFields/ncit__synonym/theme/style_cp_synonym_field.css +++ b/includes/TripalFields/ncit__synonym/theme/style_cp_synonym_field.css @@ -5,12 +5,13 @@ /* Term wrapper */ #ap-field-crop_ontology_synonym { - background-color: #3A7f21; + background-color: #3A7F21; color: #FFFFFF; display: inline-block; font-family: sans-serif; + font-weight: 300; margin-right: 20px; - padding: 10px; + padding: 5px 7px; -webkit-border-radius: 5px; -moz-border-radius: 5px; From 3f201146994567fd7b873600e82f0bbd5b8e7635 Mon Sep 17 00:00:00 2001 From: Reynold Tan Date: Wed, 3 Jul 2019 14:19:19 -0600 Subject: [PATCH 7/8] Bug fix - undefined index when no crop ontology set --- .../TripalFields/ncit__synonym/ncit__synonym.inc | 4 ++-- .../ncit__synonym/ncit__synonym_widget.inc | 13 ++++++------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/includes/TripalFields/ncit__synonym/ncit__synonym.inc b/includes/TripalFields/ncit__synonym/ncit__synonym.inc index 999e606..fd5580d 100644 --- a/includes/TripalFields/ncit__synonym/ncit__synonym.inc +++ b/includes/TripalFields/ncit__synonym/ncit__synonym.inc @@ -177,8 +177,8 @@ class ncit__synonym extends ChadoField { // Nothing here, just forward what we know so far, Related term and the trait id. $entity->{$field_name}['und'][0] = array( 'value' => array(), - 'chado-' . $field_table . '__object_id' => $entity->chado_record_id, - 'chado-' . $field_table . '__type_id' => $sysvar_related, + $field_table . 'object_id' => $entity->chado_record_id, + $field_table . 'type_id' => $sysvar_related, ); } } diff --git a/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc b/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc index dd0e944..946ff97 100644 --- a/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc +++ b/includes/TripalFields/ncit__synonym/ncit__synonym_widget.inc @@ -123,19 +123,18 @@ class ncit__synonym_widget extends TripalFieldWidget { drupal_add_css(drupal_get_path('module', 'analyzedphenotypes') . '/includes/TripalFields/ncit__synonym/theme/style_cp_synonym_field.css'); // Current crop ontology. - list($term, $accession, $cv) = array_values($items[0]['value']); - - if (empty($term)) { - $crop_ontology = 'Crop ontology not set | '; - $cvterm_lookup = ''; - } - else { + if (count($items[0]['value']) > 0) { + @list($term, $accession, $cv) = array_values($items[0]['value']); // Refer to this ID for CSS styling. $id = 'ap-field-crop_ontology_synonym'; $crop_ontology = '
' . $term . '
'; $cvterm_lookup = l('Vocabulary Details', 'cv/lookup/' . $cv . '/' . $accession, array('attributes' => array('target' => '_blank'))) . ' | '; } + else { + $crop_ontology = 'Crop ontology not set | '; + $cvterm_lookup = ''; + } // FIELDSET - Main fieldset - search ontology terms. $widget['ap_fieldset'] = array( From f3d8b50f486793febcf38e509dbb5a4a54657921 Mon Sep 17 00:00:00 2001 From: Reynold Tan Date: Wed, 3 Jul 2019 15:31:39 -0600 Subject: [PATCH 8/8] Added a check to see if term can be search in term lookup module before supplying a link to vocab details --- .../ncit__synonym/ncit__synonym_formatter.inc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/includes/TripalFields/ncit__synonym/ncit__synonym_formatter.inc b/includes/TripalFields/ncit__synonym/ncit__synonym_formatter.inc index 7be8301..50b6bb7 100644 --- a/includes/TripalFields/ncit__synonym/ncit__synonym_formatter.inc +++ b/includes/TripalFields/ncit__synonym/ncit__synonym_formatter.inc @@ -56,7 +56,15 @@ class ncit__synonym_formatter extends TripalFieldFormatter { $id = 'ap-field-crop_ontology_synonym'; list($term, $accession, $cv) = array_values($items[0]['value']); - $cvterm_lookup = l('Vocabulary Details', 'cv/lookup/' . $cv . '/' . $accession, array('attributes' => array('target' => '_blank'))); + + // If we can't find the term then do not provide the link as it will just cause a term not found + // in the term lookup module. + // @see tripal_vocabulary_lookup_term_page() + // Tripal.term_lookup.inc. + $lookterm = tripal_get_term_details($cv, $accession); + + $cvterm_lookup = (!$lookterm) ? '' + : l('Vocabulary Details', 'cv/lookup/' . $cv . '/' . $accession, array('attributes' => array('target' => '_blank'))); $element[0] = array( '#type' => 'markup',