After testing the jsonapi I came across this discovery.
I am able to create a comment of a comment (of entity_type "node") of a node. However, I can't go the next level which would be a comment of a comment (entity_type "comment") of a comment of a node.
I can do it from the drupal ui directly. I don't know if this is to protect against circular references or what, but this needs to be looked into.
Steps to reproduce.
Create 2 more comment types.
CommentOfNodeComment
CommentOfCommentComment
Then for Default comments add field General Comments CommentOfNodeComment
Then for CommentOfNodeComment add field General Comments CommentOfCommentComment
Then create an article w/ comments down to CommentOfCommentComment.
Then try to create a CommentOfCommentComment via a rest call. E.g.
POST {{protocol}}://{{host}}/jsonapi/comment/responses HTTP/1.1
Authorization: Basic token
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json
{
"data": {
"type": "comment--commentofcommentcomment",
"attributes": {
"subject": "test CommentOfCommentComment",
"entity_type": "comment",
"field_name": "field_commentofcommentcomment",
"comment_body": {
"value": "some text",
"format": "basic_html"
},
"entity_id": [{"target_id": 4}],
"uid": [{"target_id": 1}]
}
}
}
Issue fork drupal-2958241
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
e0ipsoThanks for the bug report. If you happen to work on this, please assign this to yourself using the select box.
Comment #3
Wim LeersThat sounds … pretty esoteric/extreme. Each of us setting up that same thing to reproduce this is a poor investment of our time. Please provide a failing test. If not a failing test, then at least YAML files for the relevant configuration.
Comment #4
Wim LeersIf not tests, then please at least provide steps to reproduce!
Comment #5
lastlink CreditAttribution: lastlink commentedUpdate w/ test case.
Comment #6
lastlink CreditAttribution: lastlink commentedfix typo
Comment #7
Wim LeersWorking on test coverage.
Comment #8
Wim LeersI am currently not succeeding in even creating a comment on a comment, let alone a comment on a comment on a comment. i.e. I'm getting stuck at 2 levels instead of 3.
Comment #9
Wim Leers… and when I step through it with a debugger, even the validation of
comment_type
fails, despite it being set to something valid. It fails becausecomment_type
s are of course config entities, yet\Drupal\Core\Entity\Plugin\Validation\Constraint\ValidReferenceConstraintValidator::validate()
ends up calling
\Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection::validateReferenceableEntities()
, which only supports content entities.Attached is my WIP test coverage patch.
I'll continue on Monday. Unassigning myself because if somebody wants to continue in the next 4 days, feel free!
Comment #11
Wim LeersI tried to compare how this works in "the UI" (i.e. using Drupal's UI rather than JSON API).
Turns out that there too there is violation error! The following violations is triggered for the
entity_id
field:… yet that validation error never shows up! Why? Because
\Drupal\Core\Entity\ContentEntityForm::validateForm()
does… and because
entity_id
was not edited via the form,$edited_fields
includesentity_id
, for which the violation was registered.Hence the problem lies either in
comment.module
or the Entity Field API. And this problem applies to the REST module just as well. Moving to that component for now, to make it clear this is NOT a bug in JSON API.Comment #12
Wim LeersThere are two potential solutions here:
EntityFormDisplay
config entity to determine which fields's widgets are shown to the end user, and hence are editable. No such thing is possible in an HTTP API context.Verdict: not feasible.
Comment
'sentity_id
field despite them being there), fix the root cause: ensure that that violation error is not created!I figured I'd make this easier to reproduce/debug: I want this validation error to show up even when using forms. But … that's apparently easier said than done, because just pretending
entity_id
is an edited field is not enough!\Drupal\Core\Entity\ContentEntityForm::flagViolations()
uses$form_state->setErrorByName(str_replace('.', '][', $violation->getPropertyPath()), $violation->getMessage());
to make errors show up, and guess what … because there's no form item for the given property path, that does not actually show up at all! In other words:\Drupal\Core\Entity\ContentEntityForm::flagViolations()
will happily swallow validation errors.That's what the attached patch does.
Comment #13
Wim LeersSo, going with #12.2, where does that lead?
The originally reported problem is about the 3rd level of node comments (comment on comment on comment on node). But I can also reproduce it with the 2nd level of comments on any other entity type (for example comment on comment on taxonomy term). What's the common denominator between those? The fact that the
Comment
entity you're posting is of aCommentType
which hastarget_entity_type_id: comment
in its configuration.If you start debugging that, you'll end up stepping through
\Drupal\comment\Plugin\EntityReferenceSelection\CommentSelection::entityQueryAlter()
, which does this:This is the root cause of all these problems. It results in this query:
which returns nothing, because the comment type we're trying to reference is a comment on a comment, not a comment on a node. The cited code is what adds
INNER JOIN node_field_data n ON n.nid = comment_field_data.entity_id AND comment_field_data.entity_type = 'node'
, which is what causes only comments on nodes to be eligible.Comment #14
Wim LeersComment #15
Cauliflower CreditAttribution: Cauliflower commentedMaybe related to this issues:
We also have a comment on comment.
Editing the parent comment goes fine (through comment/**id>$**/edit). Then I added a comment on this comment through code. Editing or viewing this last one fails.
In function form() on rule 76 in web/core/modules/comment/src/CommentForm.php the $field_name is wrong. $comment->getFieldName() does not return the name of the field through which the comment is referenced to its parent, but it returns instead the bundle name of the comment.
Comment #17
nnevillIt's because of
\Drupal\comment\Plugin\EntityReferenceSelection\CommentSelection::entityQueryAlter
The code is:
So we have hardcoded condition
$data_table . ".entity_type = 'node'
which means stuff will work only for nodes :(Comment #21
thetwentyseven CreditAttribution: thetwentyseven commentedHi,
I was having problem with this. I created a custom comment type, and added a field in a custom type. Using JSONAPI gets the following error:
But thanks to nnevill I have been able to create a quick patch. This is just a temporary solution for those who has the same problem.
Related:
Comment #22
thetwentyseven CreditAttribution: thetwentyseven commentedSorry I forgot to make the patch with the correct format.
Comment #23
thetwentyseven CreditAttribution: thetwentyseven commentedComment #24
thetwentyseven CreditAttribution: thetwentyseven commentedComment #25
andypostOne more issue here is that
\Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection::reAlterQuery()
called from\Drupal\comment\Plugin\EntityReferenceSelection\CommentSelection::entityQueryAlter()
trying to access protected properties on query and failsComment #29
larowlanComment #30
larowlanAdding a related (possible duplicate) issue that has tests already
Comment #33
larowlanMarked #3272023: Do not check node_access if node module is not installed as a duplicate however it has tests.
Marking as needs-reroll
Could the person who takes on the re-roll add the tests from #3272023: Do not check node_access if node module is not installed to the patch from above
Crediting those who worked on the other issue.
Comment #34
immaculatexavier CreditAttribution: immaculatexavier as a volunteer and at Srijan | A Material+ Company for Drupal India Association commentedRerolled patch against 9.4.x as mentioned in #33
Comment #35
joachim CreditAttribution: joachim as a volunteer commentedAs I said on the other issue, this approach is assuming that if node module exists, then the comment is on a node.
But those two facts are independent.
We can have:
- node module, comment on node
- node module, but comment on something else
- no node module, comment on something else
We need to check the actual host entity of the comment.
Comment #36
fjgarlin CreditAttribution: fjgarlin as a volunteer commentedI think he meant re-rolling the patch from #24 with the tests from the mentioned duplicated issue.
#34 is just the patch that was provided in #2372023 as is.
Comment #37
larowlanYep, that's what I meant, thanks
Comment #38
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedRe-roll of #24 with tests.
Comment #39
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedRe-roll of #24 with tests and coding standards fix.
Comment #41
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedForgot to copy the use statement in the patch. Re-trying.
Comment #43
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedOk, I initially thought that #24 was working, but it's not.
A few things:
Upon debugging some of the methods that fail, it seems that that's wrong. Sometimes the method gets even called with no arguments.
The code after that assumes that the table exists, but it might not, depends on the entity implementation.
Comment #44
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedDue to the above, I changed the logic in a couple of places.
First we fetch the conditions and we try to get the one that checks the "cid" value of the comment, and we get the value of the argument for it. This should work in most of the cases. Based on getting a value for "cid", we try to determine the "entity_type" that the comment is attached to via a query (like the original patch).
Then, we actually check that the produced table name does exists in the database, as "ENTITY_field_data" does not need to exists for all entity types. If that check goes through, we do the JOIN, and only if the entity type is "node", we do the "node_access" and "bypass node access" checks).
Finally, I needed to alter one of the tests in the "system" module that one could argue is opinionated. "Should a comment admin be able to view comments made on an unpublished node?". The way I see it is that the user should actually be able to view and review the comment (ie: profanity), but not the node, like a taxonomy admin should be able to view and review terms added to a node, regardless of the access to the node, for example. If we want this test unchanged, then we need to provide access to the entity_type somehow to the "entityQueryAlter" method, which I believe is a much bigger task.
Providing patch with all the above logic in place.
Comment #45
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedSame as above, fixing coding standards.
Comment #46
joachim CreditAttribution: joachim as a volunteer commentedThat looks really brittle.
I came up with an idea for how to tackle this on the other issue -- see https://www.drupal.org/project/drupal/issues/3272023#comment-14484880
Comment #47
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commented@joachim - if you could give me some more guidance on where/how to make that happen I could try, though I'm not sure I have enough "core" knowledge to do the rest.
I'm a bit lost on:
How can I debug that?
Also:
Not sure what this means.
Or maybe @larowlan wants to chip in on what could be next or how to approach it.
Comment #48
joachim CreditAttribution: joachim as a volunteer commentedSo, my basic point is that in CommentSelection.php we shouldn't be having to sniff around to figure out the host entity type. Hacking about with table names in the query is really messy. Comments *know* which host entity type they are on.
However, we don't have the host entity type in CommentSelection.php.
So, I investigated to find out how far back we have to go until we get to a point where the host entity type is known.
I used the steps to reproduce from the other issue (which could really do to be copied over here!!!!), with xdebug to see the backtrace.
So, what I found was:
> in ValidReferenceConstraintValidator::validate(), there is the comment entity with 'node' set as its entity_type field value.
However, I'm not sure either what I meant by this:
> That would require us to add a new setting to the 'comments' field type, hidden from the UI and set automatically.
because now I look at the code, I am thinking, surely field storage and field definitions know which entity type they are attached to?
There is this:
but target_type can be ambiguous -- IIRC for fields it can mean the host, and for reference fields it's the type of entity that gets referenced.
Comment #49
joachim CreditAttribution: joachim at Factorial GmbH commentedComment #50
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedHere is a slightly different approach. Rather than having all that "node" or "entity" access-related logic within the query, we can just call the "access" method on the entities that are returned and then filter out the ones which the user can't access. That is actually the way that "CommentController" uses to check access to the comment.
I've tackled that by overriding the "getReferenceableEntities" and "countReferenceableEntities" methods to perform that additional check. I find it pretty clean compared to all the other previous assumptions.
Let me know your thoughts.
Comment #52
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedIt was a false negative as the failing test didn't make sense at all in the context. I triggered a retest and we can see it all came green. Marking as "need review".
Comment #53
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedComment #54
joachim CreditAttribution: joachim at Factorial GmbH commented> Rather than having all that "node" or "entity" access-related logic within the query, we can just call the "access" method on the entities that are returned and then filter out the ones which the user can't access
That's not going to scale, unfortunately. The reason we have the node_access table system is for scalability.
Comment #55
drummWe’re running into this in upgrading API.Drupal.org.
Comment #56
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedIt's a pity that the previous version wouldn't scale, as that was probably the cleanest and a true split between comment and node (within that file at least), but I understand.
I kept digging into what was available within the "CommentSelection" class.
* When it's a nested comment, the entity is there (available since this issue https://www.drupal.org/project/drupal/issues/2879918) so we can access the host "entity_type" from the entity via "$entity->getCommentedEntityTypeId()".
* And if it's not available, we can then get the "target_type" setting from the "entity_id" field FieldStorageDefinition.
With that, we have the table name, which should still be checked to see if it exists, and finally, if the "target_entity_type" is "node", then we do the query altering to deal with scalability issues.
Patch supplied for your review here.
Comment #57
joachim CreditAttribution: joachim as a volunteer commentedLooks like you've managed to get hold of the host entity type, that's great!
I would simplify this and always use this logic, and remove the if() path. It'll always work.
Get the table from the entity type's method for that, rather than hardcoding the name.
And it's a table we're going to join to, but it would be clearer to call it $host_entity_field_data_table.
'primary' not usually a term used in Drupal for entities. Call this $id_key maybe?
I'm not clear on what this join is going to do for non-node hosts.
There doesn't seem to be any further condition?
Should we be adding a condition on status if the host entity type has a 'published' key?
Comment #58
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commented1. I am not sure why, but I think that we need to keep the "if/else" when we have an entity.
* In the newly added tests, the "$entity" object was correct and would give us the right target entity type value, but if we only use the "else" logic, we would weirdly get "user" as the value for the target entity type, even if the 'target_type' is "comment" and the test does NOT attach comments to users whatsoever.
* I tried as well in the project where I am having the issue and I get the same: "$entity" is populated with the right thing and the "else" path returns "user" (again, user does not have comments attached on the project).
So I've kept the if/else since that since to be working in all scenarios. For all top level comments, "$fields['entity_id']->getSetting('target_type')" is correct, and for all nested comments, where $entity is available, "$entity->getCommentedEntityTypeId()" is correct too.
2. Renaming done and getting the table name from the entity type method.
3. Renaming done.
4. I changed the direct "node_access" tag to a dynamic "$target_entity_type_id . '_access'", which in turn, when it's a "node", will be "node_access", but it will allow other entity types to alter the query as needed (to check for the published status for example, if needed). I didn't add the "published" check, because of what I just mentioned.
New patch attached.
Comment #60
joachim CreditAttribution: joachim as a volunteer commented> if we only use the "else" logic, we would weirdly get "user" as the value for the target entity type, even if the 'target_type' is "comment" and the test does NOT attach comments to users whatsoever.
That doesn't sound right to me at all. We always have a field. Something's not right there, I think.
Comment #61
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedYup, if defo looks weird. But it's also something that is not introduced by this patch, as we are mostly reading data, not setting any values.
If you want to replicate, you can do it running/debugging CommentNonNodeTest::testCommentFunctionality, in the methods where we test threading.
As mentioned, "comment" is not attached in any way to "user", yet the following happens when creating a comment reply in a non-node entity:
Note that in the mentioned case, the "$entity" is set to the comment that you're replying to.
Comment #62
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commented> I would simplify this and always use this logic, and remove the if() path. It'll always work.
You were right all along. It was the way I was debugging things.
I was stopping the execution and dumping things, that's why I was getting that value, which was coming from the "user" field validation within the Comment form. There is no "comment" attached to a "user", but an "user" is actually making a "comment", so it makes sense. Once I let everything run, things were good.
Thanks to this debugging, I think I finally understand what this plugin is doing. It helps validate all the EntityReference fields attached to a comment and triggers the "ENTITY_access" tag (and additional logic for node for scalability).
This version of the patch addressed all your feedback from #57
Kindly review again please.
Comment #63
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedComment #65
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedAll the reported tests do pass locally and even in the reported output of the job. Re-queing tests.
Comment #67
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedFixing the deprecation. See notes from #62 for review.
Comment #68
larowlanThis is looking great.
Can we get a test-only patch so we see red/green
Thanks
Comment #69
larowlanDidn't mean to change status
Comment #70
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedYup, not a problem. Here you go.
Comment #72
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedAbove fail expected. Changing back to "Needs review".
Comment #73
joachim CreditAttribution: joachim as a volunteer commentedLooks great!
Comment #76
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedRe-run the tests to be sure.
Comment #77
larowlanOne question here
Any reason we can't assume the entity_type_id is comment here?
Can you even use this selection handler for another entity type?
Comment #78
joachim CreditAttribution: joachim as a volunteer commented> $entity_type_id = $this->getConfiguration()['target_type'];
We're supposed to be getting the host entity type here.
(This is why inline comments are useful!)
Looking at the parent class, target_type gets us the entity type *being referenced*, so yes, 'comment' in this case:
So the approach needs work.
Comment #79
joachim CreditAttribution: joachim as a volunteer commentedSomething seems very wrong here: I added a comment field to taxo terms.
This:
says 'node'. There should be no nodes around at all here!
Comment #80
joachim CreditAttribution: joachim as a volunteer commentedAh right, it's because the 'entity_id' field on comments probably has 'node' as its target type in its base field definition. That is then overridden per-bundle in a hook somewhere.
So, expected, but not useful here.
Comment #81
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedIf we truly want the host entity type, we need the if/else that was present in #58.
If $this->getConfiguration()['entity'] is available that'll give us the target entity type. If it's not, then the above lines get it right.
Comment #82
joachim CreditAttribution: joachim as a volunteer commentedI thought someone further up had said we couldn't get values from the comment entity that's available here, but it turns out we can.
(Posted simultaneously with #81.)
Comment #83
joachim CreditAttribution: joachim as a volunteer commented@fjgarlin when does this situation happen?
> // Entity not available yet, get it from the field definition.
I've been testing manually with posting a new comment in a thread and a new top-level comment.
Comment #84
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedIt didn't happen while testing manually (top level comment, threaded, etc), that situation only showed up in one of the tests. It was "EntityReferenceSelectionAccessTest::testCommentHandler".
Comment #85
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedPerhaps we should just stop checking anything else if we don't have the "$this->getConfiguration()['entity']".So, if we do have it, do the checks for access, etc, but if we don't have it yet, there's nothing to check at this stage. So a kind of wrapping "if ($comment) {" after you first try to get it.That still makes the mentioned test fail. It might be the way that the test is calling things, bypassing the way that Drupal would normally do it.
Comment #87
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedHere is a version of the patch that brings back the checking of the entity (#58), which should be available during all cases when using the comments functionality as intended, but also has the "else" part as a fallback (which also covers the way that the failing test does the checks).
It's very similar to #58, with the suggestion from @larowlan in #77 (we know it's "comment") and the namings by @joachim in #82.
I'm open to more feedback if needed.
Comment #89
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedForgot to adapt the deprecations. See above comment for what this patch contains.
Comment #90
joachim CreditAttribution: joachim as a volunteer commentedThat is always going to be 'node' as we saw earlier, because it's a base field, and Comment entity doesn't set the target type on the base field definition, but entity reference has 'node' as the default in EntityReferenceItem:
> 'target_type' => \Drupal::moduleHandler()->moduleExists('node') ? 'node' : 'user',
I think we have to examine why the test is needing this logic, since doing stuff in the UI doesn't seem to.
EDIT: Ah, it's as a non-admin. And of course, I'm testing as an admin :/
Comment #91
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedOK, I think a mixed approach between the current patch and the one suggested in #50 can get us where we need to.
We can make the checks only when we have `$entity`, which makes sense, but also add an additional check of `$entity->access(...` in the method `getReferenceableEntities`, which we can just override from the parent class into the `CommentSelection` class.
I'll work on it.
Comment #92
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedThis is what I mean:
* We only do the additional checks in "entityQueryAlter" when we have the comment entity, which will be in most cases. If we actually don't have the host entity there is no extra checks for access that we can't do.
* In "getReferenceableEntities", we use almost the same code that the parent class, with an additional line
if ($entity->access('view', $this->currentUser)) {
, which makes sure that the comment can be accessed. The only reason why we don't call the parent here and loop through results (as originally done in #50) is that we'd need to load up entities again and (as mentioned in #54) that might not scale up, so we introduce the additional "if" over the existing loop, which would be run anyway, so there is no "scaling" problem in my opinion.With this patch, there are no assumptions or weird defaults.
Comment #93
joachim CreditAttribution: joachim as a volunteer commentedI still don't understand what circumstances produce no $comment here/ [*]
But changing the logic so we don't apply any access in that situation doesn't seem right to me.
We maybe need to go back to #48 and figure out a new way to get the information in at this point.
[*] Though really, what on EARTH is an entity doing in the configuration array ANYWAY? It's hardly actual configuration is it???
That just smells wrong.
Comment #94
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedI think there are two cases that will produce the different outcomes:
* Case 1: Create a new comment: in this case, we always have a host entity to validate against. Validate is the key-word here, as the "entityQueryAlter" is called eventually from "ValidReferenceConstraintValidator::validate()", where the entity is set in this line
$entity = !empty($value->getParent()) ? $value->getEntity() : NULL;
"ValidReferenceConstraintValidator" can be seen in the backtrace here:
* Case 2: Query entities that can be referenced: as the above "validate" function is never called, the "entity" is never set, but the "entityQueryAlter" is still called, in this case originating from "getReferenceableEntities". So this is the case where the "$comment" is not available in that function.
See backtrace of calls here:
We are applying the logic when we have the entity to check against (case 1). We're also checking the access when trying to call "getReferenceableEntities", which I think is the right thing (case 2)
Comment #95
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedComment #97
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commented@joachim - doesn't the above comment (#94) explain the different cases? I think the patch covers them both. Let me know your thoughts. Thanks.
Comment #98
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedComment #99
larowlanManually tested this.
Steps taken:
* Install minimal profile
* Install comment module
* Install field UI module
* Add a new comment type, with target entity-type of User
* Add a comment field to the user entity-type and choose the comment type from above
* Configure the compact user view mode to remove the comment field, this avoids recursion (see #2114887: Maximum nesting level when attaching comment field to User.)
* Add a comment, reply to that comment - works fine
* Uninstall node module, attempt to reply to a comment
* Get the error as expected
* Apply patch and try again, works
Comment #100
larowlanMoving to a code-path that loads the entities rather than just querying feels like it could be a performance issue.
But I checked and TermSelection is already using the full-entity load path too.
In addition, I can't find any calls to ::countReferenceableEntities outside of test code, so I don't think there is a performance issue either way.
We should open a follow up to deprecate this method for removal in D11. Added the needs followup tag.
I looked into #93 and indeed, there are instances of where a selection handler is instantiated without an entity key in $configuration, so this is a valid guard.
On that basis this is RTBC in my book, manually tested well.
xjm asked in slack if this needed an upgrade path, but it doesn't it has no impact on existing sites/data.
Comment #101
larowlan#3294840: Consider deprecating and removing \Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface::countReferenceableEntities added follow up
Comment #102
joachim CreditAttribution: joachim as a volunteer commentedI still think this line smells wrong:
Comment #103
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedThat would be "Case 1" outlined in #94, when creating a new comment.
Note that '$entity' was introduced here #2879918: Send entity to selection handler on validate. (also mentioned here #2875747: ValidReferenceConstraintValidator missing field entity).
Commit: https://git.drupalcode.org/project/drupal/commit/032ad72b49a7c4c8c5b907d...
Comment #104
joachim CreditAttribution: joachim as a volunteer commentedWhat I'm iffy about is having something that is only about the current request (the $entity) inside something that's persistent (the config). It's mixing two totally different levels together.
Comment #105
larowlanThat's unrelated to this patch though, it's the API we have at this point
Comment #106
larowlanFor posterity, the API is
\Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManager::getSelectionHandler
which accepts an$entity
parameter and that is in turn passed as a configuration option when instantiating the plugin.Comment #107
joachim CreditAttribution: joachim as a volunteer commentedThanks for the details. Let's file a follow-up to tidy that up then.
Comment #108
larowlanYeah I agree it should be a dedicated method/property
Comment #109
catchOpened the follow-up that @larowlan mentioned in #100: #3295649: Deprecate SelectionInterface::countReferenceableEntities.
Nit - why not set $id_key inside the if, it won't be used otherwise.
I know this comment is just moved, but this looks like we're working around comment module not implementing entity access, in comment module - should we open a follow-up?
Could be a strict comparison.
Comment #110
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedNew patch attached.
1. Addressed
2. Comment module implements entity access checks as far as I can see in the code. There is "CommentAccessControlHandler.php" and even within the "CommentSelection.php" we check access in "getReferenceableEntities" method. I think that the comment (and check) is there for scalability reasons based on #54 feedback.
3. Addressed
As the changes are really minimal in 1 and 3, I'm marking it as RTBC as per #100 (not sure if this is the right process).
Comment #111
catchIf comment module does indeed implement proper access and we're doing this for performance, I think the comment should be changed to reflect this.
Comment #112
fjgarlin CreditAttribution: fjgarlin as a volunteer and at Drupal Association commentedAll the access checks in the comment module are against the host entity, as the comment is a field within it.
Changed the comment to:
If you think there is a better suggestion please let me know.
Patch re-attached.
Comment #114
catchComment looks much better thank you!
Committed/pushed to 10.1.x, cherry-picked to 10.0.x and 9.5.x, thanks!
Enough changes in here I don't think we should backport to 9.4.x, so marking fixed against 9.5.x for now.
Comment #116
BerdirThis introduced a regression, if you have a comment reference field on an entity type that is _not_ a comment itself, it fails with a fatal error.
The entity that's passed to configuration is not the entity being referenced, it's the host.
As a quickfix, it needs to have an instanceof CommentInterface, but I'm not sure if just skipping this logic then is valid. Will create an issue and patch.
Comment #117
BerdirFollow-up issue for this: #3332546: CommentSelection::entityQueryAlter() fails on validate when referencing entity is not a comment