On #2148255: [meta] Make better D8 api.d.o landing page, linked to high-level overview topics, and put it in Core api.php files, we made a patch that included a stub Topic page for api.drupal.org (i.e., a @defgroup) titled:
Nodes Overview
This can be found in file core/modules/system/core.api.php where it says
@defgroup node_overview
The documentation to go on this page needs to be written. The idea is:
a) Write a few paragraphs about the topic.
b) Link to more detailed documentation on
https://drupal.org/developing/api/8
c) If the more detailed documentation does not yet exist, create stub page(s), link to the stub pages, and add a note to this issue stating that the stub pages need to be filled out.
d) If the topic has related classes, interfaces, and functions, add
@ingroup node_overview
to their documentation headers. That will make these classes etc. show up on the Topic page on api.drupal.org.
For more info -- documentation standards for @defgroup/@ingroup:
https://drupal.org/coding-standards/docs#defgroup
| Comment | File | Size | Author |
|---|---|---|---|
| #33 | 2216535-entity-hooks-32.patch | 155.88 KB | berdir |
| #28 | 2216535-entity-hooks-28.patch | 155.95 KB | jhodgdon |
Comments
Comment #1
jhodgdonBerdir, webchick, and I had a discussion about this topic in IRC today.
Here's the plan:
a) We remove the "Node overview" topic from d8
(b) We add docs to the Entity page on how to (usually) make a content entity bundle (with config)
(c) We rewrite the node API hooks topic (which is about load/view/etc. hooks), to make it more generic for all entities (there may be an existing issue for this?)
(d) We add a link from the entity topic or maybe also from the d8 landing page to the existing node access topic, because that's special for nodes. Probably needs to be linked from the entity API topic and from the landing page?
Comment #2
jhodgdonFound some related issues; probably they can be closed as duplicates once this is done, but need to look at them more carefully.
Comment #3
jhodgdonOK, I'm taking this one on (patch coming probably tomorrow)...
Comment #4
jhodgdonOh. Actually, on #2216547: Fill in topic/@defgroup for User system overview I have a (proposed) section on entity access being added to the entity_api topic. So I think this one will need to wait until that other issue is reviewed/committed (in process), before all the steps outlined above can be addressed, because I need to add stuff to that section.
Comment #5
jhodgdonComment #6
jhodgdonWell, that was quick - the postpone-blocker issue has been resolved. This is my next (and probably last) one to write!
Comment #7
jhodgdonWhew! What a mess.
I've created a first pass at this:
- Added a topic on entity CRUD and view hooks.
- Removed the Node Overview and Node API hooks topics, and most of the node-specific hooks.
- Added several pieces to the Entity API topic
- Retained the Node Access topic and linked to it from several places.
I'm going to close the related issues about creating entity CRUD hooks topics as duplicates of this one.
Note the To Do at the end of the new entity hooks topic. There are quite a few hooks documented in the entity.api.php file that I couldn't account for... not sure if they are real or not. This might be a second pass, or if anyone has pointers...
Comment #8
jhodgdonRemaining tasks:
a) Someone review the patch to see if it's OK so far.
b) (jhodgdon) Go through the other hooks in core/modules/system/entity.api.php and verify if they are real or not. If real, add to the Entity Hooks topic or elsewhere if more appropriate.
c) (jhodgdon) See if there are other specific entity types with their own hook docs and remove those too, like was done here for nodes.
I'll look at (b) and (c) next week. Brain hurts now!
Comment #9
jhodgdonI take it back. Don't even review the patch in #7 at all.
Other To Dos that this patch needs:
d) Make sure implementations of all removed hooks are redocumented as "Implements hook_ENTITY_TYPE_insert()" or whatever.
e) Make sure all the hook_ENTITY_TYPE_* hooks are actually documented. Right now, none of them are.
Comment #10
jhodgdonPhew! I think this (now huge) patch is ready for a review now.
Some notes:
a) I've consolidated all the hook_ENTITY_TYPE_* hooks, and documented them. I even created a draft change notice.
b) A lot of the hook_entity_* generic hooks did not have a $type argument in their signature, although this was being passed in. I added this to the signature and @param.
c) There are a few crud-related hooks in node.api.php that I didn't get rid of, but I'm not actually sure they're real: hook_node_validate(), hook_node_submit(), hook_node_prepare_form(). Are these actually invoked? From where?
d) Questionable crud-related hooks in entity.api.php: hook_entity_view_display_alter(), hook_entity_prepare_form(), hook_entity_form_display_alter()
Note: If the hooks in (c) and (d) are real, then I probably need to add a section to the Entity Crud Hooks topic about entity editing forms, in this patch, but I am not at this point convinced they are being invoked.
Comment #11
jhodgdonIt might help if I uploaded the patch!
Comment #12
jhodgdonand hid the old one.
Comment #13
jhodgdonWhoops. Here is a new patch with everything intended in it. Ignore #11 patch.
Comment #15
berdirUff. Will try to review that, some feedback on those questions for now...
b) AFAIK, the only entity hook that receives the type (I assume you mean entity type) is hook_entity_load(), because those receive an array of entities and getting the type out of them is bit more involving. The others do not.
c) hook_node_validate() still exists ('search for 'node_validate') and it's only for nodes. hook_node_submit() too, I think it should not but not the topic of this issue. hook_node_prepare_form() is the ENTITY_TYPE version of hook_entity_prepare_form(). See below.
d) hook_entity_view_display_alter() (and form), do exist, but they are not really part of CRUD, they allow to alter the display configuration for viewing and editing entities. Same for hook_entity_prepare_form() that does exist, (called in EntityForm::init()) and allows to do stuff before the add/edit form is displayed for an entity.
Comment #17
jhodgdonI found the line that is causing the test failure, in core/modules/system/tests/modules/entity_crud_hook_test/entity_crud_hook_test.module
Whoops, inadvertent change... anyway, fixed that.
So I discussed (b) with Berdir in IRC. The invokeHook method https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Entity!EntityStor... *is* definitely passing the entity type into all of the entity CRUD hooks, but Berdir thinks that since all of them (except load) are passing in single entities, which are typed classes, it's unnecessary and we shouldn't document it. So, filed:
#2216535: Replace Node overview topic and Node API topic with Entity Hooks topic
And here's a new patch with the code fix above and removing the types from the hook_entity_* docs (except for load(), which still has it and doesn't use invokeHook).
I'll address the rest in a second patch so the interdiff is more readable.
Leaving at needs work because I need to do a bit more.
Comment #18
jhodgdonOK, I think I've taken care of (c) and (d) -- additional hooks added to the new entity hooks topic (which has also been renamed so it doesn't say just CRUD in the title, since there are lots other hooks in there).
I've now accounted for all of the hooks in entity.api.php and node.api.php that seem to be related to CRUD, display, and editing.
This patch is hopefully viable!
Comment #19
berdirWrong issue.
Comment #20
berdirUps, wrong issue, review incoming...
Comment #21
berdirWhy the space between the other @ingroup above?
Note that the block hooks are special because they are not covered by the generic code, blocks use a entity view builder but completely override the code there and do their own thing, so not sure we should even add it to the entity documentation.
Similar, this is a super special hook for configurable fields, not sure this makes sense to add here?
This is the kind of documentation that we need to have on the generic entity hooks, reminder for myself to check that.
Bogus empty newline.
The rss stuff is node specific, wondering what happend to that.
node specific, so not sure about that @ingroup?
When we change that anyway, would make more sense to refer to the actual implementation? This change makes it even harder to find the actual code that is doing this.
Some configuration entities use a view builder too, the interface is not specific to content entities, but the default class has content entity specific code, that can be overwritten.
bundle() is defined on EntityInterface right now, although that doesn't really make much sense, but it's used in a few cases for something else than configurable fields.
I'm not sure if this part is also correct.
Might also make sense to refer to the routing or include an example for _entity_view: 'user' or so, which is probably the more common use case rather than calling it manually.
It might be worth mentioning here that
a) modules should in most cases not overwrite access() but checkAccess().
b) It's also important to mention that the check method acts as a default logic if no hook overrides that default behavior.
There's also a separate method and hooks for checking create access.
The current behavior is discussed in #2204363: [sechole] Returning TRUE from hook_entity_access()/hook_ENTITYTYPE_access() must not bypass EntityAccessController::checkAccess() because it's a bit weird and resulted in security issues in block.module, which have been solved in a different way in the meantime.
permission isn't really the word I'd use here, access grant(s) system maybe?
We're still hoping to get rid of controller here, can we avoid that word? entity storage classes/implementations or so?
no ()
same, just view builder.
And again, just entity forms.
Also, entity forms are also used for creating, deleting (confirm forms) and other operations.
I think we usually use $view_builder? it's not a viewer it's something that builds a view/render array.
That comment reads weird, not sure if it should be above the create, but it doesn't set up anything, it just saves it?
Maybe instead of saving explicitly explain that this creates a new entity in memory that has not been saved yet?
There's also $EntityClass::create() now. mostly meant for functions and test code.
fields seems like an implementation detail, only the database storage controller differs between the two things but a) everything is a field for content entities and b) other backends like MongoDB will just load "the entity".
Also, #597236: Add entity caching to core will make this a bit more complicated for content entities, as they will introduce a new hook (that already follows the ENTITY_TYPE pattern).
Update should probably be after save?
There is also no update as far as the API is concerned (the only exception are the separate hooks), just saving of new and existing entities. So maybe just merge that into save, which you more or less already did?
Those methods are also called on the field objects, they replace the old hook_field_* hooks. Both on the field item list objects and the field items (field item list by default does nothing but pass it through to all items)
Same here, just "entity values are saved to the storage"?
Also, storage has a double-meaning as both the entity storage class and the actual storage (mysql, mongodb, ..)
ah, that's why you added it, still think it's enough to just refer it here as an example.
Not sure that this makes sense, "Entity bundle" is not an entity type, so maybe "entity types that are used as bundles" ?
this is specific to content entities.
Not sure this makes sense.
Canceling a user is a separate process that can or can not result in the entity being deleted in the end (based on how it's configured). If configured to delete users, then it still does a "normal delete" at the end.
=> not sure this makes sense here, as users are the only example that I know does something like that.
This is something that is currently apparently not documented on it's own?
wondering where you found that example, already mentioned it above I think, but you don't have to both path the language along and get the translation for it.
If you want to render in the current language, don't pass anything in. If you want to render a specific language, pass in the langcode, it will get the right translation automatically.
See EntityViewBuilder::viewMultiple()
Should we update new code to EntityInterface[].
Which actually points out a problem with this approach.
for hook_node_create(), for example, we type hint with NodeInterface, not EntityInterface, we can't really document that here, unless you want to use a fake example interface.
Bad example, because this is now handled automatically for content entity changed (and created) fields. Just copied I know, but still sad to copy bad examples around.
THis is where I'd expect the removed information on hook_node_insert() to live now..
This reads a bit confusing, like as an example vs. ENTITY_TYPE as generic pattern. I understand it's meant as insert/update as examples of the full set, but that's not how I read it first.
Should possibly at least say something like generic_hook for user entities here too, as you did elsewhere?
Comment #22
jhodgdonWow, lots of good stuff there! THANK YOU berdir for taking such care in the review of this huge patch!
So, most of what you noted above was mistakes, and I think I've corrected them.
A few notes:
Regarding #1/2/6/etc.: I agree that not every hook mentioned on the entity hooks topic needs to be @ingroup. I changed those you mentioned to @see.
Regarding #10/#28, this is what is being done in the NodeSearch plugin during updateIndex() and the search execute, in order to render the node. I took the code straight from there. But I agree that looking at the code, you don't have to get the translation, so I took that part out. Anyway, yes certainly using routing is more normal so I added a note about that. There's more on entity routing being added in #2290129: Menu/routing topic needs an overhaul also.
RE #31... I would like to just document when the hooks are called once, in the @defgroup, and not on each individual hook. Those individual documentation bits were really hard to maintain, and they got out of date. Thoughts?
Comment #23
berdir#10/#28: Ah yes, I see, search is the only example that hardcodes a specific language when rendering the entity (and views, depending on the configuration).
#31: That sounds like a good idea, highlighting what is inside the transaction and what's outside in the flow there. #1729812: Separate storage operations from reactions is related, which might move the hooks out of the transactions and create new ones inside.
still a viewer reference here.
I think that shouldn't be here ;)
Comment #24
jhodgdonOops. What was I thinking? :) There were a number of typos in that section about view building in the last patch too. ?!? My brain must not have been working...
Here's a better patch. I hope.
Comment #25
jhodgdonReroll only.
Comment #26
jhodgdonUm. That one was empty.
Comment #27
webchickI think this has sat here long enough, but unfortunately when I went to commit it, it no longer applied.
Comment #28
jhodgdonYeah, there had been some changes in comment hooks (the publish/unpublish hooks were removed) and some other things... Here's a rerolled patch.
Comment #29
berdirYeah, let's do this, certainly a huge improvement.
Will likely conflict with the menu link critical, as that is certainly messing with those hook as it replaces that entity with a new one, but it's removing something that the other issue will not have to re-add anymore, so I think that's OK.
Comment #30
webchickHm. Indeed, they do conflict and #2256521: [META] New plan, Phase 2: Implement menu links as plugins, including static admin links and views, and custom links with menu_link_content entity, all managed via menu_ui module is a 600K patch. :\ Don't really want to break that one unless I get some kind of confirmation from pwolanin, etc. that it's trivial to re-roll around conflicts. (And it might be; afaik they're working in a sandbox where they can just rebase.)
I left pwolanin a tell to chime in here.
Comment #31
alexpottThis patch conflicts with HEAD
Comment #32
berdirI did talk about this with @pwolanin already, to make him aware of the impact on the renamed/new entity type in that issue, and he wasn't troubled by this as it should only conflict on stuff they remove.. they're used to merging stuff ;)
Also, this is a big patch that conflicts frequently too, so would be nice to get it in.
Will do a quick re-roll later today if nobody else has time first.
Comment #33
berdirOnly one context conflict in EntityCrudHookTest because a @group Entity was added there.
Comment #34
alexpottCommitted 5ffb1d3 and pushed to 8.x. Thanks!
Comment #36
jhodgdonwoohoo, thanks alex!!
We're down to 2 at Needs Review and one to be written on the parent issue (landing topics for api.d.o).
Comment #37
jhodgdonLooks like the change record draft wasn't switched to "published" on commit. I just took care of that.