Right now entity_load_unchanged()
simply wraps a cache clear + entity load. In OO code it's not recommended to call procedural functions which live in the global scope, hence we need to inject the entity manager and retrieve the proper storage controller. Since the load unchanged logic lives only in the function above, OO code needs to recode it every time. Although the implemented logic is quite simple this in not exactly DRY.
See #1807692-82: Introduce a column synchronization capability and use it to translate alt and titles through the image field widget and below.
Comments
Comment #1
plachHere is a patch.
Comment #2
sunLooks fine to me.
Just one thing: Can we make the method body in ConfigStorageController identical to DatabaseStorageController, please? The resetCache method exists, and is merely empty right now, but we want to change that in #1885830: Enable static caching for config entities
Comment #3
plachHere it is.
Btw, would it make sense to have an abstract
BaseStorageController
as a common ancestry between database and config storage controllers to avoid repeated code?Comment #4
sunThanks!
Yeah, I totally thought of a EntityStorageControllerBase a couple of times already, too. We might want to do that as part of #1893772: Move entity-type specific storage logic into entity classes.
Comment #5
plachYes, I was thinking about that one too :)
Comment #6
BerdirNitpick, but the @param and @return should specify the type.
Comment #7
plachThere is no fixed type for the entity ID, right?
(no interdiff I just edited the patch :)
Comment #8
BerdirThanks.
Comment #9
catchHmm while we're moving this could we rename it to loadUncached() or similar?
Comment #10
plachNot sure about this: currently the method name describes what you'll get, if we rename it we are exposing how we provide the unchanged stuff, which may need to be updated if we change the underlying implementation.
Comment #11
catchHmm yeah I'm not sure either. This was originally added for hook_node_*() implementations that want to see the original entity before it was loaded rather than the one as it's being changed, but we now have $entity->original (which is messy in itself but for the moment that's what we have).
The only place this is used outside of storage controllers and tests is http://api.drupal.org/api/drupal/core%21modules%21translation_entity%21l...
But could that use $entity->original instead?
If it can, then we could probably refactor the tests a bit and make this a protected method.
Comment #12
plachIf we make
$entity->original
a proper and reliable entity property then the field synchronizer can totally leverage it. Then we can make the method protected.Comment #13
plach@catch:
Do you think we should do that in this issue ot it can be another one? I've the feeling it'll be easier to do once the NG migration is complete.
Comment #14
catchSeparate issue seems fine but could we create that now and add a @todo?
Comment #15
sunI think that loadUnchanged() is actually much more appropriate than loadUncached().
The focus of this facility is not on the cache, because loading the [database-]cached copy of the entity would be totally OK. loadUnchanged() actually works around the static cache, because the static cache is compromised with edited, in-process, submitted form values.
Comment #16
plachHere is the todo.
Actually I'm thinking that perhaps it would be better to add a method to
EntityInterface
to retrieve the unchanged entity as a replacement to$entiy->original
instead of defining a property. This would be a more solid solution and wouldn't require us to wait for the NG conversion to be completed. If we decied to go this way we can hijack this issue and skip the follow-up.Comment #17
sunI'm not sure about #16, and likewise, also not sure about the added @todo.
I could foresee situations in which you want to populate $entity->original with a fake/dummy entity that isn't actually loaded from storage. But turning ->original into a method would enforce storage-loading on all possible scenarios.
In any case, this particular and focused change looks good to me. Let's handle any further/additional questions in separate issues instead.
Comment #18
plachMakes sense, here is the follow-up: #1925914: Make $entity->original a defined entity field.
I introduced the Post NG clean-up tag, since I have lots of issues/todos pending on that.
Comment #19
plachComment #20
fagoGood clean-up! I found a nit-pick:
"public function"
should be "public function"
Comment #21
plachHere it is.
Comment #22
catchNot necessarily, we could add a setter as well. If we had it as a method, we'd only need to load the entity when accessed, right now it's wasted effort when it's not needed.
Comment #23
fagoThanks plach, back to RTBC then.
Ideally, we'd have the entity itself tracking what has changed imo - so we could save the load operation at whole. Howsoever that discussion belongs into its own issue.
Comment #24
catchYes that's an even better point. I thought we had an issue for this already, but it may be stuck in one of the very early entity API dicsussions on Drupal.org. At the risk of a duplicate issue opened #1926714: Track changes for entity property changes and make available to hooks.
Comment #25
catchCommitted/pushed to 8.x, thanks!
Will need a change notice.
Comment #26
plachHere it is: http://drupal.org/node/1935744
Comment #27
plachSmall follow-up: #1935762: Remove entity_load_unchanged() call from FieldTranslationSynchronizer::synchronizeFields().
Nothing special in itself, but since it's probably setting a standard it could use some serious DX review. Quoting @yched from #1807692-82: Introduce a column synchronization capability and use it to translate alt and titles through the image field widget:
Comment #28
irek02 CreditAttribution: irek02 commentedThe change record looks good. I searched through d.o including examples module, where this change could be reflected but did not find anything. If no objections, I change the status to fixed.
Good job, plach!