Drupal 7 fields: Convert Float to Decimal

drupal logo

When using postgresql, indexes and fields properties are dropped with the deletion of the field. One way to change the type of a fields is to copy the data to a temporary storeage and move it back into aa newly created field with the desired type.

We can do this at the database level with db change but our approach is to go with drupal fields module functions.

$FIELD_MAX_CHAR = 30;  //normally 32 but leave a buffer
    echo "<pre>".PHP_EOL;

$float_fields = array('field_item_price_item' =>
                            array('name' => 'field_item_price', 'bundle' => 'item', 'cardinality' => 1, 'label' => 'Price'),);
 
    echo "============== Copying to temp fields".PHP_EOL;
    foreach($float_fields as $field_id => $field_def){
        $node_type = $field_def['bundle'];
        $field_name = $field_def['name'];
        echo $field_name.PHP_EOL;
        $field_card = $field_def['cardinality'];
        $field_label = $field_def['label'];
        
        $tmp_field_name = $field_name.'_t';
        if(strlen($tmp_field_name)> $FIELD_MAX_CHAR) $tmp_field_name = substr($tmp_field_name,0,$FIELD_MAX_CHAR - 2).'_t';
        $entity_type = 'node';
        //$field_info = field_info_field($field_name);
        //if($field_info){
            //print_r($field_info);
            
            $tmp_field = array(
                'field_name' => $tmp_field_name,
                'type'        => 'number_decimal',
                'cardinality' => $field_card
            );
            
            $tmp_field_info = field_info_field($tmp_field_name);
            if(!$tmp_field_info) {
                echo "Creating field $tmp_field_name".PHP_EOL;
                field_create_field($tmp_field);
            } else echo "Skipping creation of field $tmp_field_name".PHP_EOL;
            
            $tmp_instance = array(
                'field_name' => $tmp_field_name,
                'entity_type' => $entity_type,
                'label' => $tmp_field_name,
                'bundle' => $node_type,
                'label' => $field_label,
                'required' => false,
                'settings' => array(),
                'widget' => array(
                    'type' => 'textfield',
                ),
            );
            //$field_instance_info = field_info_instance($entity_type,$field_name,$node_type);
            //print_r($field_instance_info);
            $tmp_field_instance_info = field_info_instance($entity_type,$tmp_field_name,$node_type);
            if(!$tmp_field_instance_info){
                echo "Creating field instance of $tmp_field_name for $node_type".PHP_EOL;
                field_create_instance($tmp_instance);
            } else echo "Skipping creation of field instance of $tmp_field_name for $node_type".PHP_EOL;
            
            $query = db_select('node', 'n');
            $query->join('node_revision', 'v', '(n.nid = v.nid) AND (n.vid = v.vid)');
            $query->fields('n', array('nid'));
            $query->condition('n.type', $node_type, '=');
            $query->condition('n.status', 1, '=');

            $nodes = $query->execute()->fetchAll();
            if(count($nodes) > 0){
                foreach($nodes as $node){
                    $c_node = node_load($node->nid);
                    
                    if (isset($c_node->{$field_name}) && !empty($c_node->{$field_name})) {
                        echo "Copying ".$field_name." => ".$tmp_field_name." : ".$c_node->{$field_name}[LANGUAGE_NONE][0]['value']." => ".$c_node->{$tmp_field_name}[LANGUAGE_NONE][0]['value'].PHP_EOL;
                        if(empty($c_node->{$tmp_field_name})) $c_node->{$tmp_field_name}[LANGUAGE_NONE][]['value'] = $c_node->{$field_name}[LANGUAGE_NONE][0]['value'];
                        else $c_node->{$tmp_field_name}[LANGUAGE_NONE][0]['value'] = $c_node->{$field_name}[LANGUAGE_NONE][0]['value'];
                        node_save($c_node);
                    }
                }
            }
        //}
    }
    
    echo "============== Deleting real fields".PHP_EOL;
    foreach($float_fields as $field_id => $field_def){
        $field_name = $field_def['name'];
        echo $field_name.PHP_EOL;
        field_delete_field($field_name);
    }
    
    echo "============== Copying to real fields".PHP_EOL;
    foreach($float_fields as $field_id => $field_def){
        $node_type = $field_def['bundle'];
        $field_name = $field_def['name'];
        echo $field_name.PHP_EOL;
        $field_card = $field_def['cardinality'];
        $field_label = $field_def['label'];
        
        $tmp_field_name = $field_name.'_t';
        if(strlen($tmp_field_name)>$FIELD_MAX_CHAR) $tmp_field_name = substr($tmp_field_name,0,$FIELD_MAX_CHAR - 2).'_t';
        $entity_type = 'node';
        //$field_info = field_info_field($tmp_field_name);
        //if($field_info){
    
            $new_field = array(
                'field_name' => $field_name,
                'type'        => 'number_decimal',
                'cardinality' => $field_card
            );
            
            if(!field_info_field($field_name)) {
                echo "Creating field $field_name".PHP_EOL;
                field_create_field($new_field);
            } else echo "Skipping creation of field $field_name".PHP_EOL;
            
            $new_instance = array(
                'field_name' => $field_name,
                'entity_type' => $entity_type,
                'label' => $field_name,
                'bundle' => $node_type,
                'label' => $field_label,
                'required' => false,
                'settings' => array(),
                'widget' => array(
                    'type' => 'textfield',
                ),
            );
            $field_instance_info = field_info_instance($entity_type,$field_name,$node_type);
            if(!$field_instance_info){
                echo "Creating field instance of $field_name for $node_type".PHP_EOL;
                field_create_instance($new_instance);
            } else echo "Skipping creation of field instance of $field_name for $node_type".PHP_EOL;
            
            $query = db_select('node', 'n');
            $query->join('node_revision', 'v', '(n.nid = v.nid) AND (n.vid = v.vid)');
            $query->fields('n', array('nid'));
            $query->condition('n.type', $node_type, '=');
            $query->condition('n.status', 1, '=');

            $nodes = $query->execute()->fetchAll();
            if(count($nodes) > 0){
                foreach($nodes as $node){
                    $c_node = node_load($node->nid);
                    
                    if (isset($c_node->{$tmp_field_name}) && !empty($c_node->{$tmp_field_name})) {
                        echo "Copying ".$tmp_field_name." => ".$field_name." : ".$c_node->{$tmp_field_name}[LANGUAGE_NONE][0]['value']." => ".$c_node->{$field_name}[LANGUAGE_NONE][0]['value'].PHP_EOL;
                        if(empty($c_node->{$field_name})) $c_node->{$field_name}[LANGUAGE_NONE][]['value'] = $c_node->{$tmp_field_name}[LANGUAGE_NONE][0]['value'];
                        else $c_node->{$field_name}[LANGUAGE_NONE][0]['value'] = $c_node->{$tmp_field_name}[LANGUAGE_NONE][0]['value'];
                        node_save($c_node);
                    }
                }
            }
        //}
    }
    
    echo "============== Deleting temp fields".PHP_EOL;
    foreach($float_fields as $field_id => $field_def){
        $field_name = $field_def['name'];
        $tmp_field_name = $field_name.'_t';
        if(strlen($tmp_field_name)>$FIELD_MAX_CHAR) $tmp_field_name = substr($tmp_field_name,0,$FIELD_MAX_CHAR - 2).'_t';
        echo $tmp_field_name.PHP_EOL;
        field_delete_field($tmp_field_name);
    }
    
    //field_info_field($field_name);
    //field_info_instance($entity_type, $field_name, $bundle_name);
    //field_create_field($field);
    //field_create_instance($instance);
    //field_delete_field($field_name);
    //field_delete_instance($instance, $field_cleanup = TRUE);
    echo "</pre>";
}

Startup Growth Lite is a free theme, contributed to the Drupal Community by More than Themes.