Skip to content

Commit

Permalink
Merge pull request #1599 from tripal/tv4g1-issue1414-ChadoContactDefault
Browse files Browse the repository at this point in the history
Tripal 4 ChadoContactDefault field
  • Loading branch information
dsenalik committed Sep 11, 2023
2 parents aadba17 + 3bdbabd commit e30f780
Show file tree
Hide file tree
Showing 8 changed files with 789 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ content_types:

- label: Array Design
term: EFO:0000269
help_text: Use the array design page to describe the systematic arrangement of similar objects, usually in rows and columns, used by intstrument to perform an assay.
help_text: Use the array design page to describe the systematic arrangement of similar objects, usually in rows and columns, used by an instrument to perform an assay.
category: Expression
id: array_design
title_format: "[array_design_name]"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,32 @@ fields:
region: content
weight: 15

- name: study_contact
content_type: study
label: Contact
type: chado_contact_default
description: An individual or organization that serves as a contact for this record.
cardinality: 1
required: true
storage_settings:
storage_plugin_id: chado_storage
storage_plugin_settings:
base_table: study
base_column: contact_id
settings:
termIdSpace: local
termAccession: contact
display:
view:
default:
region: content
label: above
weight: 20
form:
default:
region: content
weight: 20

- name: contact_name
content_type: contact
label: Name
Expand Down Expand Up @@ -3632,6 +3658,32 @@ fields:
weight: 25


- name: array_design_manufacturer
content_type: array_design
label: Manufacturer
type: chado_contact_default
description: A manufacturer's contact details
cardinality: 1
required: true
storage_settings:
storage_plugin_id: chado_storage
storage_plugin_settings:
base_table: arraydesign
base_column: manufacturer_id
settings:
termIdSpace: local
termAccession: contact
display:
view:
default:
region: content
label: above
weight: 10
form:
default:
region: content
weight: 10

- name: array_design_name
content_type: array_design
label: Name
Expand All @@ -3652,11 +3704,11 @@ fields:
default:
region: content
label: above
weight: 10
weight: 15
form:
default:
region: content
weight: 10
weight: 15

- name: array_design_version_num
content_type: array_design
Expand All @@ -3678,11 +3730,11 @@ fields:
default:
region: content
label: above
weight: 15
weight: 20
form:
default:
region: content
weight: 15
weight: 20

- name: array_design_description
content_type: array_design
Expand All @@ -3704,11 +3756,11 @@ fields:
default:
region: content
label: above
weight: 20
weight: 25
form:
default:
region: content
weight: 20
weight: 25

- name: array_design_dimensions
content_type: array_design
Expand All @@ -3730,11 +3782,11 @@ fields:
default:
region: content
label: above
weight: 25
weight: 30
form:
default:
region: content
weight: 25
weight: 30

- name: array_design_element_dims
content_type: array_design
Expand All @@ -3756,11 +3808,11 @@ fields:
default:
region: content
label: above
weight: 30
weight: 35
form:
default:
region: content
weight: 30
weight: 35

- name: array_design_substrate_type
content_type: array_design
Expand All @@ -3783,11 +3835,11 @@ fields:
default:
region: content
label: above
weight: 10
weight: 40
form:
default:
region: content
weight: 10
weight: 40

- name: array_design_platform_type
content_type: array_design
Expand All @@ -3810,8 +3862,8 @@ fields:
default:
region: content
label: above
weight: 10
weight: 45
form:
default:
region: content
weight: 10
weight: 45
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace Drupal\tripal_chado\Plugin\Field\FieldFormatter;

use Drupal\tripal\TripalField\TripalFormatterBase;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\tripal_chado\TripalField\ChadoFormatterBase;

/**
* Plugin implementation of default Tripal contact formatter.
*
* @FieldFormatter(
* id = "chado_contact_formatter_default",
* label = @Translation("Chado contact formatter"),
* description = @Translation("A chado contact formatter"),
* field_types = {
* "chado_contact_default"
* }
* )
*/
class ChadoContactFormatterDefault extends ChadoFormatterBase {

/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items, $langcode) {
$elements = [];

foreach($items as $delta => $item) {
$contact_name = $item->get('contact_name')->getString();
// Change the non-user-friendly 'null' contact, which is spedified by chado.
if ($contact_name == 'null') {
$contact_name = 'Unknown';
}
$elements[$delta] = [
"#markup" => $contact_name,
];
}

return $elements;
}
}
171 changes: 171 additions & 0 deletions tripal_chado/src/Plugin/Field/FieldType/ChadoContactDefault.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
<?php

namespace Drupal\tripal_chado\Plugin\Field\FieldType;

use Drupal\tripal_chado\TripalField\ChadoFieldItemBase;
use Drupal\tripal_chado\TripalStorage\ChadoVarCharStoragePropertyType;
use Drupal\tripal_chado\TripalStorage\ChadoIntStoragePropertyType;
use Drupal\tripal_chado\TripalStorage\ChadoTextStoragePropertyType;
use Drupal\tripal\TripalField\TripalFieldItemBase;
use Drupal\tripal\TripalStorage\StoragePropertyValue;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\core\Form\FormStateInterface;
use Drupal\core\Field\FieldDefinitionInterface;

/**
* Plugin implementation of Tripal Contact field type.
*
* @FieldType(
* id = "chado_contact_default",
* label = @Translation("Contact"),
* description = @Translation("An individual or organization that serves as a contact for this record"),
* default_widget = "chado_contact_widget_default",
* default_formatter = "chado_contact_formatter_default",
* cardinality = 1
* )
*/
class ChadoContactDefault extends ChadoFieldItemBase {

public static $id = 'chado_contact_default';

/**
* {@inheritdoc}
*/
public static function mainPropertyName() {
// Overrides the default of 'value'
return 'contact_name';
}

/**
* {@inheritdoc}
*/
public static function defaultFieldSettings() {
$settings = parent::defaultFieldSettings();
$settings['termIdSpace'] = 'local';
$settings['termAccession'] = 'contact';
return $settings;
}

/**
* {@inheritdoc}
*/
public static function defaultStorageSettings() {
$settings = parent::defaultStorageSettings();
return $settings;
}

/**
* {@inheritdoc}
*/
public function storageSettingsForm(array &$form, FormStateInterface $form_state, $has_data) {

$elements = parent::storageSettingsForm($form, $form_state, $has_data);
$storage_settings = $this->getSetting('storage_plugin_settings');
$base_table = $form_state->getValue(['settings', 'storage_plugin_settings', 'base_table']);

// Only present base tables that have a foreign key to contact.
$elements['storage_plugin_settings']['base_table']['#options'] = $this->getBaseTables('contact');
// Ugly special case for the arraydesign table where manufacturer_id is mapped to contact_id
$elements['storage_plugin_settings']['base_table']['#options']['arraydesign'] = 'arraydesign';

// Add a validation to make sure the base table has a foreign
// key to contact_id in the chado.contact table.
$elements['storage_plugin_settings']['base_table']['#element_validate'] = [[static::class, 'storageSettingsFormValidate']];
return $elements;
}

/**
* {@inheritdoc}
*/
public static function tripalTypes($field_definition) {
$entity_type_id = $field_definition->getTargetEntityTypeId();

// Get the Chado table and column this field maps to.
$storage_settings = $field_definition->getSetting('storage_plugin_settings');
$base_table = $storage_settings['base_table'];

// If we don't have a base table then we're not ready to specify the
// properties for this field.
if (!$base_table) {
$record_id_term = 'local:contact';
return [
new ChadoIntStoragePropertyType($entity_type_id, self::$id, 'record_id', $record_id_term, [
'action' => 'store_id',
'drupal_store' => TRUE,
])
];
}

// Get the connecting information for the foreign key from the
// base table to the contact table.
$chado = \Drupal::service('tripal_chado.database');
$schema = $chado->schema();
$base_table_def = $schema->getTableDef($base_table, ['format' => 'Drupal']);
$contact_table_def = $schema->getTableDef('contact', ['format' => 'Drupal']);
$base_pkey_col = $base_table_def['primary key'];
// Note that for the arraydesign table, this will be manufacturer_id instead of contact_id
$base_fkey_col = array_key_first($base_table_def['foreign keys']['contact']['columns']);

// Create variables to store the terms for the contact.
$storage = \Drupal::entityTypeManager()->getStorage('chado_term_mapping');
$mapping = $storage->load('core_mapping');
$record_id_term = 'SIO:000729';
$contact_id_term = $mapping->getColumnTermId('contact', 'contact_id');
$contact_name_term = $mapping->getColumnTermId('contact', 'name');
$contact_name_length = $contact_table_def['fields']['name']['size'];

// Define field properties, this is a simple lookup in the contact table
$properties = [];
$properties[] = new ChadoIntStoragePropertyType($entity_type_id, self::$id, 'record_id', $record_id_term, [
'action' => 'store_id',
'drupal_store' => TRUE,
'chado_table' => $base_table,
'chado_column' => $base_pkey_col,
]);
$properties[] = new ChadoIntStoragePropertyType($entity_type_id, self::$id, 'contact_id', $contact_id_term, [
'action' => 'store',
'chado_table' => $base_table,
'chado_column' => $base_fkey_col,
]);
$properties[] = new ChadoVarCharStoragePropertyType($entity_type_id, self::$id, 'contact_name', $contact_name_term, $contact_name_length, [
'action' => 'join',
'path' => $base_table . '.' . $base_fkey_col . '>contact.contact_id',
'chado_column' => 'name',
'as' => 'contact_name',
]);

return $properties;
}

/**
* Form element validation handler
*
* @param array $form
* The form where the settings form is being included in.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state of the (entire) configuration form.
*/
public static function storageSettingsFormValidate(array $form, FormStateInterface $form_state) {
$settings = $form_state->getValue('settings');
if (!array_key_exists('storage_plugin_settings', $settings)) {
return;
}

// Validation confirms that the base table has a foreign key
// to contact_id in the chado.contact table.
// This validation might be redundant, since we only present
// valid base tables to the user, but let's play it safe.
$base_table = $settings['storage_plugin_settings']['base_table'];
$chado = \Drupal::service('tripal_chado.database');
$schema = $chado->schema();
$base_table_def = $schema->getTableDef($base_table, ['format' => 'Drupal']);
$base_fkey_col = 'contact_id';
$fkeys = $base_table_def['foreign keys']['contact']['columns'] ?? [];
if (!in_array($base_fkey_col, $fkeys)) {
$form_state->setErrorByName('storage_plugin_settings][base_table',
'The selected base table does not have a foreign key to contact_id,'
. ' this field cannot be used on this content type.');
}
}

}

0 comments on commit e30f780

Please sign in to comment.