Problem/Motivation

I found an annoying bug in statistics module - it crashes the site page rendering if you somehow have nid for non-existing node in the node_counter table. I don't know how it happened and I could not make it happen at will, but reference to a deleted node has not been removed from the table. That causes use of NULL instead if the node object and the site page rendering breaks - on every page that has StatisticsPopularBlock. The fix is simple - just 2 lines to modify in the function StatisticsPopularBlock::nodeTitleList(). I can supply a patch for the fix, it is pretty obvious on lines 195 and 196 in StatisticsPopularBlock.php file.

Steps to reproduce

Proposed resolution

TBD

Remaining tasks

Update patch
Add a test
Review
Commit

User interface changes

TBD

API changes

TBD

Data model changes

TBD

Release notes snippet

TBD

Issue fork drupal-2987952

Command icon 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

calmforce created an issue. See original summary.

calmforce’s picture

I have created a patch. The change was even easier than I thought: only one line in StatisticsPopularBlock.php needs to be changed to ignore those node IDs in the node_counter table that do not have nodes anymore.

calmforce’s picture

StatusFileSize
new778 bytes

I have attached exactly the same patch (only changed the patch file name) to this comment, so the patch file name matches the comment number.

timmillwood’s picture

Status: Active » Reviewed & tested by the community

Nice find, and yes, super simple fix.

catch’s picture

Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/modules/statistics/src/Plugin/Block/StatisticsPopularBlock.php
    @@ -192,7 +192,7 @@ protected function nodeTitleList(array $nids, $title) {
         $nodes = $this->entityTypeManager->getStorage('node')->loadMultiple($nids);
    

    I think we should not load the nodes here, since this never gets used.

  2. +++ b/core/modules/statistics/src/Plugin/Block/StatisticsPopularBlock.php
    @@ -192,7 +192,7 @@ protected function nodeTitleList(array $nids, $title) {
           $node = $this->entityRepository->getTranslationFromContext($nodes[$nid]);
    

    Instead maybe check the return value here?

timmillwood’s picture

@catch The initial node load is used as the param in getTranslationFromContext().

tstoeckler’s picture

Well, instead of doing the workaround of iterating over the keys we could just do foreach ($nodes as $node), though, right?

calmforce’s picture

@catch The nodes need to be loaded because getTranslationFromContext() requires an entity as a first argument.

@tstoeckler yes, you are right - the iteration over $nodes would do the fix as well, I just tested. I did iteration over the keys because that requires changing the only one line instead of two. However, iteration over $nodes may provide better code readability. If so, I can suggest another patch - with iteration over $nodes array. The new patch is attached.

calmforce’s picture

Status: Needs work » Needs review
borisson_’s picture

Status: Needs review » Reviewed & tested by the community

The change in #8 is great, thanks for the suggestion @tstoeckler and the implementation @calmforce! This was already set to RTBC by @timmillwood before without it having tests, so setting this back to rtbc based on that.

I also think that writing a test for this would be really hard to get right.

catch’s picture

Version: 8.5.5 » 8.6.x-dev
Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/statistics/src/Plugin/Block/StatisticsPopularBlock.php
@@ -192,8 +192,8 @@ protected function nodeTitleList(array $nids, $title) {
       $this->renderer->addCacheableDependency($item, $node);

I think the reason this was originally written looping over the $nids was to avoid overwriting $node, which this now does. I think we should probably rename the variable to $translation or something?

timmillwood’s picture

Status: Needs work » Reviewed & tested by the community

@catch - I believe you're wrong, $node has always been the translation.

catch’s picture

Status: Reviewed & tested by the community » Needs work

That's not the point I was making, but got my selection in dreditor wrong so it wasn't clear maybe:

$node = $this->entityRepository->getTranslationFromContext($node);

There's no need to reassign $node here, we should use a different variable name, this wasn't a problem with the previous code.

Or in other words, $node was always the translation, now it starts as not being the translation, then becomes the translation.

calmforce’s picture

Status: Needs work » Reviewed & tested by the community

@catch your demands sound arbitrary and capricious. You do not explain why we "should" use a different variable name. The code works perfectly well (I tested it extensively) in its final form, it was reviewed and approved by the module maintainer, @timmillwood. I think we should finish this debate.

timmillwood’s picture

Status: Reviewed & tested by the community » Needs review
StatusFileSize
new887 bytes
new1008 bytes

@calmforce - @catch's view always outweighs the module maintainer. From knowing @catch for nearly 10 years his thoughts and ideas always end up being for the better.

So here's a patch adding the $translation variable.

catch’s picture

So the patch in #8 is overwriting the value of $node in the foreach. Because the objects are by reference in PHP, this means that after that foreach loop, all of the array values would be the translations. Would need to double check, but it might even affect what gets loaded by Node::load() and Node::loadMultiple() later in the request, because that also returns by ref.

By assigning to a different variable name instead of overwriting as in #15, we're not changing the contents of the array in the foreach loop or anywhere else - i.e. $node remains exactly the same object.

An old issue that covered some of this is #154859: Document that cached entity objects are not necessarily cloned any more.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev
quietone’s picture

Version: 9.3.x-dev » 10.0.x-dev
Issue summary: View changes
Status: Needs review » Needs work
Issue tags: +Bug Smash Initiative, +Needs reroll, +Needs tests

This looks like an edge case and the code has not changed. It is still looping on the passed in value $nids.

This needs a reroll and a test.

pooja saraah’s picture

StatusFileSize
new1010 bytes
new1.22 KB

Attached Reroll patch against 10.0.x

immaculatexavier’s picture

#22 patch failed to apply, Need reroll.

rassoni’s picture

Status: Needs work » Needs review
StatusFileSize
new1.24 KB
new1.07 KB

Attached Reroll patch against 10.0.x with fixing failed testing patch issues.
Also take care #16 node suggestion part

shubham chandra’s picture

Version: 10.0.x-dev » 10.1.x-dev
StatusFileSize
new1.24 KB

Applied Patch against #24 in Drupal 10.x.1.

Munavijayalakshmi made their first commit to this issue’s fork.

quietone’s picture

Status: Needs review » Postponed

Statistics is approved for removal. See #3266457: [Policy] Deprecate Statistics module in D10 and move to contrib in D11

This is now Postponed. The status is set according to two policies. The Remove a core extension and move it to a contributed project and the Extensions approved for removal policies.

It will be moved to a contributed Statistics project once the project is created and the Drupal 11 branch is open.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

quietone’s picture

Project: Drupal core » Statistics
Version: 11.x-dev » 1.0.0-beta1
Component: statistics.module » Code
Status: Postponed » Needs review