entity_create('some_string', $array) is pretty cumbersome to use, especially for all the test field entities that are created.
In the Entity Field API DX discussions, we agreed that adding static create would help.
Advantage:
- Can be documented with the correct @return Interface, so autocomplete works
- You don't need to remember the entity type string
- You don't have to call out to a function (you still have to call a static method, but that's already better and I think is fine in e.g. tests and procedural code)
Disadvantage:
- A few lines of code and a docblock to copy
- It could be a bit weird if someone replaces the used implementation and you'd get a different instance back than the static class you called (but I don't think this will happen often and if, will very likely be a subclass)
Questions:
Always use create(array $values) or have separate arguments for always required arguments, config entities e.g. could always include the id.
| Comment | File | Size | Author |
|---|---|---|---|
| #28 | interdiff.txt | 4.96 KB | amateescu |
| #28 | 2096899-27.patch | 6.46 KB | amateescu |
Comments
Comment #1
tim.plunkettEntity types are theoretically swappable. You could swap the 'node' entity type out for a new class. If we start using Node::create(), that will fall through.
Comment #2
chx commentedIndeed sometimes you want to denormalize something right into the Node table and do something with it; but one would need to review the node class whether you want to replace the Node for that or just NodeStorageController.
Comment #3
fagoDuring the discussion we figured this should not be a problem, as Node::create() then would just create an instance of the overridden class as a node_create() helper would do. As it's documented that it would return NodeInterface that should be fine as long as people fulfill that. (and if they don't, it's there fault)
Comment #4
chx commentedFair enough.
new staticI guess.Comment #5
msonnabaum commentedHere's a quick stab at how this could work. It shows an example of when entities would need to explicitly supply their name, but that should be the exception.
One problem I ran into on this however, is that the static entityManager property ends up in the config entities yaml file. No idea what's going on there, but it looks like we're doing some kind of introspection of properties to come up with that? Seems super fragile…
Comment #6
tim.plunkett?
Comment #7
msonnabaum commentedThis should fix the bug I described in #5.
Comment #9
berdir#7: entity-create-2096899-7.patch queued for re-testing.
Comment #10
berdirAs fancy as this is, it partially defeats one of the reasons for adding this.. having a useful @return hint for the specific entity type.
Not sure...
Comment #11
fagoI think the document @return is quite a win and worth defining it on each of the entity classes. Shouldn't be a big deal, is it?
Comment #12
msonnabaum commentedI thought the idea was that we'd either use the @method phpdoc and not override, or override and just call parent? I dont see a reason to implement any logic on a per entity basis there.
Comment #13
plachIs this public so that we can reset it?
I find this method a bit confusing: would it be so bad if we renamed it to
Entity::entityType()and dropped the non-static one?Comment #14
fagoYeah, as long as the entity-type specific return interface is documented I'm happy. But I do not see that in the patch?
I'm not sure this is really worth another static?
This should by entityType(), but that would clash with the non-static variant I guess?
Comment #14.0
fagoUpdated issue summary.
Comment #15
berdir7: entity-create-2096899-7.patch queued for re-testing.
Comment #17
yched commentedHow would this play with the fact that runtime code isn't suppose to hardcode any knowledge of the actual class for an entity type, which could be swapped ?
That's the whole point of the "entity type string name" indirection (talk about 'node' rather than Node)
Comment #18
yched commentedAlso, how would this play with #1867228: Make EntityTypeManager provide an entity factory ?
Comment #19
berdirThat's handled, currently with some magic based on the class name that can be overridden if it doesn't match. It's just a shortcut, it works exactly the same as entity_create() and uses whatever factory etc. that uses.
So, the factory issue doesn't change anything apart from having multiple static methods, one that should be called directly and the other not.
Comment #20
xjmComment #21
martin107 commentedComment #22
xjmPostponed on #2190313: Add $EntityType::load() and loadMultiple() to simplify loading entities per @Berdir.
Comment #23
webchickCan we get some clarification on why this is postponed on that one? Seems like the two could easily happen in parallel and whichever's ready first wins.
The reason I ask is there are starting to be a bunch of patches that speed up tests (yay!), but as a result they make the tests 100x more verbose and complicated (as an example, see #2254183: Fix test performance of Drupal\filter\Tests\FilterAdminTest, which Dries rightly pushes back on for this reason). If instead this logic lived in FilterFormat::create(), for example, this would not only help test authors but also distribution authors and everyone else.
Comment #24
berdirThis is postponed because all the complexity in this two patches is exactly the same. The other issue is pretty much ready, has extensive test coverage and just needs some final reviews and an RTBC.
Once it is in, then the essential part of this will be 3 trivial lines of code.
As discussed in the other issue, this will *not* make that issue and similar ones easier, all it will do is change entity_create('filter_format', ...) to FilterFormat::create(...), everything else will stay the same, the complexity that you see there is data the filter format data structures, not the API. I fully agree with @sun and @timplunkett over there that it makes the test less brittle and more explicit about what it is testing instead of relying on some default configuration somewhere.
Comment #25
amateescu commented#2190313: Add $EntityType::load() and loadMultiple() to simplify loading entities is in, so this is all we need to do here now.
Comment #26
berdirGreat. Possibly add a single unit test for create() ? ( we don't need all the variations that we added for load(), that code is already tested).
There are no wrappers for entity_create(), so nothing to deprecate, we can update the change records after it was committed...
Only thing that we could do is pick a module and update it to use this, just like we did with load(), to see it working outside of unit tests as well.
Comment #28
amateescu commentedSure, would this be enough?
Comment #29
berdirI think it is, yes :)
As mentioned above, I think we can extend the change record created for #2190313: Add $EntityType::load() and loadMultiple() to simplify loading entities, I'll also go through existing change records and update them to use the new method, just like I did there.
Comment #30
fagoThat's a good addition and goes inline with #2190313: Add $EntityType::load() and loadMultiple() to simplify loading entities. Patch looks fine as well, RTBC+1.
Comment #31
webchickAwesome, this patch makes me very happy from a DX perspective! :) And is a good complement to ::load().
Unfortunately, Tim's concerns are still unresolved. Though he did mention in IRC that #2028097: Map data types to interfaces to make typed data discoverable might help, and also acknowledged that this concern affects a very small minority of contrib. I think if this turns out to be a real limitation in a contrib module we can revisit at that time.
Committed and pushed to 8.x. Thanks!
Comment #33
berdirThanks, updated https://drupal.org/node/2266845.