|  | @@ -33,22 +33,19 @@ function tripal_chado_field_storage_write($entity_type, $entity, $op, $fields) {
 | 
	
		
			
				|  |  |    $type_field = $entity->chado_column;
 | 
	
		
			
				|  |  |    $record     = $entity->chado_record;
 | 
	
		
			
				|  |  |    $record_id  = $entity->chado_record_id;
 | 
	
		
			
				|  |  | +  $base_schema = chado_get_schema($base_table);
 | 
	
		
			
				|  |  | +  $base_pkey = $base_schema['primary key'][0];
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    // Convert the fields into a key/value list of fields and their values.
 | 
	
		
			
				|  |  |    $field_vals = tripal_chado_field_storage_merge_fields($fields, $entity_type, $entity);
 | 
	
		
			
				|  |  | -dpm($field_vals);
 | 
	
		
			
				|  |  | -return;
 | 
	
		
			
				|  |  | -  // Write the record for the base table.
 | 
	
		
			
				|  |  | -  $record_id = tripal_chado_field_storage_write_table(array(
 | 
	
		
			
				|  |  | -    'entity' => $entity,
 | 
	
		
			
				|  |  | -    'term' => $term,
 | 
	
		
			
				|  |  | -    'op' => $op,
 | 
	
		
			
				|  |  | -    'field_vals' => $field_vals,
 | 
	
		
			
				|  |  | -    'base_table' => $base_table,
 | 
	
		
			
				|  |  | -    'tablename' => $base_table,
 | 
	
		
			
				|  |  | -    'type_field' => $type_field,
 | 
	
		
			
				|  |  | -    'record_id' => $record_id,
 | 
	
		
			
				|  |  | -  ));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // Write the record for the base table.  If this is an update then we'll have
 | 
	
		
			
				|  |  | +  // the record_id and we need to add that to our values array.
 | 
	
		
			
				|  |  | +  $values = $field_vals[$base_table][0];
 | 
	
		
			
				|  |  | +  if ($record_id) {
 | 
	
		
			
				|  |  | +    $values[$base_pkey] = $record_id;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  $base_record_id = tripal_chado_field_storage_write_table($base_table, $values);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    // If this is an insert then add the chado_entity record.
 | 
	
		
			
				|  |  |    if ($op == FIELD_STORAGE_INSERT) {
 | 
	
	
		
			
				|  | @@ -68,185 +65,108 @@ return;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    // Now that we have handled the base table, we need to handle linking tables.
 | 
	
		
			
				|  |  | -  foreach ($fields as $field_id) {
 | 
	
		
			
				|  |  | -    // Get the field using the id.
 | 
	
		
			
				|  |  | -    $field = field_info_field_by_id($field_id);
 | 
	
		
			
				|  |  | -    $field_name = $field['field_name'];
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    // If the field has a chado_table setting then we can try to write.
 | 
	
		
			
				|  |  | -    if (array_key_exists('settings', $field) and array_key_exists('chado_table', $field['settings'])) {
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -      // Skip fields that use the base table, as we've already handled those.
 | 
	
		
			
				|  |  | -      if ($field['settings']['chado_table'] != $base_table){
 | 
	
		
			
				|  |  | -        $field_table = $field['settings']['chado_table'];
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        // Iterate through each record.
 | 
	
		
			
				|  |  | -        if (array_key_exists($field_name, $field_vals)) {
 | 
	
		
			
				|  |  | -          foreach ($field_vals[$field_name] as $delta => $fvals) {
 | 
	
		
			
				|  |  | -            tripal_chado_field_storage_write_table(array(
 | 
	
		
			
				|  |  | -              'entity' => $entity,
 | 
	
		
			
				|  |  | -              'term' => $term,
 | 
	
		
			
				|  |  | -              'op' => $op,
 | 
	
		
			
				|  |  | -              'field_vals' => $fvals,
 | 
	
		
			
				|  |  | -              'base_table' => $base_table,
 | 
	
		
			
				|  |  | -              'tablename' => $field_table
 | 
	
		
			
				|  |  | -            ));
 | 
	
		
			
				|  |  | -          }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | +  foreach ($field_vals as $table_name => $details) {
 | 
	
		
			
				|  |  | +    // Skip the base table as we've already dealt with it.
 | 
	
		
			
				|  |  | +    if ($table_name == $base_table) {
 | 
	
		
			
				|  |  | +      continue;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    foreach ($details as $delta => $values) {
 | 
	
		
			
				|  |  | +      $record_id = tripal_chado_field_storage_write_table($table_name, $values);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /**
 | 
	
		
			
				|  |  | + * Write (inserts/oupdates) a nested array of values for a table.
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * The $values array is of the same format used by chado_insert_record() and
 | 
	
		
			
				|  |  | + * chado_update_record().  However, both of those methods will use any nested
 | 
	
		
			
				|  |  | + * arrays (i.e. representing foreign keys) to select an appropriate record ID
 | 
	
		
			
				|  |  | + * that can be substituted as the value.  Here, the nested arrays are
 | 
	
		
			
				|  |  | + * either inserted or updated as well, but the choice is determined if the
 | 
	
		
			
				|  |  | + * primary key value is present.  If present an update occurs, if not present
 | 
	
		
			
				|  |  | + * then an insert occurs.
 | 
	
		
			
				|  |  |   *
 | 
	
		
			
				|  |  | + * This function is recursive and nested arrays from the lowest point of the
 | 
	
		
			
				|  |  | + * "tree" are dealt with first.
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * @param $table_name
 | 
	
		
			
				|  |  | + *   The name of the table on which the insertion/update is performed.
 | 
	
		
			
				|  |  | + * @param $values
 | 
	
		
			
				|  |  | + *   The values array for the insertion.
 | 
	
		
			
				|  |  | + * @throws Exception
 | 
	
		
			
				|  |  | + * @return
 | 
	
		
			
				|  |  | + *   The unique record ID.
 | 
	
		
			
				|  |  |   */
 | 
	
		
			
				|  |  | -function tripal_chado_field_storage_write_table($params) {
 | 
	
		
			
				|  |  | -  $entity = $params['entity'];
 | 
	
		
			
				|  |  | -  $term = $params['term'];
 | 
	
		
			
				|  |  | -  $op = $params['op'];
 | 
	
		
			
				|  |  | -  $field_vals = $params['field_vals'];
 | 
	
		
			
				|  |  | -  $base_table = $params['base_table'];
 | 
	
		
			
				|  |  | -  $tablename = $params['tablename'];
 | 
	
		
			
				|  |  | -  $type_field = array_key_exists('type_field', $params) ? $params['type_field'] : NULL;
 | 
	
		
			
				|  |  | -  $record_id = array_key_exists('record_id', $params) ? $params['record_id'] : NULL;
 | 
	
		
			
				|  |  | -  $depth = array_key_exists('depth', $params) ? $params['depth'] : 0;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  // Intialize the values array.
 | 
	
		
			
				|  |  | -  $values = array();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  // Get the schema for this table so that we can identify the primary key
 | 
	
		
			
				|  |  | -  // and foreign keys.
 | 
	
		
			
				|  |  | -  $schema = chado_get_schema($tablename);
 | 
	
		
			
				|  |  | -  $pkey_field = $schema['primary key'][0];
 | 
	
		
			
				|  |  | -  $fkey_fields = $schema['foreign keys'];
 | 
	
		
			
				|  |  | -  $fkey_fields_list = array();
 | 
	
		
			
				|  |  | -  $fkey_base_linker = NULL;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  // STEP 1: Recurse on the FK fields.
 | 
	
		
			
				|  |  | -  // Loop through the foreign keys so that we can recurse on those first.
 | 
	
		
			
				|  |  | -  foreach ($fkey_fields as $fk_table => $details) {
 | 
	
		
			
				|  |  | -    foreach ($details['columns'] as $local_id => $remote_id) {
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -      // If this is the base table then do not recurse on the type_id.
 | 
	
		
			
				|  |  | -      if ($tablename == $base_table && $local_id == $type_field) {
 | 
	
		
			
				|  |  | -        $values[$local_id] = $term->details['cvterm']->cvterm_id;
 | 
	
		
			
				|  |  | -        continue;
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -      // If this is a linking table, do not recurse on the fields that
 | 
	
		
			
				|  |  | -      // link back to the base table.
 | 
	
		
			
				|  |  | -      if ($tablename != $base_table && $details['table'] == $base_table) {
 | 
	
		
			
				|  |  | -        $fkey_base_linker = $local_id;
 | 
	
		
			
				|  |  | -        continue;
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -      // Get the value of the FK field as provided by the user.
 | 
	
		
			
				|  |  | -      $fk_val = NULL;
 | 
	
		
			
				|  |  | -      $fk_vals = array();
 | 
	
		
			
				|  |  | -      $fk_field_name = $tablename . '__' . $local_id;
 | 
	
		
			
				|  |  | -      if (array_key_exists($fk_field_name, $field_vals)) {
 | 
	
		
			
				|  |  | -        $fk_val = $field_vals[$fk_field_name][0][$tablename . '__' . $local_id];
 | 
	
		
			
				|  |  | -        $fk_vals = $field_vals[$fk_field_name][0];
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -      // Don't recurse if the value of the FK field is set to NULL.  The
 | 
	
		
			
				|  |  | -      // Tripal Chado API value for NULL is '__NULL__'.
 | 
	
		
			
				|  |  | -      if ($fk_val == "__NULL__") {
 | 
	
		
			
				|  |  | -        $values[$local_id] = $fk_val;
 | 
	
		
			
				|  |  | -        continue;
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -      // Don't recuse if there are no fkvals.
 | 
	
		
			
				|  |  | -      if (count(array_keys($fk_vals)) == 0) {
 | 
	
		
			
				|  |  | -        continue;
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -      // Keep track of the FK fields so that in STEP 2 we don't have to
 | 
	
		
			
				|  |  | -      // loop through the $fk_fields again.
 | 
	
		
			
				|  |  | -      $fkey_fields_list[] = $local_id;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -      // Recurse on the FK field.
 | 
	
		
			
				|  |  | -      $nparams = $params;
 | 
	
		
			
				|  |  | -      $nparams['field_vals'] = $fk_vals;
 | 
	
		
			
				|  |  | -      $nparams['tablename'] = $fk_table;
 | 
	
		
			
				|  |  | -      $nparams['type_field'] = NULL;
 | 
	
		
			
				|  |  | -      $nparams['record_id'] = $fk_val;
 | 
	
		
			
				|  |  | -      $nparams['depth'] = $depth + 1;
 | 
	
		
			
				|  |  | -      $fk_val = tripal_chado_field_storage_write_table($nparams);
 | 
	
		
			
				|  |  | -      if (isset($fk_val) and $fk_val != '' and $fk_val != 0) {
 | 
	
		
			
				|  |  | -        $values[$local_id] = $fk_val;
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  // STEP 2: Loop through the non FK 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 ($field_vals as $field_name => $items) {
 | 
	
		
			
				|  |  | -    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($chado_field, $fkey_fields_list)) {
 | 
	
		
			
				|  |  | -        continue;
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -      // If the value is empty then exclude this field
 | 
	
		
			
				|  |  | -      if (!$items[0][$tablename . '__' . $chado_field]) {
 | 
	
		
			
				|  |  | -        continue;
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -      // Add the value of the field to the $values arr for later insert/update.
 | 
	
		
			
				|  |  | -      $values[$chado_field] = $items[0][$tablename . '__' . $chado_field];
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  // STEP 3: Insert/Update the record.
 | 
	
		
			
				|  |  | -  // If there are no values then return.
 | 
	
		
			
				|  |  | -  if (count($values) == 0) {
 | 
	
		
			
				|  |  | -    return $record_id;
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  dpm($values);
 | 
	
		
			
				|  |  | -  // If we don't have an incoming record ID then this is an insert.
 | 
	
		
			
				|  |  | -  if ($record_id == NULL) {
 | 
	
		
			
				|  |  | -    // STEP 3a: Before inserting, we want to make sure the record does not
 | 
	
		
			
				|  |  | -    // already exist.  Using the unique constraint check for a matching record.
 | 
	
		
			
				|  |  | -    $options = array('is_duplicate' => TRUE);
 | 
	
		
			
				|  |  | -    $is_duplicate = chado_select_record($tablename, array('*'), $values, $options);
 | 
	
		
			
				|  |  | -    if($is_duplicate) {
 | 
	
		
			
				|  |  | -      $record = chado_select_record($tablename, array('*'), $values);
 | 
	
		
			
				|  |  | -      return $record[0]->$pkey_field;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | +function tripal_chado_field_storage_write_table($table_name, $values) {
 | 
	
		
			
				|  |  | +   $schema = chado_get_schema($table_name);
 | 
	
		
			
				|  |  | +   $fkeys = $schema['foreign keys'];
 | 
	
		
			
				|  |  | +   $pkey = $schema['primary key'][0];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +   // Before inserting or updating this table, recruse if there are any
 | 
	
		
			
				|  |  | +   // nested FK array values.
 | 
	
		
			
				|  |  | +   foreach ($values as $column => $value) {
 | 
	
		
			
				|  |  | +     // If this value is an array then it must be a FK... let's recurse.
 | 
	
		
			
				|  |  | +     if (is_array($value)) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +       // Find the name of the FK table for this column.
 | 
	
		
			
				|  |  | +       $fktable_name = '';
 | 
	
		
			
				|  |  | +       foreach ($fkeys as $fktable => $details) {
 | 
	
		
			
				|  |  | +         foreach ($details['columns'] as $fkey_lcolumn => $fkey_rcolumn) {
 | 
	
		
			
				|  |  | +           if ($fkey_lcolumn == $column) {
 | 
	
		
			
				|  |  | +             $fktable_name = $fktable;
 | 
	
		
			
				|  |  | +           }
 | 
	
		
			
				|  |  | +         }
 | 
	
		
			
				|  |  | +       }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +       // Recurse on this recod.
 | 
	
		
			
				|  |  | +       $record_id = tripal_chado_field_storage_write_table($fktable_name, $values[$column]);
 | 
	
		
			
				|  |  | +       $values[$column] = $record_id;
 | 
	
		
			
				|  |  | +     }
 | 
	
		
			
				|  |  | +   }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    // STEP 3b: Insert the reocrd
 | 
	
		
			
				|  |  | -    // Insert the values array as a new record in the table.
 | 
	
		
			
				|  |  | -    $record = chado_insert_record($tablename, $values);
 | 
	
		
			
				|  |  | -    if ($record === FALSE) {
 | 
	
		
			
				|  |  | -      throw new Exception('Could not insert Chado record into table: "' . $tablename . '".');
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    $record_id = $record[$pkey_field];
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -  // We have an incoming record_id so this is an update.
 | 
	
		
			
				|  |  | -  else {
 | 
	
		
			
				|  |  | -    // TODO: what if the unique constraint matches another record?  That is
 | 
	
		
			
				|  |  | -    // not being tested for here.
 | 
	
		
			
				|  |  | -    $match[$pkey_field] = $record_id;
 | 
	
		
			
				|  |  | -    if (!chado_update_record($tablename, $match, $values)) {
 | 
	
		
			
				|  |  | -      drupal_set_message("Could not update Chado record in table: $tablename.", 'error');
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | +   // Fields with a cardinality greater than 1 will often submit an
 | 
	
		
			
				|  |  | +   // empty form.  We want to remove these empty submissions.  We can detect
 | 
	
		
			
				|  |  | +   // them if all of the fields are empty.
 | 
	
		
			
				|  |  | +   $num_empty = 0;
 | 
	
		
			
				|  |  | +   foreach ($values as $column => $value) {
 | 
	
		
			
				|  |  | +     if (!$value) {
 | 
	
		
			
				|  |  | +       $num_empty++;
 | 
	
		
			
				|  |  | +     }
 | 
	
		
			
				|  |  | +   }
 | 
	
		
			
				|  |  | +   if ($num_empty == count(array_keys($values))) {
 | 
	
		
			
				|  |  | +     return '';
 | 
	
		
			
				|  |  | +   }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  return $record_id;
 | 
	
		
			
				|  |  | +   // If the primary key column has a value then this will be an udpate,
 | 
	
		
			
				|  |  | +   // otherwise it's an insert.
 | 
	
		
			
				|  |  | +   if (!$values[$pkey]) {
 | 
	
		
			
				|  |  | +     // Before inserting, we want to make sure the record does not
 | 
	
		
			
				|  |  | +     // already exist.  Using the unique constraint check for a matching record.
 | 
	
		
			
				|  |  | +     $options = array('is_duplicate' => TRUE);
 | 
	
		
			
				|  |  | +     $is_duplicate = chado_select_record($table_name, array('*'), $values, $options);
 | 
	
		
			
				|  |  | +     if($is_duplicate) {
 | 
	
		
			
				|  |  | +       $record = chado_select_record($table_name, array('*'), $values);
 | 
	
		
			
				|  |  | +       return $record[0]->$pkey_field;
 | 
	
		
			
				|  |  | +     }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +     // Insert the values array as a new record in the table.
 | 
	
		
			
				|  |  | +     $record = chado_insert_record($table_name, $values);
 | 
	
		
			
				|  |  | +     if ($record === FALSE) {
 | 
	
		
			
				|  |  | +       throw new Exception('Could not insert Chado record into table: "' . $tablename . '".');
 | 
	
		
			
				|  |  | +     }
 | 
	
		
			
				|  |  | +     return $record_id = $record[$pkey_field];
 | 
	
		
			
				|  |  | +   }
 | 
	
		
			
				|  |  | +   // We have an incoming record_id so this is an update.
 | 
	
		
			
				|  |  | +   else {
 | 
	
		
			
				|  |  | +     // TODO: what if the unique constraint matches another record?  That is
 | 
	
		
			
				|  |  | +     // not being tested for here.
 | 
	
		
			
				|  |  | +     $match[$pkey] = $values[$pkey];
 | 
	
		
			
				|  |  | +     if (!chado_update_record($table_name, $match, $values)) {
 | 
	
		
			
				|  |  | +       drupal_set_message("Could not update Chado record in table: $tablename.", 'error');
 | 
	
		
			
				|  |  | +     }
 | 
	
		
			
				|  |  | +     return $values[$pkey];
 | 
	
		
			
				|  |  | +   }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /**
 | 
	
	
		
			
				|  | @@ -420,15 +340,19 @@ function tripal_chado_field_storage_merge_fields($fields, $entity_type, $entity)
 | 
	
		
			
				|  |  |              $parent_item_name = $matches[1];
 | 
	
		
			
				|  |  |              $sub_item_name = $matches[2];
 | 
	
		
			
				|  |  |              $sub_item = tripal_chado_field_storage_expand_field($sub_item_name, $value);
 | 
	
		
			
				|  |  | -            // If we've already encountered this table and column then we've
 | 
	
		
			
				|  |  | -            // already seen the numeric FK value or we've already added a
 | 
	
		
			
				|  |  | -            // subcolumn. If the former we want to convert this to an array
 | 
	
		
			
				|  |  | -            // so we can add the details.
 | 
	
		
			
				|  |  | -            if (array_key_exists($parent_item_name, $new_fields[$table_name][$delta]) and
 | 
	
		
			
				|  |  | -                !is_array($new_fields[$table_name][$delta][$parent_item_name])) {
 | 
	
		
			
				|  |  | -              $new_fields[$table_name][$delta][$parent_item_name] = array();
 | 
	
		
			
				|  |  | +            if (count(array_keys($sub_item))) {
 | 
	
		
			
				|  |  | +              // If we've already encountered this table and column then we've
 | 
	
		
			
				|  |  | +              // already seen the numeric FK value or we've already added a
 | 
	
		
			
				|  |  | +              // subcolumn. If the former we want to convert this to an array
 | 
	
		
			
				|  |  | +              // so we can add the details.
 | 
	
		
			
				|  |  | +              if (!array_key_exists($table_name, $new_fields) or
 | 
	
		
			
				|  |  | +                  !array_key_exists($delta, $new_fields[$table_name]) or
 | 
	
		
			
				|  |  | +                  !array_key_exists($parent_item_name, $new_fields[$table_name][$delta]) or
 | 
	
		
			
				|  |  | +                  !is_array($new_fields[$table_name][$delta][$parent_item_name])) {
 | 
	
		
			
				|  |  | +                $new_fields[$table_name][$delta][$parent_item_name] = array();
 | 
	
		
			
				|  |  | +              }
 | 
	
		
			
				|  |  | +              $new_fields[$table_name][$delta][$parent_item_name] += $sub_item;
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | -            $new_fields[$table_name][$delta][$parent_item_name] += $sub_item;
 | 
	
		
			
				|  |  |            }
 | 
	
		
			
				|  |  |            else {
 | 
	
		
			
				|  |  |              // If not seen this table and column then just add it. If we've
 |