I have a couple of event types that use a "Date" field. I now want to modify that field to allow users to submit "end dates", but that option is no longer available (the check box is grayed out).

Why is it not possible to enable "end dates" once a Date is created, or once nodes using Date fields exist in the DB ?
Are there any suggested migration paths to add end dates to existing content types (ideally without affecting existing content) ?

Comments

stefan_seefeld created an issue. See original summary.

glanster’s picture

I´m having the same issue. Is there any feedback around about it?
Thanks!

herved’s picture

This is what I came up with to add an optional end date to an existing date field with data in DB.
It is inspired from field_update_field().

/**
 * Add end date to field_my_field.
 */
function my_module_update_7000() {
  $prior_field = field_info_field('field_my_field');

  // Changes to the current field definition.
  $field = $prior_field;
  $field['settings']['todate'] = 'optional';
  $field['columns']['value2'] = $field['columns']['value'];
  $field['columns']['value2']['views'] = FALSE;
  $field['indexes'] = array(
    'value' => array('value'),
    'value2' => array('value2'),
  );

  // Get new storage details definition.
  $details = (array) module_invoke($field['storage']['module'], 'field_storage_details', $field);
  drupal_alter('field_storage_details', $details, $field);
  $field['storage']['details'] = $details;

  // Update the field_config table.
  $data = $field;
  unset($data['columns'], $data['field_name'], $data['type'], $data['locked'], $data['module'], $data['cardinality'], $data['active'], $data['deleted'], $data['bundles'], $data['data']);
  $field['data'] = $data;
  $primary_key = array('id');
  drupal_write_record('field_config', $field, $primary_key);

  // Update the tables schema.
  $old_schema = _field_sql_storage_schema($prior_field);
  $new_schema = _field_sql_storage_schema($field);
  $schema_changes = drupal_array_diff_assoc_recursive($new_schema, $old_schema);
  if (!empty($schema_changes)) {
    foreach ($schema_changes as $table => $data) {
      foreach ($data['fields'] as $id => $spec) {
        if (!db_field_exists($table, $id)) {
          db_add_field($table, $id, $spec);
        }
      }
      foreach ($data['indexes'] as $id => $spec) {
        if (!db_index_exists($table, $id)) {
          db_add_index($table, $id, $spec);
        }
      }
    }
  }

  // Clear caches.
  field_cache_clear();
}

If your field base is exported in features you also need to change your field_base export (a feature export after running the update might work):

'indexes' => array(
  'value' => array(
    0 => 'value',
  ),
  'value2' => array(
    0 => 'value2',
  ),
),

and

'settings' => array(
  ...
  'todate' => 'optional',
  ...
),
bernig’s picture

herved, your solution worked perfectly for 3 of my projects where I was about to scratch my head for a very long time. Thanks a lot for your work.

herved’s picture

@bernig You're welcome. Glad to hear my solution helped others as well ;)

viswanathsai’s picture

Hi can you please explain how can i implement this, i can't figure out how do this.

herved’s picture

@viswanathsai This is a standard hook_update() to be placed in one of your custom modules .install file.
See also https://api.drupal.org/api/drupal/modules%21system%21system.api.php/func...

steinmb’s picture

Status: Active » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

Collins405’s picture

You absolute beauty!! Thank you for this!!