Problem/Motivation
The MigrateCckFieldPluginManager
class overrides the createInstance
method to create an instance using a field_type
instead of the usual plugin_id
. However, when loading definitions in CckMigration
, it uses hasDefinition
method which uses plugin_id
. While debugging, I noticed that some of the fields were being skipped because of this but they are covered by the default map present in d7_field.yml and they went through correctly. With this, and the default process map generated in the derived node migration, the migration works.
But the problem remains for more complex field types (like address field). I created a cckfield plugin with id address
and the field type in D7 is addressfield
. Because of this, the plugin is never loaded because of the outer hasDefinition
check.
foreach ($source_plugin as $row) {
$field_type = $row->getSourceProperty('type');
if (!isset($this->processedFieldTypes[$field_type]) && $this->cckPluginManager->hasDefinition($field_type)) {
$this->processedFieldTypes[$field_type] = TRUE;
// Allow the cckfield plugin to alter the migration as necessary so
// that it knows how to handle fields of this type.
if (!isset($this->cckPluginCache[$field_type])) {
$this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($field_type, [], $this);
}
call_user_func([$this->cckPluginCache[$field_type], $this->pluginDefinition['cck_plugin_method']], $this);
}
}
Given the narrow set of errors that this produces which are difficult to debug, I am marking this as major. IMHO, this should also be a migrate critical.
Proposed resolution
There are two ways to do this.
Like thecreateInstance
method, overridehasDefinition
andgetDefinition
to load by field_type instead of plugin_id.Create new methods with clear naming that indicates field_type should be used instead of plugin_id. If we do this, we should ideally rename createInstance too.- Add a new method to get the plugin id from the field type and restore createInstance to its original definition.
Remaining tasks
User interface changes
None
API changes
None
Data model changes
None
Comment | File | Size | Author |
---|---|---|---|
#8 | 2787639-8.patch | 11.72 KB | hussainweb |
#8 | interdiff-5-8.txt | 3.61 KB | hussainweb |
#5 | 2787639-5.patch | 12.15 KB | hussainweb |
Comments
Comment #2
hussainwebI am trying out a different approach altogether. I am not overriding hasDefinition or other methods but restoring createInstance to its original meaning. Instead, I am adding a new method to get the plugin id from the field type.
Comment #4
hussainwebThe tests fail because the test relies on the behaviour of createInstance we are trying to change. I will work on that. However, I just wanted to update that this worked nicely in manual tests with the process map getting updated correctly and data being migrated with nodes.
Comment #5
hussainwebFixing the failures.
Comment #6
hussainwebComment #7
phenaproximaOverall I think this looks good.
s/id/ID
Can this just be "The field type being migrated" or "The legacy field type"?
Missing (optional).
s/plugin_id/plugin ID
Can we change this to "If the plugin ID cannot be determined"?
For readability, can all of this be moved out of the try block, and just put a return in the catch?
Comment #8
hussainwebThanks for the review. All fixed. We can't put a
return
in the catch because the loop has to continue. I tried putting acontinue;
instead. Please review to see if it is more readable than before.Comment #9
phenaproximaMisspelled optional, but this is fixable on commit.
Otherwise, I like it! If nobody else has objections, I'd say this is RTBC once Drupal CI passes it.
Comment #10
phenaproximaThis is a pretty big WTF, so I'm marking it Migrate-critical. Luckily, it is also my opinion that this patch is RTBC :)
Comment #12
phenaproximaWrong!
Comment #13
alexpottCommitted and pushed cea3af0 to 8.3.x and 4607ba0 to 8.2.x and 3876957 to 8.1.x. Thanks!
Ideally this should be on an interface... but let's add that in #2787619: CckMigration does not type hint CckPluginManager correctly
Fixed on commit.