Problem/Motivation

All D6 Integer, Float, Decimal or Text fields are converted to Number(Integer) or Text fields in D8. These new fields don't support check boxes, radio buttons, or select lists.

Proposed resolution

When migrating Integer, Float, Decimal or Text fields we need to check the widget and use that as part of the map when figuring out which widget to use.

D8field        = D6field:D6widget

list_text      = text:optionwidgets_select
list_text      = text:optionwidgets_buttons
boolean        = text:optionwidgets_onoff
text           = text:text_textfield
long_text      = text:text_textarea

integer        = number_integer:number
list_integer   = number_integer:optionwidgets_select
list_integer   = number_integer:optionwidgets_buttons
boolean        = number_integer:optionwidgets_onoff

decimal        = number_decimal:number
list_float     = number_decimal:optionwidgets_select
list_float     = number_decimal:optionwidgets_buttons
boolean        = number_decimal:optionwidgets_onoff

float          = number_float:number
list_float     = number_float:optionwidgets_select
list_float     = number_float:optionwidgets_buttons
boolean        = number_float:optionwidgets_onoff

Remaining tasks

User interface changes

API changes

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

ultimike’s picture

hosef’s picture

Title: D6->D8 CCK Single On/Off Checkbox migration » D6->D8 CCK Single On/Off Checkbox, Check boxes/Radio buttons, and Select formaters
Issue summary: View changes
hosef’s picture

Issue summary: View changes
hosef’s picture

Issue summary: View changes
hosef’s picture

hosef’s picture

Issue summary: View changes
hosef’s picture

Issue summary: View changes
hosef’s picture

Issue summary: View changes
ultimike’s picture

Title: D6->D8 CCK Single On/Off Checkbox, Check boxes/Radio buttons, and Select formaters » D6->D8 CCK Single On/Off Checkbox, Checkboxes/Radio buttons, and Select formatters
hosef’s picture

Here is a fix for the issue that involves greatly expanding the field type map. Another option would be to create a process plugin to handle the field types.

I, also modified several of the tests so that they provide better feedback.

hosef’s picture

Status: Active » Needs review

Status: Needs review » Needs work

The last submitted patch, 10: drupal-d6-d8-fields-and-widgets-2262275-10.patch, failed testing.

hosef’s picture

Status: Needs work » Needs review
FileSize
17.04 KB

Ok, let's try this again.

Status: Needs review » Needs work

The last submitted patch, 13: drupal-d6-d8-fields-and-widgets-2262275-13.patch, failed testing.

hosef’s picture

I forgot to add the unsupported_field_handler class to my patch. I, also, had to change some of the test data because a few of the new fields that I added to the test were miss-formatted.

ultimike’s picture

@hosef,

This is really great work!

I applied the patch to my local and ran a manual test, and I think we still have some issues we need to work out.

On my local D6 test site, I created a decimal select list field and created a couple of nodes using the field, the migration appeared to run fine, and the field values appear to be migrated correctly, but there are two issues I noticed:

  1. The "edit" page for the field instances on D8 returns a white screen of death.
  2. The "edit" page for nodes with the field on D8 does not include any of the "allowed values".

On another (minor) note:

+++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateFieldTest.php
@@ -55,29 +55,29 @@ public function testFields() {
+    $this->assertEqual($field->type, "text", "Field type is $field->type. It should be text.");

Stuff like this should probably be written as

$this->assertEqual($field->type, "text", t('Field type is @fieldtype. It should be text.', array('@fieldtype' => $field->type)));

-mike

hosef’s picture

FileSize
21.15 KB

Ok, here is an updated patch with the requested changes. It turns out that it wasn't parsing the allowed values from Drupal 6 but was just passing it in as a string like 'key1|value1\r\nkey2|value2', and that was causing the white screens.

There is still one place where it white screens though. When I create a field that gets migrated over as a Boolean and then go to the field instance settings page, I get the following in my Apache log followed by a stack trace:
Fatal error: Call to a member function form() on a non-object in /var/www/drupal8/core/lib/Drupal/Core/Field/FieldItemList.php on line 319

There is also an undefined offset error when I run the tests that I haven't been able to figure out.

If anyone knows where I should look to fix those, that would be great.

hosef’s picture

Status: Needs review » Needs work

Oops, didn't mean to change the status.

The last submitted patch, 17: drupal-d6-d8-fields-and-widgets-2262275-17.patch, failed testing.

chx’s picture

First Rule Of Migration Debug: Never try to debug MigrateDrupal6Test! That way only lies burnout.

That's why we have the small tests, to have something debuggable. You got lucky cos both tests fail the same.

Drupal\Core\Config\Schema\Mapping->get('settings.allowed_values.1.2')
Drupal\Core\Config\StorableConfigBase->castValue('settings.allowed_values.1.2', '1.2') 

Well, CMI uses dot as an array delimiter so what this try to is $config['settings']['allowed_values'][1][2] = '1.2';

Does that help? I hope it does.

Also Drupal codign standards put the else on a separate line

}
else {

thanks.

hosef’s picture

Status: Needs work » Needs review
FileSize
21.53 KB

Ok, I've changed it so that it replaces the . with an _ in the allowed values key.

I've, also, moved the else's onto their own lines.

ultimike’s picture

It might be worth it to move the regex stuff into its own process plugin (as benjy suggested), seeing how it is used in patch 21 above but also in #2281627: Freeform text profile field does not migrate properly from D6 to D7.

Thanks,
-mike

hosef’s picture

I'm a little confused. The regex stuff is already in a process function. Is it possible to call another process function from within a process function? If so, is that a good idea? That would mean that we would be using multiple process functions, but you would not be able to tell that by simply looking at the .yml file for that migration.

I do think the new regex in the other issue looks much nicer though.

ultimike’s picture

hosef and I chatted on IRC about this and we decided to proceed as follows:

  1. He'll update the patch with cleaner RegEx (via #2281627: Freeform text profile field does not migrate properly from D6 to D7).
  2. I'll do some manual testing tonight or tomorrow morning.
  3. If all looks good, we'll ask chx to review the patch again.
  4. The RegEx refactoring shouldn't hold up this patch, so we'll open a new issue if it makes sense to.

Thanks,
-mike

hosef’s picture

FileSize
21.51 KB

Here is the new patch with the cleaner regex.

ultimike’s picture

hosef,

As promised, I did some manual testing and found some good stuff and some bad stuff. First, the good:

The widget mapping appears to be working great. I created a select list (integer), radio buttons (decimal), and checkboxes (text), and the widget settings were migrated properly into D8.

On a test node, the selected values for the checkboxes (text) were migrated fine as well, they were displayed/selected properly on both the node edit and view pages.

Unfortunately, the selected values for the select list (integer) and radio buttons (decimal) fields on test nodes didn't fare so well:

  1. The radio buttons (decimal) allowed values were migrated with their decimals replaced with underscores (I suspect the change in comments 20 and 21 is to blame) so that the proper value wasn't selected on the edit page of the node. The odd part is that on the view display for the node the "key" value was displayed, not the "label" (from the allowed values).
  2. The select list (integer) allowed values appear to have been migrated properly, but it looks like their selected value did not. On both the edit and view page of my test node, this field didn't appear to have a value migrated.

Both of these appear to be ripe for an automated test (and a fix).

Let me know if you need further explanation on my results.

Thanks,
-mike

ultimike’s picture

Status: Needs review » Needs work
ultimike’s picture

FileSize
21.51 KB

The patch in 25 no longer applies cleanly (something with $field->status() vs. $field->status), so I re-rolled it. Diving back into this issue now.

-mike

ultimike’s picture

FileSize
25.71 KB
6.03 KB

Attaching a new patch that I believe modifies the MigrateFieldTest and MigrateCckFieldValuesTest to capture the two issue I reported in comment 26 above.

I'm pretty confident that the addition to MigrateFieldTest that I made reflects the "underscore" issue. I'm slightly less confident that I modified the MigrateCckFieldValuesTest properly to capture the missing select list (integer) value.

My next step is to debug the migration to try to get these new tests to pass.

Thanks,
-mike

ultimike’s picture

For the decimal/float allowed values issue (item 1 from comment 26), this is related to #2293773: Field allowed values use dots in key names - not allowed in config. How that patch ultimately lands will dictate the fix for this bug.

-mike

ultimike’s picture

I chatted with chx about this today, he also thinks that #2293773: Field allowed values use dots in key names - not allowed in config will go a long way in solving the "use a decimal as a key" issue.

I'll continue working on the "missing select list (integer)" part of this patch.

Thanks,
-mike

hussainweb’s picture

Status: Needs work » Needs review
FileSize
26.64 KB

Just rerolling for now and testing. It is a reroll of #29 and resolving conflicts against #2287727: Rename FieldConfig to FieldStorageConfig.

hussainweb’s picture

I have been wondering why we are introducing a UnsupportedFieldHandler plugin here. If I understand it correctly, this plugin will skip the row if the map has missed transforming the value. Isn't that the behaviour if we just remove bypass from static_map? I am attaching a patch for this to see what the testbot thinks.

The last submitted patch, 32: d6_d8_cck_single-2262275-32.patch, failed testing.

chx’s picture

Thanks, that's a great idea, I was overcomplicating things.

hussainweb’s picture

FileSize
2.88 KB
25.11 KB

I missed out a couple of references to field_config from the old patch. I think I got them all now.

UPDATE: This builds on the patch in #33 with UnsupportedFieldHandler removed.

The last submitted patch, 33: d6_d8_cck_single-2262275-33.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 36: d6_d8_cck_single-2262275-36.patch, failed testing.

hussainweb’s picture

Status: Needs work » Needs review
FileSize
3.29 KB
24.91 KB

One of the test failures is due to a typo in field name in the test. I have fixed that with this patch. The other four failures are due to the float in keys being changed to underscore, as @ultimike mentioned in #26. From the current discussion in #2293773: Field allowed values use dots in key names - not allowed in config, we probably won't have to change the '.' to '_' once that issue is fixed. I have added a TODO in the patch for that (probably not required, but anyway).

I also reviewed the patch again, particularly changes to process/FieldSettings.php and simplified code a bit:

  1. +++ b/core/modules/migrate_drupal/src/Plugin/migrate/process/d6/FieldSettings.php
    @@ -48,6 +48,42 @@ public function getSettings($field_type, $global_settings, $widget_settings) {
    +      if ($field_type == 'list_text' || $field_type == 'list_integer') {
    

    I replaced this entire if-elseif-else block with a switch.

  2. +++ b/core/modules/migrate_drupal/src/Plugin/migrate/process/d6/FieldSettings.php
    @@ -48,6 +48,42 @@ public function getSettings($field_type, $global_settings, $widget_settings) {
    +          if (isset($value[1])) {
    +            $allowed_values[$value[0]] = $value[1];
    +          }
    +          else {
    +            $allowed_values[$value[0]] = $value[0];
    +          }
    

    I removed this (and one other) if/else blocks in favour of ternary operators.

  3. +++ b/core/modules/migrate_drupal/src/Plugin/migrate/process/d6/FieldSettings.php
    @@ -48,6 +48,42 @@ public function getSettings($field_type, $global_settings, $widget_settings) {
    +          $allowed_values_key = implode('_', explode('.', $value[0]));
    

    I changed the implode('_', explode('.', ...)) bit to a simple str_replace.

  4. +++ b/core/modules/migrate_drupal/src/Plugin/migrate/process/d6/FieldSettings.php
    @@ -48,6 +48,42 @@ public function getSettings($field_type, $global_settings, $widget_settings) {
    +        $counter = 0;
    +        foreach ($d6_allowed_values as $value) {
    +          $allowed_values[$counter++] = $value;
    +        }
    +        unset($counter);
    +      }
    

    In the last else in that block of code, I removed the entire foreach loop and simply assigned the value to $allowed_values.

I posted this bit because the interdiff might not show these in an obvious way (because of additional indentation in switch block).

There should be 8 total failures with this patch now, which are related to the decimal point in allowed values key and is dealt with in #2293773: Field allowed values use dots in key names - not allowed in config. There is no point fixing that here (or even changing it to underscore, as that might be a regression?) We'll just have to wait until that fix gets in.

Status: Needs review » Needs work

The last submitted patch, 39: d6_d8_cck_single-2262275-39.patch, failed testing.

ultimike’s picture

@hussainweb - this is great stuff, thanks so much.

Did you by any chance run a manual test to confirm that your latest patch handles the other bug I found (see comment 26, point 2) - the "missing select list (integer)" stuff? (thanks for catching the typo - doh!)

Thanks,
-mike

hussainweb’s picture

Thanks @ultimike.

I went through the comment in #26.2 and ran a manual test. I created a Integer field with Select list widget on a D6 site and devel generated 50 nodes. I ran a migration using the manifest in #2222375-6: Manual Testing: Nodes and found that the nodes in destination had the correct value set in both node edit form and node view page.

Am I missing something here? Can you please post exact steps to reproduce the problem. If it helps, I ran the test with the patch from #39 and #2306049-1: D6->D8 node migration - Handle nodes with format = 0 ? (which shouldn't matter here, but I needed it to migrate devel generated nodes).

On another note, #2293773: Field allowed values use dots in key names - not allowed in config is close to being RTBC'd, which is good news for this issue too. I think once that gets in, we won't need to make any changes here, just retest it as it is to fix those test failures (unless we have to reroll it).

ultimike’s picture

@hussainweb,

I just manually retested for the "integer select" and it appears to be working. Not sure if I goofed on my initial manual test or what happened, but based on your and my testing, it looks like we're good.

As you said, let's keep our fingers crossed that #2293773: Field allowed values use dots in key names - not allowed in config takes care of decimal selects.

Since you asked, here's the steps to reproduce my manual test for the "integer select" bug:

  1. Create a new content type (I called mine "integer select" because I'm so creative).
  2. Add a new field, type=integer, widget=select list to the content type, give it a few "allowed values" (1|One, 2|Two, 3|Three, etc...)
  3. Add a new node of type "integer select", set the integer select field to a value.

Thanks,
-mike

hussainweb’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 39: d6_d8_cck_single-2262275-39.patch, failed testing.

hussainweb’s picture

Identical failures. I will continue debugging this.

@ultimike: Just to confirm, the issue with select list is not reproducible, right?

ultimike’s picture

@hussainweb, yes, at this time, I am unable to reproduce the select list issue. Hope that's a good sign!

Thanks,
-mike

ultimike’s picture

FileSize
25.07 KB

Attached patch fixes the MigrateCckFieldValuesTest - there was some incomplete dump data.

I forgot to create a new branch to make an interdiff, so sorry.

The two main changes are:

  1. Missing db_columns array in field_test_integer_selectlist (around line 1019 of Drupal6FieldInstance.php
  2. Missing "_value" from "field_test_integer_select_value" (around lines 313, 328, and 334 of Drupal6Node.php

The MigrateFieldTest still has some issues that will need to be resolved before this patch is ready to be reviewed.

Thanks,
-mike

ultimike’s picture

Status: Needs work » Needs review
FileSize
24.98 KB
1.69 KB

Ok - I have this one to where all tests are passing.

Updated patch and interdiff attached.

Thanks,
-mike

chx’s picture

Awesome! I think I only have one question left. Given D6

function number_field_formatter_info() {
  return array(
    'default' => array('label' => '9999',            'multiple values' => CONTENT_HANDLE_CORE, 'field types' => array('number_integer', 'number_decimal', 'number_float')),
    'us_0'    => array('label' => '9,999',           'multiple values' => CONTENT_HANDLE_CORE, 'field types' => array('number_integer', 'number_decimal', 'number_float')),

why are we adding us_0 to text when the formatter only applies to number field types? Is this something somehow CCK allowed for real??

hussainweb’s picture

FileSize
683 bytes
24.95 KB

I agree with @chx in #51. I am trying to remove it and see what happens. I don't think there will be any failures.

I did a grep for us_0 in cck module in a D6 site and could not find any other usage apart from the one in number.module as listed above. I think this was a typo introduced in #15. This line was not present before the patch in that comment.

hussainweb’s picture

FileSize
1.49 KB
24.91 KB

Thanks @chx, for pointing out the field instances that need updating. As discussed on IRC, I have removed unformatted from text field formatter mapping as well.

The last submitted patch, 52: d6_d8_cck_single-2262275-52.patch, failed testing.

benjy’s picture

+++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateCckFieldValuesTest.php
@@ -87,12 +97,13 @@ protected function setUp() {
+    $node = \Drupal\node\Entity\Node::load(1);

Can we add a use statement?

chx’s picture

Thanks! This is almost ready. There's one more thing I would like to discuss (sorry for not catching it earlier): $d6_allowed_values = preg_split("/[\r\n,]+/", $global_settings['allowed_values']);. Where does that preg_split expression come from? I looked for validating with allowed_values and if I am not mistaken then http://drupalcontrib.org/api/drupal/contributions%21cck%21modules%21text... this is it and it calls http://drupalcontrib.org/api/drupal/contributions!cck!content.module/fun... which does

    $list = explode("\n", $field['allowed_values']);
    $list = array_map('trim', $list);
    $list = array_filter($list, 'strlen');

which we might actually want to keep. But first, where is that preg from? #17 says

It turns out that it wasn't parsing the allowed values from Drupal 6 but was just passing it in as a string like 'key1|value1\r\nkey2|value2', and that was causing the white screens.

I would recommend adopting the D6 code instead of inventing our own especially because our own picked up a comma from somewhere, I'm not quite sure where. Although I seem to remember having this discussion over at profile too and that was wrong, too. Also, I am reasonably sure that key|value_line1\rvalue_line2 will be completely valid in the D6 code because \r wasn't a delimiter (it was removed from the end of the line after explode by trim but it wasn't a delimiter).

hussainweb’s picture

Status: Needs review » Needs work

There are multiple things I want to bring up here:

  1. +++ b/core/modules/migrate_drupal/src/Plugin/migrate/process/d6/FieldSettings.php
    @@ -48,6 +49,25 @@ public function getSettings($field_type, $global_settings, $widget_settings) {
    +      $d6_allowed_values = preg_split("/[\r\n,]+/", $global_settings['allowed_values']);
    

    I am trying to figure out the comma, but can't find it. Like @chx says, we should just remove it and use the strategy of content_allowed_values which seems to be called from all modules.

    More to the point, the comma might actually break tests if the allowed values key or label had a comma.

  2. +++ b/core/modules/migrate_drupal/src/Plugin/migrate/process/d6/FieldSettings.php
    @@ -48,6 +49,25 @@ public function getSettings($field_type, $global_settings, $widget_settings) {
    +      switch ($field_type) {
    +        case 'list_text':
    +        case 'list_integer':
    +        case 'list_float':
    +          foreach ($d6_allowed_values as $value) {
    +            $value = explode("|", $value);
    +            $allowed_values[$value[0]] = isset($value[1]) ? $value[1] : $value[0];
    +          }
    +          break;
    +
    

    In D6 CCK, allowed values were a valid setting for text even if the widget did not allow selection. Typing in a value not present in the allowed values list would throw a validation error when creating the node. Does this make sense for Drupal 8 now? If so, we should migrate it. If not, we should document that any field using allowed values but not using one of those widgets would lose that ability.

  3. +++ b/core/modules/migrate_drupal/src/Plugin/migrate/process/d6/FieldSettings.php
    @@ -60,8 +80,22 @@ public function getSettings($field_type, $global_settings, $widget_settings) {
    +    $settings = ListItemBase::settingsToConfigData($settings);
    

    Is this necessary? The code does nothing in this case. Consider the function:

      public static function settingsToConfigData(array $settings) {
        if (isset($settings['allowed_values'])) {
          $settings['allowed_values'] = static::structureAllowedValues($settings['allowed_values']);
        }
        return $settings;
      }
    

    The if condition would always fail for the $settings array in our case. But the tests still work. I think the reason is we don't have to worry about calling this methods. Field storage takes care of that.

hussainweb’s picture

Elaborating more on #57.2, I don't think we can use allowed values for other field types. We have to document that users would lose this on migration. If they wish to avoid that, they have to change the widget on D6 site before upgrading.

hussainweb’s picture

Status: Needs work » Needs review
FileSize
2.68 KB
574 bytes
24.82 KB

Attaching patch with fixes for issues raised in comments #55, #56 and #57.

Particularly, I am removing the line $settings = ListItemBase::settingsToConfigData($settings); as I believe it doesn't do anything in this case. We have tests for checking this and if this line is necessary, the test would fail. So, let's see.

I should warn about the two interdiffs. I forgot to remove the use declaration for ListItemBase much later and I didn't have enough energy to start again. However, the patch is final with both interdiffs applicable.

ultimike’s picture

@hussainweb, @chx, @benjy,

Thanks for (hopefully) pushing this across the finish line. I just did some manual testing with the patch in 59 and didn't see any issues.

-mike

chx’s picture

Status: Needs review » Reviewed & tested by the community

I think we are good to go. As for #57.2 that's a bad joke. We can add it to the known issues pile but seriously, making you fail on text input without giving you even a hint of what you can type? That's the worst UX possible... and I doubt anyone ever used it. Anyways, I do not think we have the ability any more nor we should have it.

hussainweb’s picture

I agree about the UX part. It doesn't make sense and it is good that we don't have it anymore. But since this could be counted as data loss, I think we should at least document this somewhere (I am not sure where).

chx’s picture

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed 267202b and pushed to 8.x. Thanks!

  • alexpott committed 267202b on 8.0.x
    Issue #2262275 by hussainweb, hosef, ultimike: Fixed D6->D8 CCK Single...

Status: Fixed » Closed (fixed)

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