Copying Values Between Fields on Thousands of Entities
In a nutshell, I had a List (text) field that I needed to convert to a Text field (so that I wasn’t locked in to specific values anymore). Instead of trying to modify the field to convert it from one type to another, I decided to create a new Text field and populate it with the data from the List field (modifying it a bit first). Here’s the script I used to do this. Admittedly it could be cleaner, more efficient, etc. but it’ll show you a few things, and it got the job done for me.
If you choose to run with drush scr update_nodes.php
you can leave out the top 3 bootstrap lines.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
<?php define('DRUPAL_ROOT', '/var/www/mysite'); require_once DRUPAL_ROOT . '/includes/bootstrap.inc'; drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); ///////////////////////////////////////////////////// // Copies the values from a list(text)/selectlist field (field_stock_source) // into a new text/text field (field_warehouse), transforming the values // to match a desired JSON format. // Watch the row count of your new field's table(s) while this is running // to make sure rows are being created correctly. // WARNING! I had to run this file SEVERAL times before I had the same number of // records in the new field's table as the old one. The last time I ran it only // took a few seconds because there weren't any more results in the query. // Operate on all commerce_line_item entities that don't already have a field_data_field_warehouse value // Skip commerce_line_item entities that we know don't have this field_warehouse field $result = db_query("SELECT line_item_id FROM {commerce_line_item} LEFT JOIN {field_data_field_warehouse} fw ON fw.entity_id = commerce_line_item.line_item_id WHERE fw.entity_id IS NULL AND commerce_line_item.type NOT IN ('shipping', 'commerce_coupon')"); foreach ($result as $record) { // Load the entity we want to modify $line_item = commerce_line_item_load($record->line_item_id); $wrapper = entity_metadata_wrapper('commerce_line_item', $line_item); // Get the quantity so we can match the new/desired format $qty = $wrapper->quantity->value(); // If the original field and the new field exist, set the new field's value // to the original field's value. if (isset($wrapper->field_stock_source) && isset($wrapper->field_warehouse)) { // This JSON format is what we're preparing for with this new textfield // and is the reason the original field (a list field) won't work for us anymore if ($wrapper->field_stock_source->value() == 'local') { $json_value = '{"Warehouse X":' . $qty . '}'; } else { $json_value = '{"Supplier":' . $qty . '}'; } // Set the JSON value on the new field $wrapper->field_warehouse->set($json_value); // Save the changes $wrapper->save(); } } |