6

I've been running a d7 site for a couple months and one of the content types has a date field. Initially I opted not to collect and end date but the need for it has arisen. As you may know, there's a design decision in d7's field api that forbids you from changing field settings after it's been saved. screenshot for reference

The problem is that I have a very considerable amount of data on a fairly live site, which means it's extremely hairy to do something like deleting the field and then somehow herding all the data back in. Has anyone ran into this? How did you solve it? Any insight at all? Thank you :)

4 Answers 4

3

When I did this, I created a new date field and set it as hidden on the page. I configured it the way I wanted, then duplicated the existing information in the new field, manipulating the database directly. As you will have two date values (..._value and ..._value2) you should begin by setting them the same.

Once you are sure that the correct values are in place, you must then change all your views, rules etc that use the date field to use the new field.

Then set the new field to display and hide the old field. Make sure everything is working before you delete the old field.

There is no short cut that I am aware of. Best to do all this on a copy, with extensive backups. Good luck.

2

I use a different approach. I:

  • back up my database table for my field, for example field_data_field_event_date. Back up entire database as well for good measure.
  • Delete my field from the field manager (admin/structure/types/manage/yourcontenttype/fields).
  • Add field back with field manager, using exactly the same machine name (field_event_date in my example).
  • set the field settings to allow you to collect an end date.
  • import your field table backup file into the field_data_field_event_date table. This brings back your previous date values.
  • Now try and edit a content item. You should be able to edit the date and provide an end date too.
1

The easiest way, if you don't mind patching, is to review the patch in the following Date module issue: https://www.drupal.org/node/2581013

The patch unlocks the "Collect End Date" option when there is already data in the field and allows you to change it.

0

I once wrote an update script that converted a date field from using only a start date to collect both a start and an end date. Here it is as a sample. Be warned, I haven't looked at this sample in 3 years, so review with caution. Basically, delete the field in your local dev environment, then recreate it and export it using the Features module. Once that's done, push your code to your dev/stage/prod environments. This update hook will save all the values for a given date field to a variable, delete the field, recreate it using the Features module, then re-add the saved data. This might fail with enormous data sets as it doesn't make use of the batch API (a large data set might cause a PHP to run out of memory and error).

/**
* The following was used as in an update hook to convert a date field from using 
* a single date value to a date field that uses both begin and end dates.
* The date field in question here was for an "event" content type
*   
*/
function hook_update_700X(&$s){

//Get the current event date field data
$query = db_select('node', 'n');
$query->condition('n.type', 'event', '=')
    ->fields('n', array('nid'));

$result = $query->execute();

//Save the dates
$dates = array();
foreach ($result as $row) {
    $node = node_load($row->nid);
    $dates[$node->nid] = $node->field_date;
}

//Delete the field, this destroys data
field_delete_field('field_date');
field_purge_batch(5);//5 Should cover this field and any others to be purged (which is probably 0)

//Create new date formats, we are moving away from regenerating the dates in the views templates
$formats = array(
    array(
        'type'    => 'date_selector_class',
        'format'  => 'm-Y',
    ),
    array(
        'type'    => 'event_selector',
        'format'  => 'l, F j',
    ),
 );

 foreach ($formats as $format) {
     variable_set('date_format_' . $format['type'], $format['format']); 
 }

//Use features to recreate the field with the end date option
features_revert(array('cloud_events' => array('field'))); 

$counter = 0;   

 //Set the dates, use the start date for the end date for now.
foreach ($dates as $nid => $date) {
    $counter++;
    $node = node_load($nid);
    error_log('Repopulating node '.$node->nid,0);
    $node->field_date = $date;
    $node->field_date[$node->language][0]['value2'] = $date[$node->language][0]['value']; 
    node_save($node);
}

return $counter . " Events updated.";

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.