|
@@ -17,44 +17,54 @@ function tripal_entities_field_storage_info() {
|
|
|
*/
|
|
|
function tripal_entities_field_storage_write($entity_type, $entity, $op, $fields) {
|
|
|
|
|
|
- switch ($op) {
|
|
|
- case FIELD_STORAGE_INSERT:
|
|
|
- // Use the cvterm_id to look up tables where this term is used
|
|
|
- $sel_values = array(
|
|
|
- 'term_id' => array(
|
|
|
- 'cvterm_id' => $entity->cvterm_id,
|
|
|
- ),
|
|
|
- );
|
|
|
- $term_usage = chado_generate_var('tripal_term_usage', $sel_values, array('return_array' => 1));
|
|
|
+ // Conver the fields into a key/value list of fields and their values.
|
|
|
+ $field_vals = tripal_entities_field_storage_reformat_fields($fields, $entity_type, $entity);
|
|
|
+ $transaction = db_transaction();
|
|
|
+ try {
|
|
|
+ switch ($op) {
|
|
|
+ case FIELD_STORAGE_INSERT:
|
|
|
+ // Use the cvterm_id to look up tables where this term is used
|
|
|
+ $sel_values = array(
|
|
|
+ 'term_id' => array(
|
|
|
+ 'cvterm_id' => $entity->cvterm_id,
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ $term_usage = chado_generate_var('tripal_term_usage', $sel_values, array('return_array' => 1));
|
|
|
|
|
|
- // For each table that uses this term, insert the field recursively
|
|
|
- foreach ($term_usage as $usage) {
|
|
|
- $data_table = $usage->data_table;
|
|
|
- //$type_table = $usage->type_table;
|
|
|
- $type_field = $usage->field;
|
|
|
- tripal_entities_field_storage_write_recursive($entity_type, $entity,
|
|
|
- $op, $fields, $data_table, $type_field);
|
|
|
- }
|
|
|
- break;
|
|
|
+ // For each table that uses this term, insert the field recursively
|
|
|
+ foreach ($term_usage as $usage) {
|
|
|
+ $data_table = $usage->data_table;
|
|
|
+ //$type_table = $usage->type_table;
|
|
|
+ $type_field = $usage->field;
|
|
|
+ tripal_entities_field_storage_write_recursive($entity_type, $entity,
|
|
|
+ $op, $field_vals, $data_table, $type_field);
|
|
|
+ }
|
|
|
+ break;
|
|
|
|
|
|
- case FIELD_STORAGE_UPDATE :
|
|
|
+ case FIELD_STORAGE_UPDATE :
|
|
|
|
|
|
- // Get the base table and record id for the fields of this entity.
|
|
|
- $details = db_select('chado_entity', 'ce')
|
|
|
- ->fields('ce')
|
|
|
- ->condition('entity_id', $entity->id)
|
|
|
- ->execute()
|
|
|
- ->fetchObject();
|
|
|
- $tablename = $details->data_table;
|
|
|
- $type_field = $details->field;
|
|
|
- $record_id = $details->record_id;
|
|
|
+ // Get the base table and record id for the fields of this entity.
|
|
|
+ $details = db_select('chado_entity', 'ce')
|
|
|
+ ->fields('ce')
|
|
|
+ ->condition('entity_id', $entity->id)
|
|
|
+ ->execute()
|
|
|
+ ->fetchObject();
|
|
|
+ $tablename = $details->data_table;
|
|
|
+ $type_field = $details->field;
|
|
|
+ $record_id = $details->record_id;
|
|
|
|
|
|
- tripal_entities_field_storage_write_recursive($entity_type, $entity,
|
|
|
- $op, $fields, $tablename, $type_field, $record_id);
|
|
|
- if (!$details) {
|
|
|
- // TODO: what to do if record is missing!
|
|
|
- }
|
|
|
- break;
|
|
|
+ tripal_entities_field_storage_write_recursive($entity_type, $entity,
|
|
|
+ $op, $field_vals, $tablename, $type_field, $record_id);
|
|
|
+ if (!$details) {
|
|
|
+ // TODO: what to do if record is missing!
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Exception $e) {
|
|
|
+ $transaction->rollback();
|
|
|
+ watchdog_exception('tripal_feature', $e);
|
|
|
+ drupal_set_message('Could not write record to Chado. See recent logs', 'error');
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -62,7 +72,7 @@ function tripal_entities_field_storage_write($entity_type, $entity, $op, $fields
|
|
|
* Implements hook_field_storage_write_recursive().
|
|
|
*/
|
|
|
function tripal_entities_field_storage_write_recursive($entity_type, $entity,
|
|
|
- $op, $fields, $tablename, $type_field = NULL, $record_id = NULL, $depth = 0) {
|
|
|
+ $op, $field_vals, $tablename, $type_field = NULL, $record_id = NULL, $depth = 0) {
|
|
|
|
|
|
// Intialize the values array and $record_id;
|
|
|
$values = array();
|
|
@@ -89,24 +99,13 @@ function tripal_entities_field_storage_write_recursive($entity_type, $entity,
|
|
|
// loop through the $fk_fields again.
|
|
|
$fkey_fields_list[] = $local_id;
|
|
|
|
|
|
- // Recurse differently if this is an insert or an update.
|
|
|
+ // Recurse on the FK field. Pass in the ID for the FK field if one
|
|
|
+ // exists in the $field_vals;
|
|
|
$fk_val = NULL;
|
|
|
- switch ($op) {
|
|
|
- case FIELD_STORAGE_INSERT:
|
|
|
- // On an insert we do not pass in a $record_id because
|
|
|
- // we don't have any.
|
|
|
- $fk_val = tripal_entities_field_storage_write_recursive($entity_type,
|
|
|
- $entity, $op, $fields, $fk_table, NULL, NULL, $depth + 1);
|
|
|
- break;
|
|
|
- case FIELD_STORAGE_UPDATE:
|
|
|
- // On an update we must get the value of the FK field. This should
|
|
|
- // be present as a field, so get it's value and pass it in as the
|
|
|
- // $record_id field.
|
|
|
- $fk_val = tripal_entities_get_field_value($tablename . '__' . $local_id, $entity, $entity_type);
|
|
|
- $fk_val = tripal_entities_field_storage_write_recursive($entity_type,
|
|
|
- $entity, $op, $fields, $fk_table, NULL, $fk_val, $depth + 1);
|
|
|
- break;
|
|
|
- }
|
|
|
+ $fk_field_name = $tablename . '__' . $local_id;
|
|
|
+ $fk_val = array_key_exists($fk_field_name, $field_vals) ? $field_vals[$fk_field_name] : NULL;
|
|
|
+ $fk_val = tripal_entities_field_storage_write_recursive($entity_type,
|
|
|
+ $entity, $op, $field_vals, $fk_table, NULL, $fk_val, $depth + 1);
|
|
|
if ($fk_val) {
|
|
|
$values[$local_id] = $fk_val;
|
|
|
}
|
|
@@ -116,95 +115,71 @@ function tripal_entities_field_storage_write_recursive($entity_type, $entity,
|
|
|
// STEP 2: Loop through the incoming fields.
|
|
|
// Loop through the fields passed to the function and find any that
|
|
|
// are for this table. Then add their values to the $values array.
|
|
|
- foreach ($fields as $field_id) {
|
|
|
- $field = field_info_field_by_id($field_id);
|
|
|
- $field_name = $field['field_name'];
|
|
|
-
|
|
|
+ foreach ($field_vals as $field_name => $field_val) {
|
|
|
+ // If the field value is empty then continue.
|
|
|
+ if (!$field_val) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
if (preg_match('/^' . $tablename . '__(.*)/', $field_name, $matches)) {
|
|
|
$chado_field = $matches[1];
|
|
|
|
|
|
+ // Skip the Pkey field. We won't ever insert a primary key and if
|
|
|
+ // one is provided in the fields then we use it for matching on an
|
|
|
+ // update. We don't add it to the $values array in either case.
|
|
|
+ if ($chado_field == $pkey_field) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
// Skip FK fields as those should already have been dealt with the
|
|
|
// recursive code above.
|
|
|
- if (in_array($field_id, $fkey_fields_list)) {
|
|
|
+ if (in_array($chado_field, $fkey_fields_list)) {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
// Add the value of the field to the $values arr for later insert/update.
|
|
|
- $values[$chado_field] = tripal_entities_get_field_value($tablename . '__' . $chado_field, $entity, $entity_type);
|
|
|
+ $values[$chado_field] = $field_vals[$field_name];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// STEP 3: Insert/Update the record.
|
|
|
// If there are no values then return.
|
|
|
- $entity->storage = array();
|
|
|
- switch ($op) {
|
|
|
- case FIELD_STORAGE_INSERT:
|
|
|
- if (count($values) == 0) {
|
|
|
- return NULL;
|
|
|
- }
|
|
|
- // Inser the values array as a new record in the table.
|
|
|
- $record = chado_insert_record($tablename, $values);
|
|
|
- if ($record === FALSE) {
|
|
|
- drupal_set_message('Could not insert Chado record.', 'error');
|
|
|
- }
|
|
|
- $record_id = $record[$pkey_field];
|
|
|
-
|
|
|
- // Add a record to the chado_entity table so that the data for the
|
|
|
- // fields can be pulled from Chado when loaded the next time. Only do
|
|
|
- // this for the base table record.
|
|
|
- if ($depth == 0) {
|
|
|
- $record = array(
|
|
|
- 'entity_id' => $entity->id,
|
|
|
- 'record_id' => $record_id,
|
|
|
- 'data_table' => $tablename,
|
|
|
- 'type_table' => $tablename, // TODO: this must be fixed.
|
|
|
- 'field' => $type_field,
|
|
|
- );
|
|
|
- $success = drupal_write_record('chado_entity', $record);
|
|
|
- if (!$success) {
|
|
|
- drupal_set_message('Unable to insert new data.', 'error');
|
|
|
- }
|
|
|
- }
|
|
|
- break;
|
|
|
- case FIELD_STORAGE_UPDATE:
|
|
|
- // If we don't have any values we are not going to update the
|
|
|
- // record because there is nothing to udpate, do just return the
|
|
|
- // record_id.
|
|
|
- if (count($values) == 0) {
|
|
|
- return $record_id;
|
|
|
- }
|
|
|
- $match[$pkey_field] = $record_id;
|
|
|
-
|
|
|
- chado_update_record($tablename, $match, $values);
|
|
|
- break;
|
|
|
+ if (count($values) == 0) {
|
|
|
+ return $record_id;
|
|
|
}
|
|
|
- return $record_id;
|
|
|
-}
|
|
|
+ // If we don't have an incoming record ID then this is an insert.
|
|
|
+ if (!$record_id) {
|
|
|
+ // Insert the values array as a new record in the table.
|
|
|
+ $record = chado_insert_record($tablename, $values);
|
|
|
+ if ($record === FALSE) {
|
|
|
+ drupal_set_message('Could not insert Chado record into table, "$table".', 'error');
|
|
|
+ }
|
|
|
+ $record_id = $record[$pkey_field];
|
|
|
|
|
|
-/**
|
|
|
- *
|
|
|
- */
|
|
|
-function tripal_entities_get_field_value($field_name, $entity, $entity_type) {
|
|
|
- $value = NULL;
|
|
|
- $field = field_info_field($field_name);
|
|
|
- if (!$field) {
|
|
|
- return $value;
|
|
|
+ // Add a record to the chado_entity table so that the data for the
|
|
|
+ // fields can be pulled from Chado when loaded the next time. Only do
|
|
|
+ // this for the base table record.
|
|
|
+ if ($depth == 0) {
|
|
|
+ $record = array(
|
|
|
+ 'entity_id' => $entity->id,
|
|
|
+ 'record_id' => $record_id,
|
|
|
+ 'data_table' => $tablename,
|
|
|
+ 'type_table' => $tablename, // TODO: this must be fixed.
|
|
|
+ 'field' => $type_field,
|
|
|
+ );
|
|
|
+ $success = drupal_write_record('chado_entity', $record);
|
|
|
+ if (!$success) {
|
|
|
+ drupal_set_message('Unable to insert new Chado entity.', 'error');
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- // Currently, we only support one language, but for for the sake of
|
|
|
- // thoroughness we'll iterate through all possible languages.
|
|
|
- $all_languages = field_available_languages($entity_type, $field);
|
|
|
- $field_languages = array_intersect($all_languages, array_keys((array) $entity->$field_name));
|
|
|
- foreach ($field_languages as $langcode) {
|
|
|
- $items = (array) $entity->{$field_name}[$langcode];
|
|
|
- // The number of items is related to the cardinatily of the field.
|
|
|
- // We should always only have one item because this is a field in a
|
|
|
- // table. But we loop anyway.
|
|
|
- foreach ($items as $delta => $item) {
|
|
|
- $value = $item['value'];
|
|
|
+ // We have an incoming record_id so this is an update.
|
|
|
+ else {
|
|
|
+ $match[$pkey_field] = $record_id;
|
|
|
+ if (!chado_update_record($tablename, $match, $values)) {
|
|
|
+ drupal_set_message('Could not update Chado record for in table, "$table".', 'error');
|
|
|
}
|
|
|
}
|
|
|
- return $value;
|
|
|
+ return $record_id;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -272,4 +247,44 @@ function tripal_entities_field_storage_load($entity_type, $entities, $age, $fiel
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Iterates through all of the fields reformats to a key/value array.
|
|
|
+ *
|
|
|
+ * @param $fields
|
|
|
+ */
|
|
|
+function tripal_entities_field_storage_reformat_fields($fields, $entity_type, $entity) {
|
|
|
+ $new_fields = array();
|
|
|
+ foreach ($fields as $field_id => $ids) {
|
|
|
+ $field = field_info_field_by_id($field_id);
|
|
|
+ $field_name = $field['field_name'];
|
|
|
+ // Currently, we only support one language, but for for the sake of
|
|
|
+ // thoroughness we'll iterate through all possible languages.
|
|
|
+ $all_languages = field_available_languages($entity_type, $field);
|
|
|
+ $field_languages = array_intersect($all_languages, array_keys((array) $entity->$field_name));
|
|
|
+ foreach ($field_languages as $langcode) {
|
|
|
+ $items = (array) $entity->{$field_name}[$langcode];
|
|
|
+ // The number of items is related to the cardinatily of the field.
|
|
|
+ // We should always only have one item because this is a field in a
|
|
|
+ // table. But we loop anyway.
|
|
|
+ foreach ($items as $delta => $item) {
|
|
|
+ // If the $value is an array then this field has nested fields. We
|
|
|
+ // want to add those to our $new_fields list.
|
|
|
+ if (is_array($item['value'])) {
|
|
|
+ foreach ($item['value'] as $children) {
|
|
|
+ foreach ($children as $child_field_name => $child_value) {
|
|
|
+ if (preg_match('/^.*?__.*?$/', $child_field_name)) {
|
|
|
+ $new_fields[$child_field_name] = $child_value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ $new_fields[$field_name] = $item['value'];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return $new_fields;
|
|
|
}
|