Problem/Motivation
The Entity migrate destination plugin doesn't implement the fields() method, and so does not allow reporting of the available fields of the destination entity.
This means that developers can't get a listing of the destination fields to help them when writing a migration. This is a blocker for #2630718: Implement drush migrate-fields-destination.
Steps to reproduce
Look at the code:
public function fields() {
// TODO: Implement fields() method.
}
;)
Proposed resolution
Implement the method in EntityContentBase.
The method should return both base fields on the destination entity type and bundle fields. To detect the destination bundle, the following methods should be tried, in this order:
1. the migration's destination configuration specifies 'default_bundle'
2. the destination entity type has no bundles, in which case there are no bundle fields (e.g. user)
3. the destination entity type has only 1 bundle, it must be that one (e.g. if there's only the 'article' node type defined)
The EntityContentBase class will need the 'entity_type.bundle.info' service injecting.
Remaining tasks
Make a followupAdd missing return type in the kernel test. (See Comment #144. Novice task.)- Rebase on the current 11.x and resolve conflicts from #3474640: Drupal\Tests\migrate\Unit\destination\EntityRevisionTest uses weird mocking pattern. (See Comment #150. Novice task.)
User interface changes
None.
API changes
The \Drupal\migrate\Plugin\migrate\destination\EntityContentBase::__construct() method has an additional parameter,\Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info.
Classes that extend this will need to add the parameter to their call to the parent __construct().
Data model changes
None.
Release notes snippet
N/A
Original report by mikeryan
Went to implement #2630718: Implement drush migrate-fields-destination and got no output, because:
public function fields(MigrationInterface $migration = NULL) {
// TODO: Implement fields() method.
}
D'oh!
Some introspection necessary here. Ideally, if we followed the D7 migration model, the destination instance in a migration would have a specific bundle assigned, so we would be able to retrieve bundle-specific fields here. That's not true in D8, the bundle is assumed to be pulled per-row from the source data so can't be statically determined. That's... unfortunate, and would seem to require an architectural change (I would love if destinations could be configured like entity:node:article). But at least for now we can pull the base properties here.
| Comment | File | Size | Author |
|---|---|---|---|
| #169 | entity-fields-migration-destination-10.4.x-2630732-169.patch | 76.29 KB | smulvih2 |
Issue fork drupal-2630732
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
mallezieThis does the trick for the base fields.
We should look how we could get the more granular fields for each bundle. Not only for the drush command, but also for the UI. #2470916: Implement the migration detail page
Perhaps we should split this up, add the basefields here, and discuss the architectural changes needed to get the bundle specific fields in a seperate issue.
Comment #3
heddnSome of the boilerplate for this could probably be grabbed from the patch at #2642612: Create Entity Lookup & Generate process Base plugins.
Comment #4
heddnThe hard part is knowing the destination bundle. Because it isn't always required (bundle-less entities) nor is it in the same place or named the same thing across different types of entities (taxonomy terms use vocabulary, nodes use type, other entities use something different).
Comment #6
mikeryanComment #7
mikeryanLet's do this after #2700581: Destination bundle set in destination plugin, not in process, and support bundle fields when the destination has a bundle set.
Comment #8
mallezieSince #2700581: Destination bundle set in destination plugin, not in process is getting close, i started rerolling and expanding this one.
I added the base fields and expanded with all the fields.
Comment #10
mallezieI can probably fix the test fails here, but i'm not sure if injecting the EntityFieldManager and thus changing the constructor is even allowed from a BC perspective.
If anyone could confirm this is the good or wrong direction, i'm happy to work further on this, and bring this home.
Comment #11
mallezieJust a small test to see if i can figure out how to fix the test fails. This should fix 1 of the failing tests.
Comment #13
mallezieNext try, should work ;-)
Comment #15
mallezieBetter create the correct patches, so ignore the previous one
Comment #17
mallezieAnd some more test fixes. Next up writing tests for the new code.
Comment #18
mallezieWoohoo test pass. However not sure how to add a test for the new method. So need to leave this open. Anyhow blocked on #2700581: Destination bundle set in destination plugin, not in process before this is functional and can be tested. So gonna leave it open for now.
Comment #19
mallezieAnd #2700581: Destination bundle set in destination plugin, not in process is in!
Comment #21
sylus commentedThe patch was no longer working for me in 8.x-2.x-dev:
The file
EntityFile.phpno longer has its constructors and merely extends from EntityContentBase.php so I have just removed that file. Finally I have corrected the minor issue with a comment inEntityUser.phpComment #22
sylus commentedComment #24
mallezieThanks, i rerolled your work against 8.3.x, and fixed the new test fails. This is probably 8.3.x material at this time.
Comment #25
heddnMostly nits & questions. The last one, if I understand what is going on correctly though, should be addressed.
Should this be $this?
Does this handle revisions too? I'd like to see a test using both a revision and a non-revision.
New code, is it possible to use the new array syntax? Check around, are we already using it in this class?
I think we should do an if/else here. If we have the default bundle, no need to add extra fields into the mix.
i.e. if default bundle... gather them. else gather all from base field definitions.
Comment #26
mallezieThanks for the review.
1. Since protected static function getEntityTypeId() is a static function and Entity is an abstract class self is more appropriate if i recall correctly.
2. No other arrays in this class, but changed to new syntax. Nice catch.
3. It's actually the other way around, when a default_bundle is around we can add the default specific fields. This value is set in the migration destiny. it was added in #2700581: Destination bundle set in destination plugin, not in process. So i think this way is correct. Add the default entity fields, and when we got the bundle specified in 'default_bundle' add the bundle specific fields as well.
I don't think revisions are on order here. Migration destinations are not revisionable AFAICT.
This indeed needs some tests, but i have not really an idea how to start with those tests.
Comment #27
mikeryanNo BC change here, no reason we can't get this into 8.2.1 or 8.2.2.
Comment #28
mikeryanOoh, should've actually looked at the patch first, adding entity field manager into the middle of the constructor arguments, so that is a BC break (which, we're trying to be done with as of 8.2.0).
For BC, could we add that to the end of each constructor as an optional argument, so any classes extending those destinations won't break?
Comment #29
mallezieThanks for the feedback. This causes some inconsistency in the constructors, but that's probably not a problem. Let's remove also the test changes, to see if this is acutally BC.
Comment #30
mallezieWith help from @chx, i rewrote the fields method, and finally found a way to add a test.
Instead of showing only basefields for a destination we return all fields from all bundles of the entity. This is actually also more logical, and does what the interface says, show all posibble destination fields.
I also added a test, and did some minor code changes. Interdiff is added to be complete, but almost size of the patch.
Comment #31
mallezieJust to note: According to me the entity destination class is actually untested.
Comment #32
ckaotikThanks all for the work on this!
Just tried the patch, and found a problem: This fails with a LogicException when the entity type is not fieldable (see EntityFieldManager::buildBaseFieldDefinitions). This is the case, for example, when migrating node type configuration entities and probably quite common.
Comment #33
heddnRemoving the bc breaking tag since we're providing the additional construction argument.
Comment #35
sylus commentedJust attaching an updated patch to apply to both 8.3.x + 8.4.x branch (minor adjustments to
EntityComment.php. Pushing to needs review just to trigger testbot.Comment #36
ckaotikThanks for the reroll. We still need to address the exception thrown on non-fieldable entities (e.g. config entities or custom content entities), which is probably easier once we have a test for that :)
$this->entityFieldManager->getFieldDefinitionsand$this->entityFieldManager->getFieldStorageDefinitions($entity_type_id);will both throw a LogicException in \Drupal\Core\Entity\EntityFieldManager::buildBaseFieldDefinitions viaBasically, we might add that check ourselves and just bail out if the interface is not implemented by our destination entity type.
Comment #37
heddnDo an is_subclass_of makes sense. I would expect that.
Comment #39
Ben Buske commentedWe tried this patch with a book migration wich has as destination "plugin: book".
Because the function getEntityTypeId just cuts the first 7 letters to remove "entity:" that fails.
As quick fix we used this code:
Comment #41
joachim commentedPatch doesn't apply on 8.5.x unfortunately.
Comment #42
jofitzReroll.
Still need to address #36.
Comment #43
heddnI've just added a check for #36 over in #2935951-59: Copy migrate source plugin from migrate_drupal_d8 into migrate_drupal. Thanks for the pointer.
And I've added the same check here. And moved the fieldable logic down into EntityContentBase. I'm assuming that config entities are normally not fieldable. There's also tests now, so I've removed that tag.
Comment #44
heddnAnd cleaned up the DI and imports for the base Entity class here.
Comment #47
quietone commentedCame across this waiting for a long test to run.
Fixed the failing test by declaring the entityFieldManger in EntityContentBase. Also did some renaming of the test migrations and node type to something more descriptive that just appending a '2' to signify the difference. The intentions was to make the code easier to understand.. There are also several fixes for coding standards.
Comment #49
quietone commentedRetest with 8.6.x
Comment #50
heddnNeed to figure out a solution for the problem with not knowing the destination bundle. Since we don't know it, we cannot really pull up destination fields.
Perhaps we "standardize" on a method to designate the destination bundle that is optional. But if it is used, then trigger the Entity::fields logic for a destination.
My proposed standard is entity:node:page or entity:node:blog, etc.
Bumping back to NW for this piece.
Comment #51
mallezie@heddn i'm not really sure i can follow the comment, as i saw it initially (and seems the patch still follows that). We can only show the base fields when we don't have a bundle specified. When we don't specify the bundle, the migration can migrate to different bundles in one migration, so we can't set a default one here?
This would mean, that fields() can only return the fields it's certain about, not all possible fields, but i think that's good. Better showing only correct fields, even if that means those are not all available fields, then showing possible 'wrong' fields.
Comment #53
heddnIf we want to do this in 2 phases. Show base fields and bundle fields in a follow-up, that's fine. Let's open the follow-up though and link it in as an @TODO in this patch.
Comment #55
joachim commentedReroll of #47 for 8.7.x.
I'm assuming the 'default_bundle' property is something this patch invents -- so it needs to be documented in the class docs for the destination plugin.
I don't really follow #50 either... is 'default_bundle' not sufficient here?
Comment #56
mallezie'default_bundle' was introduced in #2700581: Destination bundle set in destination plugin, not in process
Since an entity migration can migrate to different bundles in one migration we cannot specifiy the 'non' base fields of the target entity. When the migration specifices the 'default_bundle' property, we know it migrates to that specific bundle of the entity, and can request the non base fields of that bundle to add them in the destination.
I think #50 also missed the introduction of that in the 'preceeding' issue where it was introduced.
Comment #57
yonailoHello,
Two small issues related this patch (#55) maybe worth saying :
When testing a 'drush mfd' command (see: https://www.drupal.org/project/migrate_tools/issues/2630718) for a paragraphs destination migration. I have found that 'self::getEntityTypeId($this->getPluginId());' should be replaced by 'static::getEntityTypeId($this->getPluginId());'
inside the EntityContentBase:fields() function.
Afterwards, I also had to modify the _construct() function of EntityReferenceRevisions and EntityRevision classes to add the last parameter $entity_field_manager.
With these two small modification, I was able to execute the drush command that shows all migration destination fields for my paragraph type.
Hope this helps.
Comment #59
Ben Buske commentedrerolled for 8.8.x
Comment #60
mikelutzNW for reroll, #53 and #57
Comment #61
shubham.prakash commentedThis should fix the php error.
Comment #63
shubham.prakash commentedThis should fix the failed test case.
Comment #65
aleevasAdded fix for failed test
Comment #66
mikelutzThis is still NW for #53 and #57
Comment #67
aleevasLooks like all changes that was offered in #57already implemented in 8.9 branch:
Comment #69
joseph.olstadPatch needs reroll for 9.1.x
Patch applies cleanly to 9.0.x
Comment #70
kishor_kolekar commentedComment #71
kishor_kolekar commentedI have re-roll the patch for 9.1.x
Comment #72
kishor_kolekar commentedComment #73
mikelutzThe test module here needs to be updated to work with Drupal 9.
Comment #74
ridhimaabrol24 commentedTrying to fix the test cases
Comment #76
ridhimaabrol24 commentedFixing failed test!
Comment #77
quietone commentedStarted to review this and the changes to the User entity caught my eye, Why are those needed? They are not, so they are gone. And I've added a test for a user destination for verification. That required a changed to EntityContentBase::fields to get the fields for an entity that does not have bundles and therefor would be not setting the 'default_bundle' in the destination plugin configuration.
Comment #78
heddnI think we can also pass the bundle in other ways. We should also return early or do some logic around this for when we don't know the bundle but the entity type is a bundle-able entity. I'm OK with not returning all the bundle fields, as returning something is better then nothing. But we should at least be a little more defensive.
Comment #81
joachim commented@heddn I don't quite follow your points in #78.
> I think we can also pass the bundle in other ways
Could you say what other ways? Do you mean we should check for other ways in which the migration's destination bundle is defined in the migration?
> I'm OK with not returning all the bundle fields, as returning something is better then nothing.
Is the 'not' a typo in that sentence? It seems to contradict itself!
I agree this isn't quite right. For one thing, if a developer forgets to put in 'default_bundle' and it IS an entity type with bundles (maybe they are mapping the bundle from source data?), then this will take the entity type ID as the bundle, and pass it to entityFieldManager->getFieldDefinitions()... which will possibly throw an exception for an invalid bundle?
Comment #82
joseph.olstadReroll for no-fuzz on 9.3.x.
The patch has been in use for over a year with the WXT distribution. The patch applies on D9.1.x
If someone has a specific suggestion with the patch or implementation please provide helpful feedback.
There's no interdiff for this, straight up reroll.
Comment #83
joseph.olstadwow ya, code style restrictions, ftlog.
Comment #84
heddn$migrationisn't used, nor is it on the parent method. Do we need it?A bundle can be provided in 2 or 3 different ways.And if isn't set by default bundle, we would pass null value along to$this->entityFieldManager->getFieldDefinitionsand get PHP errors.But let's take node as an example. There are base fields on it we could return; so return those, at least.
We can try some of the other common ways to get the "bundle".Actually, that isn't really true. At the point thatfields()is called, there be might be very little context provided. The only thing we really have is "default_bundle", because we don't have a Row object. But that means, we need to just return the base fields without any bundle ones. i.e.getBaseFieldDefinitionsComment #85
joachim commentedThanks for clarifying @heddn
> We can try some of the other common ways to get the "bundle".
> At the point that fields() is called, there be might be very little context provided.
Here's what I think we can try at that point, in the order to attempt them (and complexity)
1. default_bundle
2. if the destination entity type has no bundles: there are no bundle fields (e.g. user)
3. if the destination entity type has only 1 bundle, it must be that one (e.g. if there's only the 'article' node type defined)
4. if the bundle field on the destination entity is mapped from a constant value, it's that
5. if the bundle field on the destination entity is mapped from a source field, and that source field is in the source query as a fixed value condition, it's that
I'm not sure about whether 4 is worth the effort. 5 is definitely not worth the effort IMO. 2 and 3 are pretty simple though.
Comment #86
heddnI think I agree about 1,2,3. But 4 and 5 require data outside the scope of the destination and might not be data available so let's keep it simple for now. maybe we can hit those in follow-up issues, if we even think that is worth it.
Comment #88
joachim commented> I think I agree about 1,2,3. But 4 and 5 require data outside the scope of the destination and might not be data available so let's keep it simple for now. maybe we can hit those in follow-up issues, if we even think that is worth it.
Agreed. Maybe a follow-up for 4.
Comment #89
quietone commentedCame to review but the IS is not up to date. In #85 and #86 it was agreed that certain cases should be implemented. Has that happened? Tagging for IS update.
Comment #90
joachim commentedDone.
Comment #91
joachim commentedComment #92
quietone commented@joachim, thanks that helped!
Comment #93
joachim commentedWorking on fixing the tests...
Comment #94
joachim commentedFixed tests and moved stuff from the test module into the test class as in the review.
Unsure about a couple of points in @quietone's review -- see review threads.
Comment #95
joseph.olstadThe above merge request no longer applies cleanly to the head of 9.3.x
The source branch is 379 commits behind the target branch
Comment #98
mikran commentedRebased and conflicts fixed.
First push was rebase to 9.3.x but then I realized I need to do it to 9.4.x and that is the second push. No conflicts with the second one.
Comment #99
joachim commentedRebased to 9.4.x.
Comment #100
quietone commentedIn Slack, joachim asked me to review this.
Comment #101
quietone commentedComment #102
joachim commentedI don't seem to be able to get to the MR comments to mark them as resolved -- possibly because I've rebased?
Anyway, points from reviews have been addressed:
- documentation of new @throw
- moved new test into the existing class.
Comment #103
joseph.olstadthis patch is a snapshot of todays MR 902
https://git.drupalcode.org/project/drupal/-/merge_requests/907.diff
Comment #107
joseph.olstadnew patch for D10.0.x / D10.1.x
straight up reroll of #103
Comment #108
joseph.olstadComment #109
benjifisherThe issue description makes this seem straightforward: implement the method. But looking at the patch, it seems more complicated than that. We are adding parameters to constructors, for example. I see some discussion of backwards compatibility (BC) in Comments #10, #28, and others. But I would like to see that discussion (and why we need to change the constructors for this issue) in the issue summary, so I am adding the tag for that. It will be easier to review this issue if we do not have to read all the comments to get that explained.
The patch in #107 failed static analysis. Unfortunately, the testbot does not set the issue to NW when that happens, so I am changing the status now. Just looking at the PHPStan report, and not looking too closely at the patch, it seems that the static analysis is catching a pretty serious problem:
Comment #110
joachim commented> We are adding parameters to constructors, for example. I see some discussion of backwards compatibility (BC) in Comments #10, #28, and others.
Adding to constructors is a fairly standard change. We need the bundle info service to get the bundles of the entity type in question.
We do need to add BC handling, even though technically it's internal, as lots of things will be extending this class.
> But I would like to see that discussion (and why we need to change the constructors for this issue) in the issue summary, so I am adding the tag for that. It will be easier to review this issue if we do not have to read all the comments to get that explained.
That's already in there, where it says "To detect the destination bundle, the following methods should be tried, in this order".
Comment #111
sakthi_dev commentedResolved the custom command fails.
Comment #112
joachim commented> 2. the destination entity type has no bundles, in which case there are no bundle fields (e.g. user)
It occurs to me that it would still be possible to define bundle fields on an entity type with no bundle. For example, you might have something that always defines fields as bundle fields, on different entity types.
I've not checked the code, but what it should do here is take the one single bundle that's defined by default by the entity system.
Comment #113
sakthi_dev commentedComment #115
sylus commentedJust attaching a re-roll for 9.5.x so patch works against 9.5.10
Comment #116
sylus commentedJust attaching a re-roll for 9.5.x so patch works against 9.5.10
Comment #119
donquixote commentedAt first I wanted to rebase the original MR, but this was not practical.
So now a new MR.
Comment #120
joseph.olstadComment #121
smustgrave commentedLeft some comments on the MR.
I see @quietone has been involved so the submaintainer tag may not be needed but added just in case.
Comment #122
vlyalko commentedThe patch #113 no longer applying for me in 10.3
Comment #123
jan kellermann commentedI post our patches for D10.2(.7) and 10.3.
The patches are the changes from patch 113 adapted to the current code.
We are not doing migrations at this time, so it is not tested for migrations in real life.
Comment #125
benjifisherIn Comment #109, I asked for an issue summary update.
In Comment #110, the tag was removed without updating the issue summary.
Comment #121 adds the tag for subsystem maintainer review. Please do what the subsystem maintainer requests before adding that tag back.
Since DrupalCI shut down, we no longer run automated tests on patches. If anyone cares to move this issue forward, then it would help to convert the latest patch to a MR (and to update the issue summary).
I am hiding the original MR (for 9.4.x). The newer MR (for 11.x) needs work.
Comment #126
benjifisherComment #127
joachim commented> We are adding parameters to constructors, for example. I see some discussion of backwards compatibility (BC) in Comments #10, #28, and others. But I would like to see that discussion (and why we need to change the constructors for this issue) in the issue summary, so I am adding the tag for that. It will be easier to review this issue if we do not have to read all the comments to get that explained.
We need to change the constructors because the EntityContentBase class will need the 'entity_type.bundle.info' service injecting so it can know about bundles.
I do not think this sort of detail needs to be explained in the proposed resolution. Adding a service is like adding a variable.
Comment #128
benjifisherThanks for updating the issue description.
It would be nice to finish up this old issue.
I had a look at the MR. (I got most of the way through it, but it is getting close to bed time.) I may have more comments the next time I review it.
I left some suggestions on the MR. @smustgrave, in #121 you said that you also commented on the MR, but I do not see those comments.
I am afraid that the MR also needs to be updated to resolve conflicts.
I am also not sure why this issue ever had the tag for subsystem maintainer review. Not every issue in the migration system needs that. Like most Drupal issues, it needs someone to write the code and someone to review it. In general, changing the status of an issue from NR to NW is not a good way to get the attention of the migration maintainers.
Comment #129
joachim commented> ?AccountSwitcherInterface $account_switcher = NULL
$account_switcher should not be optional here.
It was optional for BC, but that handling was removed in f58fccc2fc690b62e1beac6a6d1c2b3d8a61c31a -- #3261004: Remove deprecated code from the migration system . The parameter should have been changed in that issue!
Fixing that here, but happy to cherry-pick it to a separate, blocking issue if preferred.
Comment #130
joachim commentedI've addressed all the points in the review.
The MR is not letting me ticky things to say I've resolved them though :/
Comment #131
benjifisherI replied to a few threads on the MR.
Since the MR adds a parameter to the constructor of
EntityContentBase, this counts as an API change. This class is intended to be extended, so it cannot befinalnor@internal.The API change should be documented in the issue summary, under the "API changes" section. I am adding the tag for an issue summary update again.
We also need to deprecate calling the constructor without the new parameter. See the "Constructor parameter additions" section in Drupal deprecation policy.
Comment #132
joachim commentedDone.
Comment #133
quietone commentedI modified the test to use a mock migration and that lead to changing variable names and moving things around a bit. Also, some other minor changes and removed an item from the phpstan baseline. Curious that that was not discovered when running the commit checks locally.
Comment #134
benjifisherI think that difference is explained by this code block in
commit-code-check.sh:Comment #135
benjifisher@quietone, thanks for working on this issue.
I made several suggestions on the MR. Most of them are minor, like adding the optional comma at the end of an argument list. If you feel strongly about using the plugin manager in the test class instead of the helper function, then I will not insist.
In #128, I wrote,
I have now reviewed the entire MR.
We need a change record to document the API change, so I am adding the tag for that.
I am adding a tag for a follow-up issue because of the comment on
core/modules/migrate/tests/src/Unit/destination/EntityRevisionTest.php.Comment #136
joachim commentedI think I've addressed all the comments apart from the ones about createDestination().
I tried adding a plugin ID to createDestination(), but then hit the problem that createDestination() uses the $this->storage property, and in the testFields() test we are using a different entity type.
I find createDestination() a bit problematic, as it's a mixture of taking parameters and reading properties, and updates a property rather than returning the destination object. For testFields() which sets up the a destination plugin multiple times, not explicitly seeing $destination being changed worsens readability.
> We need a change record to document the API change, so I am adding the tag for that.
I don't see why we need this. It's not an API change - the fields() method was there all along, just that EntityContentBase was failing to correctly implement it. If anything, this is a bugfix.
Comment #137
benjifisherThere are arguments on both sides of using
createDestination()(previous two comments). As I said, I will not insist: we can agree to disagree. Still, from the MR comment:and
I did run the test with the suggested changes. Probably it fails if you apply some but not all of them. But the basic pattern works:
It turns out that is not needed. Just setting
$this->storageis enough.It is both a bug-fix and an API change.
Custom or contrib modules may extend
EntityContentBase, just as some of the core destination plugins do. If so, then those modules will need to add the new parameter, just asentity:commentandentity:userdo in this MR.Another way to put it: in order to fix the bug, this issue makes an API change.
Thanks for updating the MR. I do not have time now to re-review.
Comment #138
benjifisherI did another round of review. Some of my earlier comments were not addressed, and I added a few new comments on the MR.
Let's make sure the PHPUnit tests pass.
Comment #139
joachim commentedCR done and I think that's the rest of things fixed.
Comment #140
benjifisherThanks for the updates. This is very close: just one more
@varcomment should be nullable. (See the MR.)Thanks for the CR. I added a line, and I am removing the issue tag.
Follow-up issues
I am removing these lines from the issue summary:
In my opinion, that is a bad idea. The migration plugin knows about the destination plugin, and should pass configuration to it. The destination plugin should not know about the migration that is using it. Implementing this suggestion would add a lot of complexity to the system in order to make a small DX improvement when writing migrations. (See also Comments #86, #88, ...)
Thanks for adding #3474640: Drupal\Tests\migrate\Unit\destination\EntityRevisionTest uses weird mocking pattern. I am adding it as a related issue.
I added #3477244: Add return-type declaration to Drupal\migrate\Plugin\MigrateDestinationInterface::fields(), but I am not sure how we implement a change like this. If we just add a return-type declaration to the interface, then we will break any class that implements the interface and does not already have that declaration.
I am removing the issue tag for a folow-up.
Comment #141
joachim commented> In my opinion, that is a bad idea. The migration plugin knows about the destination plugin, and should pass configuration to it. The destination plugin should not know about the migration that is using it. Implementing this suggestion would add a lot of complexity to the system in order to make a small DX improvement when writing migrations. (See also Comments #86, #88, ...)
Yup, it would certainly add a lot of complexity. Fair enough that it's too much, and architecturally dubious, for a minor DX improvement.
I've applied your suggestion for the nullable type to the MR.
Comment #142
benjifisherThanks for all the work on this, @quietone and @joachim! I think this issue is ready to go.
Comment #143
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #144
benjifisherThe MR no longer applied.
I rebased on the current 11.x, and the only conflict was in
core/.phpstan-baseline.php. There is a single commit, removing one item from that file. The context (3 lines above and below the removed item) has changed, so that commit did not apply. During the rebase, I skipped that commit, then made the same change in a new commit.Given the nature of the change, I feel I can do that and still keep my role as a reviewer of this issue.
Now that the merge conflict is resolved, PHPStan complains:
That should be easy to fix, but it is a little more than I should do as a reviewer. I am leaving the status at NW, and adding the Novice tag to add a return type to that function.
Comment #145
lavanyatalwar commentedWorking on it.
Comment #146
lavanyatalwar commentedHeyy @benjifisher,
Fixed the missing return type issue.
Kindly check :)
Comment #147
lavanyatalwar commentedComment #148
benjifisher@lavanyatalwar:
Thanks for fixing that. It may feel like a small thing, but helping to finish an issue that is 99% done has as much impact as completing an unstarted issue all by yourself.
Some unrelated tests were failing. That seems to happen a lot recently. Maybe I should add a note on #2829040: [meta] Known intermittent, random, and environment-specific test failures, but I was lazy and just re-ran the failing tests. They all pass, now.
Back to RTBC, The CI job and I agree that @lavanyatalwar correctly added the return type reported by PHPStan. I am updating the "Remaining tasks" in the issue summary and removing the Novice tag.
Comment #149
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #150
benjifisherNo good deed goes unpunished: our follow-up issue #3474640: Drupal\Tests\migrate\Unit\destination\EntityRevisionTest uses weird mocking pattern was recently Fixed, and it creates a conflict with this issue.
Resolving the conflict is a little more than what I am comfortable doing while acting as a reviewer on this issue. (I already did that once: see Comment #144. The changes now are a little more complicated.)
I rewrote the git history, combining all the commits that change
core/modules/migrate/tests/src/Unit/destination/EntityRevisionTest.php, and force-pushed. You can confirm that I only changed history by comparing with the tag for the previous HEAD of the feature branch:That should make it easier to rebase on the current 11.x. I think that is considered a Novice task, so I am adding that tag again.
When rebasing, pay attention to the improvements that #3474640 made to the other class variables:
reveal()in thesetUp()method, not the test/helper method(s).Comment #152
baltowen commentedHi, I attempted to resolve the merge conflict, please review.
Comment #153
benjifisher@baltowen:
Thanks for working on this issue. Unfortunately,
core/modules/migrate/tests/src/Unit/destination/EntityRevisionTest.phpfails after the changes you made. Back to NW.There are also some unrelated tests that fail. For now, do not worry about those.
This issue adds the
$entityTypeBundleclass variable to the test class. After your rebase, that variable is handled correctly: callreveal()in thesetUp()method, not in the test methods. But your rebase also changes the way$storageis handled. That is not in scope for this issue, and Comment #4 on #3474640: Drupal\Tests\migrate\Unit\destination\EntityRevisionTest uses weird mocking pattern explains why that one variable should not follow that pattern.If you undo the changes to
$storagein the test class, then that test should pass. Then we can worry about any unrelated test failures.Comment #154
baltowen commentedThanks @benjifisher for the review. I have reverted the change of
$storage.Comment #155
benjifisher@baltowen:
Thanks for fixing that. There is still one line that needs to be fixed: see my comment on the MR. I wish I had caught that sooner.
There is also one unrelated test failure:
Drupal\Tests\block\Functional\BlockCacheTest::testCachePerPage. Again, let's not worry about that until we fix the problem we know about.Comment #156
baltowen commentedBack to needs review.
Comment #157
benjifisher@baltowen:
Thanks for fixing that.
Next time around, please add additional commits instead of making your changes as part of a rebase. I had to compare to the tag
previous/2630732-11-x-migration-destinations-entity-fields/2024-11-05in order to make sure that there were no accidental changes added during the rebase.The merge conflicts were in
core/modules/migrate/tests/src/Unit/destination/EntityRevisionTest.php. I reviewed that carefully, and the changes there look good to me. Back to RTBC.Comment #158
benjifisherComment #159
benjifisherI forgot to review the failing tests:
Drupal\Tests\image\Functional\ImageStylesPathAndUrlTest::testImageStyleUrlAndPathPrivateDrupal\Tests\responsive_image\FunctionalJavascript\ResponsiveImageFieldUiTest::testResponsiveImageFormatterUiI added a note to #2829040: [meta] Known intermittent, random, and environment-specific test failures and re-ran the tests. They both passed.
Comment #161
smulvih2I was using 6111.diff as a patch in composer for core 10.3.6. Commits pushed in the last 1-2 days broke this and now it no longer applies. Here is a patch that captures all the latest changes and still applies to 10.3.x.
Comment #162
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #163
liam morlandThe bot is wrong; the patch is for Drupal 10.3.
Comment #164
larowlanThe deprecation links in the MR need to point to a change record, other than that there seems to still be a lot of open threads.
Can we get those resolved please? If the only change is to the deprecation link URLs, fine to self RTBC
I believe this one has required a few re-rolls so feel free to ping me for another look - thanks everyone
Comment #165
liam morlandI have updated the link to point to the change record.
Comment #166
benjifisherI resolved several threads. I left open the ones where I made a suggestion and it has not been implemented. I still think these are improvements.
Unfortunately, one fix seems to have been lost, so back to NW. It is pretty small: just a missing
|nullin an@varcomment.Comment #167
liam morlandI have rebased and fixed the missing comment mentioned in #166.
Comment #168
benjifisherI reviewed all the changes, and I do not see anything else that got lost.
I still think it is a bad idea to cast to
stringinEntityContentBase::fields(), and some of my other suggestions would be improvements. But I will not insist on those changes, so RTBC.Comment #169
smulvih2Patch #161 not working with 10.4.x, which is supposed to be LTS for D10. Tested patch created from the merge request's latest commit ID
021da95fand works with 10.4.x, adding patch here.Comment #170
quietone commentedThe are conflicts in the phpstan baseline.
@smulvih2, Yes, Drupal 10 is an LTS, but not all changes will be backported. There is more detail on that at release overview page and the allowed changes in each version.
Comment #171
benjifisherAs in Comment #144, I think I can rebase and resolve the conflict in
.phpatan-baseline.phpeven though I am the reviewer of this issue. Back to RTBC.The conflict was caused by #3486713: Bump PHPStan to version 2.0.4, which changed the format of the baseline file.
Comment #172
heddnSince Benji RTBCed this, I'm going to assume his suggestions/comments on the MR can be resolved at this point. That is now done. Otherwise, +1 on RTBC.
Comment #173
benjifisher@heddn:
In Comment #166, I wrote,
and in #168,
I think you may have resolved some threads that I intentionally left open.
Comment #175
catchThis all looks good. I had to update the deprecation message to reference 11.2.
Committed/pushed to 11.x, thanks!
Comment #178
catch