
I have a case where I need to append my own checks into the User entity's access callback, but unfortunately I can't set my own 'access callback' as the Entity module uses 'hook_module_implements_alter()' to ensure it has the last say and overwrites my own changes.
I can't even use 'hook_module_implements_alter()' myself because mine runs earlier. While I could change the weight of my module it is less than ideal.
Instead, it seems to be that the Entity module should check if certain values have been already set before setting them itself, or at least implementing a pass-through method (take the old callback and if it's own checks return FALSE, pass through to the previous callback to let it have the last say) or a drupal_alter() approach in all of it's callbacks.
Comment | File | Size | Author |
---|---|---|---|
#13 | entity-info-metadata-alter-2269989-13-D7.patch | 8.92 KB | Bird-Kid |
#4 | entity-2269989-4-entity_info_metadata_alter.patch | 8.11 KB | les lim |
#1 | entity_info_metadata_alter-2269989-1.patch | 439 bytes | deciphered |
Comments
Comment #1
deciphered CreditAttribution: deciphered commentedThis was the easiest solution for the issue, simply adding an alter to the
_entity_info_add_metadata()
function. I'm happy to revisit if a better solution is suggested.Comment #2
fagoan alter for an alter seems wrong to me. I'd ok with setting the values in a way you can enforce others tough, e.g. we could be just doing
$info += $array_of_additions;
?Comment #3
deciphered CreditAttribution: deciphered commentedI agree that it seems wrong, which is why it wasn't my first attempt at a fix.
I did try adding all the metadata additions in the exact manner described, as well as using array_merge_recursive(), but neither of those resulted in a satisfactory result:
-
+=
ignored any nested items if the parent was present, which it always is.-
array_merge_recursive()
doubles up on nested items if present.My initial feeling is that each callback should be iterated over and shift the existing item into an secondary array so that it can be passed through in the metadata callback;
eg., if $entity_info['user']['access callback'] is set, array_unshift it into $entity_info['user']['access callbacks'], then during the metadata access callback if the result is not TRUE, pull in the $entity_info values and array_shift() the callbacks (if there are any) and pass return from that callback.
The reason I didn't start with this is two fold:
- The $entity_info object isn't passed to the callback.
- A lot of work would be required to implement this change.
Comment #4
les limI just ran into the same problem, trying to use a custom callback for
$entity_info['comment']['access callback']
.Did you try drupal_array_merge_deep()? That should prevent
_entity_info_add_metadata()
from overwriting previously set properties or doubling nested items.Comment #5
alberto56 CreditAttribution: alberto56 at Dcycle commentedThe code is straightforward, and I successfully tested this on my site.
Comment #6
checker CreditAttribution: checker commentedLooks good.
Is "if (!module_exists('file_entity')) { .. }" still necessary?
Comment #7
nancydruSee also #2398129: "Add new" taxonomy entity reference requires elevated permissions which needs this patch before that issue can be resolved.
Comment #8
nancydruApplies with a 5 line offset to the current Git checkout.
Comment #9
nancydruSeems to work for me.
Comment #10
fagoWhile that seems reasonable, I fear it might create issues in subtle situations where modules already provide a key that clashes with the one of entity.module. Thus, I'd rather opt to not commit a risky change like that.
I think having to change module implements order or module weights is fine to achieve the alter of the alter. I'd be happy though to commit a change to make that easier, e.g. we could move the module implements alter of entity module to the top?
Comment #11
drupalfan2 CreditAttribution: drupalfan2 as a volunteer commentedIs this patch still necessary for latest Drupal 7 version?
Comment #12
drupalfan2 CreditAttribution: drupalfan2 as a volunteer commentedComment #13
Bird-Kid CreditAttribution: Bird-Kid commentedUnfortunately this issue is still active.
We are using custom entity classes for core entities such as node and taxonomy_term in production. Inconveniently, entity.module is setting a
creation callback
for nodes. That callback ignores the entity controller and creates a new, class-less object instead. As mentioned by Deciphered, when your own module is invoked before the entity module, you cannot even use an implementationhook_module_implements_alter
, because entity module is implementing the very same hook to ensure its implementation ofentity_info_alter
is run last.I have looked into both patches provided. While they do provide solutions to the issue at hand, I also somewhat agree with fago's concerns:
_entity_info_add_metadata()
. Doing so with this patch would require setting something likein an implementation of
hook_entity_info
orhook_entity_info_alter
, which IMO is not very declarative.Attached here is a patch which I'd argue merits the best of both previous patches, while trying to address the aforementioned concerns:
drupal_alter()
from within an implementation ofhook_entity_info_alter
, it is not exposing the same information twice. Here, only the newly defined entity info metadata is being passed for altering.from inside an implementation of
hook_entity_info_metadata_alter
.We are already using this patch in production without any issues. Hope this helps!
Comment #14
Bird-Kid CreditAttribution: Bird-Kid commented