Kalin Chernev

Convert a text to textarea type of field in Drupal 7 (Elegant way)

Converting a text field in Drupal 7 from one type to another is a frequently encounter task, especially in times when the field text length haven’t been planned well.

Most of the times, site builders add another field with the corresponding type, delete the old one. However, in larger projects, where the “machine” name (the system name) is used throughout modules and themes, we need to keep this name intact, keep all the data entered in the database so far, and still change the type. From site building point of view, this operation is impossible on first place if users have entered data in old-type-field on first place – Drupal won’t let you delete the field before deleting all the content.

Our approach

  1. We need to query the database in a way to only change the type of the field in a scalable way, no data should be lost!
  2. Also, we have to make sure changes do not require users and developers to edit the database tables in anyway! The solution have to be as safe as possible!
  3. Changes have to be managed throught code (again best practices and scalability)
  4. Use Drupal API functions as much as possible.

Simple example would be when we have the following form – the fields in read are those text fields we are going to convert to text area such.

Drupal form initially

In a Drupal module file, we place the following code (quick link to the developers documentation if you need help for writing the module)

/**
 * Change field_inq_description field from textfield to textarea
 */
function pip_inquiry_update_7001() {
  // Manual database changes.
  db_query("UPDATE {field_config} SET type = 'text_long' WHERE field_name = 'field_inq_description'");
  db_change_field('field_data_field_inq_description', 'field_inq_description_value', 'field_inq_description_value', array(
    'type' => 'varchar',
    'length' => '20000',
  ));
  db_change_field('field_revision_field_inq_description', 'field_inq_description_value', 'field_inq_description_value', array(
    'type' => 'varchar',
    'length' => '20000',
  ));
  // Clear caches.
  field_cache_clear(TRUE);
  // Apply the new field instance configuration.
  features_revert(array(
    'pip_inquiry_show' => array('field'),
  ));
}

/**
 * Change field_inq_camp_description field from textfield to textarea
 */
function pip_inquiry_update_7002() {
  // Manual database changes.
  db_query("UPDATE {field_config} SET type = 'text_long' WHERE field_name = 'field_inq_camp_description'");
  db_change_field('field_data_field_inq_camp_description', 'field_inq_camp_description_value', 'field_inq_camp_description_value', array(
    'type' => 'varchar',
    'length' => '20000',
  ));
  db_change_field('field_revision_field_inq_camp_description', 'field_inq_camp_description_value', 'field_inq_camp_description_value', array(
    'type' => 'varchar',
    'length' => '20000',
  ));
  // Clear caches.
  field_cache_clear(TRUE);
  // Apply the new field instance configuration.
  features_revert(array(
    'pip_inquiry_show' => array('field'),
  ));
}

The hook we implement is the hook_update_N, it lets us communicate to site users and developers that there are updates in the system (via the update.php script)

Updates in Drupal

The following functions are used to apply changes in the database:

  • db_query for changing the type of the field to “text_long” which is the type we need to have in the end of the update script
  • db_change_field for changing field definition
  • field_cache_clear to clear the cache about fields information
  • features_revert to revert all features related to the changes applied

It won’t hurt if you clear the overall cache :)

After the updates, configurations and edit form for the entity are correctly taking long text values:

updated form

Conclustions

It’s always good to think scalability when you modify database schema, and even more when existing information has to be contained intact. Best approach for Drupal would include the implementation of it’s API as much as possible. Our example is for changing the type of a text field to long text area one, still you can convert between other types of fields as well in a similar manner.

Comments

  1. dennis

    good article thank you for sharing…

  2. Adrien L

    Thanks a lot for this example, I had to change few fields for a project I’m working on right now and was not very pleased to delete / recreate all these fields by hand !

    Perfect.

  3. Etienne

    Very clear and useful, thanks a lot !

  4. Oneng

    Thanks man!
    very useful article -))

  5. Sebastian

    Im trying to do it fow convert integer field to decimal field and I see these notices

    Notice: Undefined index: precision in number_field_schema() (line 35 of /home/servilla/public_html/servillantasgiraldo.com.co/modules/field/modules/number/number.install).
    Notice: Undefined index: scale in number_field_schema() (line 36 of /home/servilla/public_html/servillantasgiraldo.com.co/modules/field/modules/number/number.install).

  6. ajay gadhavana

    hi i have created module same as you told its work perfectly and change value in database but still its give Error message
    “name: the text may not be longer than 255 characters.”

    due to error i have not added “features_revert “statements

Leave a comment




captcha

Please enter the CAPTCHA text