Updated in comment #25
Problem/Motivation
As we are moving the code base to OOP, we want to replace entity_create()
by its OOP equivalent.
This discussion started in #2345607: Translated taxonomy terms not rendered in the entity display language where it was decided that entity_create should only be used when the entity type is unknown or stored in a variable. If the node type is known, and passed as a string, the create method should be called on the specific entity type class.
In #9, @jhedstrom suggested that this function should be replaced by a static method of EntityManager.
Between #13 and #22 it has been decided that, regarding the number of case where the entity type is variable, we should use the full call to \Drupal::entityManager()->getStorage($entity_type)->create($values)
directly.
Beta phase evaluation
Issue category | Task |
---|---|
Issue priority | Not critical because it's only about good practices |
Prioritized changes | The main goal of this issue is DX and performance. (DX because it increases code consistency and performances because it avoids call to EntityManager when they are not absolutely needed) |
Disruption | Not disruptive because the old function is only marked as deprecated and not removed. |
Proposed resolution
Add a clear comment on entity_create()
to mark it as deprecated and explain the two cases clearly.
Remaining tasks
Task | Novice task? | Contributor instructions | Complete? |
---|---|---|---|
Create a patch | Instructions | Done | |
Update the issue summary | Instructions | Done | |
Update the issue summary noting if allowed during the beta | Instructions | Done | |
Manually test the patch | Novice | Instructions | |
Review patch to ensure that it fixes the issue, stays within scope, is properly documented, and follows coding standards | Instructions |
User interface changes
None.
API changes
entity_create() is now @deprecated
Comment | File | Size | Author |
---|---|---|---|
#22 | deprecate_entity_create-2346261-22.patch | 695 bytes | DuaelFr |
#22 | interdiff.2346261.10.22.txt | 1.79 KB | DuaelFr |
#10 | deprecate_entity_create_for_entitymanager_create_helper-2346261-10.patch | 1.65 KB | DuaelFr |
#2 | 2346261-Update-entity_create-documentation.2.patch | 619 bytes | kmoll |
Comments
Comment #1
BerdirThe question is if we should actually keep entity_create() as a function, as we are removing most wrapper functions like this.
The OOP/D8 way is \Drupal::entityManager()->getStorage($entity_type)->create(). Which is a bit long...
Comment #2
kmoll CreditAttribution: kmoll commentedI created a patch that would deprecate it and add what should be done instead. As far as the debate, I am usually a fan of wrapper functions, but a bigger fan of consistency. If wrappers are being removed in core maybe it would be better to remove it and go with the entityManager.
The question I have is, should this be used only when $entity_type is a variable, as apposed to a known String, as in the case of creating a node? IE. $node = Node:create($values).
Comment #3
kmoll CreditAttribution: kmoll commentedComment #4
jhodgdonSounds like this needs to be in the entity system component for a decision on whether to document and keep, deprecate, or remove this function. And the patch doesn't accomplish what is in the issue summary either...
Comment #5
kmoll CreditAttribution: kmoll commentedThere was another issue created for it, https://www.drupal.org/node/2346253, so the patch above was only meant to handle the deprecation, if in fact that is what is decided upon.
Comment #6
kmoll CreditAttribution: kmoll commentedor maybe we should mark this as a duplicate and merge this into the patch there?
Comment #7
jhodgdonHm... That other issue at least the title is only about Taxonomy. So ... not sure. But the issue summary here is talking about documenting that this function shouldn't be used unless the entity type is unknown or in a variable, and this patch doesn't do that. Marking it deprecated is not the same thing. So we need (a) a decision and (b) probably a new patch.
Comment #8
kmoll CreditAttribution: kmoll commentedok, I agree, if we can get a decision, I can update the patch.
Comment #9
jhedstromI agree that we can't just mark it deprecated without a better replacement than the current OOP way. Many, many contrib modules use
entity_create()
, and I'd prefer at least a helper method on the entity manager so it could be called asEntityManager::create()
or some such.Comment #10
DuaelFrI came to that issue looking around for entity_create replacement rules.
I don't know where to put that patch that introduces the EntityManager::create() static method.
I didn't include the #2 patch as it seems to be applied on the wrong method.
Comment #11
DuaelFrComment #12
Dave ReidSo.... how would this work if something like file_entity wants to swap out the entity class being used for a specific entity type?
Comment #13
BerdirThat works just fine, the new method is identical to the existing one, and create() works too, it works both for the original class and the one that was replaced, I made sure of that and I'm actively using that in our file_entity port.
However, not convinced about adding a method like that here. First, it should definitely not be static. Second, we already have multiple issues about introducing factory methods and/or making the existing ones work. See #1867228: Make EntityTypeManager provide an entity factory and #2015535: Improve instantiation of entity classes and entity controllers. They would however have slightly different purpose and that's exactly the problem (creating an object vs. creating a new entity and applying default values). Naming is hard there..
Comment #14
Dave Reid@Berdir: Yeah, seeing get_called_class() in Entity::create() seemed very suspect for me, given that we'd be hard-coding calling Drupal\file\Entity\File::create() and not Drupal\file_entity\Entity\File::create() throughout core and other contrib modules.
Comment #15
DuaelFrWhat would you think about moving this method to
\Drupal\Core\Entity\Entity
and call it something likecreateFromType()
? Would it be better ?I think having a static helper for this kind of use is far better from a DX point of view than having to remember
\Drupal::entityManager()->getStorage($entity_type)->create($values);
. Although, there are only 81 occurences of this case (entity_create on a variable entity type) in Core, I think that contrib would use it a lot.Comment #16
tim.plunkettReferring to the service within itself is strange. I would just stick to using the longhand.
Comment #17
BerdirEvery example of entity_create($entity_type... that I can see in core is in tests And almost all of them are in field/entity tests. Contrib will not write tests like that. I have 55 modules in my modules folder, and exactly one call like that.
load(), loadMultiple() are actually more likely to be used in a generic way, we'd have to add corresponding methods like that as well. But again, almost all remaining calls there are in tests, everything else already has been converted to use getStorage(), often from an injected entity manager or entity storage.
This is IMHO not worth polluting the already way too big entity manager interface.
Comment #18
DuaelFrSo, what's your decision?
Do you want me to create an helper or du you want me to replace these 81 occurences by the long syntax and indicate this way to solve the deprecation?
Comment #19
webchickIt would be nice to get an answer to #18 so we could continue with #2490966: [Meta] Replace deprecated usage of entity_create with a direct call to the entity type class in some fashion. It would be a shame to ship D8 with entity_create() everywhere, given the importance of the entity API to D8 and the amount of work given to modernize other parts of the API.
Comment #20
DuaelFrI guess the answer is that we should use
or
according to the availability of the manager in the scope.
I don't really know how to write that in a comment. Do you think the following is going to be unerstandable?
Comment #21
alexpottI don't think we should add this static method. We should just tell people to do
\Drupal::entityManager()->getStorage($entity_type)->create($values);
if the entity type is a variable. I agree with @Berdir in #17 and others.Re #20 I would do something like:
Comment #22
DuaelFrIt seems that we have an agreement.
Here is the patch.
Comment #23
Crell CreditAttribution: Crell at Palantir.net commentedI prefer not adding static methods, too. :-)
Comment #24
BerdirYes, but the issue title and summary still talks about doing that.
Comment #25
DuaelFr@Berdir IS and title updated. Thank you for your review.
Comment #26
Crell CreditAttribution: Crell at Palantir.net commentedIS is now accurate.
Comment #27
alexpottCommitted 6cf71a2 and pushed to 8.0.x. Thanks!
Docs only changes are not frozen in beta.
Comment #29
DuaelFr