Problem/Motivation
The "moderation_state_filter" views filter defined in "core/modules/content_moderation/src/Plugin/views/filter/ModerationStateFilter.php" does not correctly join the entity's base table when the views filter is using a views relationship that relates the entity's revision data table.
Relate code in "ModerationStateFilter::opSimple()":
$entity_base_table_alias = $this->relationship ?: $this->table;
// The bundle field of an entity type is not revisionable so we need to
// join the base table.
$entity_base_table = $entity_type->getBaseTable();
$entity_revision_base_table = $entity_type->isTranslatable() ? $entity_type->getRevisionDataTable() : $entity_type->getRevisionTable();
if ($this->table === $entity_revision_base_table) {
$configuration = [
'table' => $entity_base_table,
'field' => $entity_type->getKey('id'),
'left_table' => $entity_revision_base_table,
'left_field' => $entity_type->getKey('id'),
'type' => 'INNER',
];
$join = Views::pluginManager('join')->createInstance('standard', $configuration);
$entity_base_table_alias = $this->query->addRelationship($entity_base_table, $join, $entity_revision_base_table);
}
BUG: Using the 'left_table' as $entity_revision_base_table only works if the view's base table is the entity's revision base table, example "node_field_revision".
This bug results in the following error and WSOD:
Warning: Trying to access array offset on value of type null in Drupal\views\Plugin\views\join\JoinPluginBase->buildJoin() (line 311 of {WEBROOT]/core/modules/views/src/Plugin/views/join/JoinPluginBase.php)
The 'left_table' should be $entity_base_table_alias which is the $this->relationship or the $this->table, which at this point $this->table is $entity_revision_base_table.
Currently, there is no test coverage for this bug. The current "Drupal\Tests\content_moderation\Kernel\ViewsModerationStateFilterTest" uses a "node_field_data" relationship so it will not test the code within if ($this->table === $entity_revision_base_table) {.
Steps to reproduce
- Using a hook_views_data_alter, add a view relationship for the views data of a table that can join to the entity's revision data table. Example: A new relationship from "user_field_data.uid" to "node_field_revision.uid").
- Create a view for the User
- Add the new relationship to relate the "node_field_revision".
- Add an exposed views filter for "Moderation State" that uses the relationship for the "node_field_revision".
- Add a page display with a path
- Save the view.
- View the page for this view.
- Select "Draft" for the Moderation State filter
- Submit the views form
- RESULT: BUG - WSOD with a log message of "Warning: Trying to access array offset on value of type null in Drupal\views\Plugin\views\join\JoinPluginBase->buildJoin() (line 311 ..."
Proposed resolution
The 'left_table' should be $entity_base_table_alias which is the $this->relationship or the $this->table, which at this point $this->table is $entity_revision_base_table.
Remaining tasks
None
User interface changes
None
API changes
None
Data model changes
None
Release notes snippet
TBD
| Comment | File | Size | Author |
|---|
Issue fork drupal-3396741
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
recrit commentedThe attached "3396741-moderation_state_filter-11.x-2.patch" changes the 'left_table' to use "$entity_base_table_alias" and uses the same in the "addRelationship()".
The attached "3396741-moderation_state_filter-11.x-2--tests-only.patch" should fail. This only includes the new tests in order to demonstrate the bug.
Comment #3
recrit commentedComment #4
recrit commentedAdded a new
$entity_revision_base_table_aliasto avoid semantics with the$entity_base_table_aliasbeing used for the actual base table join.Comment #5
smustgrave commentedWas tough to verify think I saw the issue following the steps. Also the test case think shows the issue.
Patch #4 seemed to solve the problem.
Comment #6
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue.
While you are making the above changes, we recommend that you convert this patch to a merge request. Merge requests are preferred over patches. Be sure to hide the old patch files as well. (Converting an issue to a merge request without other contributions to the issue will not receive credit.)
Comment #8
recrit commentedConverted patches to an MR - https://git.drupalcode.org/project/drupal/-/merge_requests/5381.
Moving back to "Reviewed & tested by the community"
Comment #12
catchCommitted/pushed to 11.x, cherry-picked to 10.3.x and 10.2.x, thanks!