Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
EntityForm::setEntityManager should be fully deprecated, not used in core and trigger an error.
Proposed resolution
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet
Comment | File | Size | Author |
---|---|---|---|
#10 | interdiff.3052233.5-10.txt | 6.53 KB | mikelutz |
#10 | 3052233-10.drupal.Properly-deprecate-EntityFormInterfacesetEntityManager-and-trigger-an-error-on-use.patch | 9.09 KB | mikelutz |
Comments
Comment #2
mikelutzPatch attached.
Comment #3
mikelutzs/@see/See/
Comment #4
BerdirReroll and adding deprecated to the entity.manager service to see what happens if we do this.
I'm not really sold yet on the whole private thing here. If we do this then we should IMHO just clean it up properly like everything else, drop the property and rely on the trait.
Specifically, this doesn't test anymore what it used to test, the BC layer in the constructor. Setting the private property there doesn't do anything anymore and is not what is tested here, so we can just as well drop it entirely there and adopt a standard construct BC layer. This was the first such constructor change that we did around entity manager.
Comment #5
mikelutzThe reason the trait doesn't work in this case is because the trait would break the behavior of the setEntityManager() injector. The trait will always get the service from the container, so the injector would no longer do anything. In normal mode, this is probably fine, but if someone injects a mock using that method or is testing something in a unit test, the test would break.
The reason for moving it to private is specifically so the constructor BC injection layer does still work. While contentEntityForm::__construct triggers it's own error, the whole magic method is there to make sure the error is triggered anytime a subclass tries to set $this->entityForm directly. You can see it in the test you posted. === is a strict comparison, same as assertSame(). $form->entityManager refers to the exact same prophecy instance that was passed to the constructor. Because the member is private, when the subclass tries to set it, it gets funneled through the parent's __set method, and gets set anyway, we just have the opportunity to trigger an error.
In fact it might be more clear if we do remove the member and create a new private $privateEntityManager member to hold the value.
The point is that the added work here is about doing what the trait does in a similar way, but also allowing setEntityManager() to continue working, which we couldn't do if we used the trait.
The only real way this breaks is if a subclass implements their own __set or __get and doesn't pass through to the parent.
Comment #6
mikelutzComment #7
BerdirThanks for the explanation, makes sense now what it does.
I think it comes down to whether this is something we care about:
Do we care about such IMHO rare cases that would AFAICS only break (unit) tests which would quite likely already be broken as we ourself on longer use $this->entityManager.
Or are we just going to say that code needs to be updated anyway and adding that logic to support it isn't worth it. IMHO, it's not :)
Comment #8
alexpottShouldn't this set the private entity manager now? ie.
$this->privateEntityManager
? Or we want this to invoke the magic __set()? I guess it doesn't matter. Looks odd though.Re the trait vs private discussion - I'm assuming that @Berdir is suggesting we use
\Drupal\Core\DependencyInjection\DeprecatedServicePropertyTrait
and @mikelutz is pointing out that this would break the \Drupal\Core\Entity\EntityForm::setEntityManager() method.At this point I'm not sure it really matters either way. I think on balance I'd err towards @mikelutz's solution because we're adhering better to the BC promise. Therefore going to rtbc.
Comment #9
mikelutzYes, that should set the private entity manager.. There's no need to trigger both errors by running through __set.
Also, the deprecation messages need updating. I originally wrote this before the format was finalized.
Updated patch incoming.
Comment #10
mikelutzComment #11
alexpottLooks good. I should have spotted the message formats. Nice work.
Comment #12
mikelutzThanks!
Comment #13
larowlanComment #14
larowlanCommitted 668e08a and pushed to 8.8.x. Thanks!
Comment #17
joachim CreditAttribution: joachim as a volunteer commentedUnfortunately, this patch breaks any subclasses that are lazy about declaring class properties: #3094913: EntityForm's use of magic setter/getter breaks any subclasses that don't declare a property.
Comment #18
joelpittet@joachim Same here #3097934: Fatal error on admin page
I'm wondering if @mikelutz for BC it should create an array property for default getters and setters that are used?