Problem/Motivation

Message Error: Call to a member function getTotalCount() on bool in statistics_tokens() (line 47 of core/modules/statistics/statistics.tokens.inc)

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

pavnish created an issue. See original summary.

daffie’s picture

Priority: Critical » Normal
Status: Active » Postponed (maintainer needs more info)

@pavnish: Could you tell a bit more how you got the error message. Helps with understanding how you got this error and how to fix it. Could you tell why you think this issue is "critical". See: https://www.drupal.org/docs/develop/issues/fields-and-other-parts-of-an-....

pavnish’s picture

@daffie Hi ,
We are using token on Node detail ,This issue comes when we create a node and redirect to node detail page initially there is zero count for the node.
I think we need to be more take care of these line of code:
if ($name == 'total-count') {
$replacements[$original] = $stats_storage->fetchView($node->id())->getTotalCount();
}
elseif ($name == 'day-count') {
$replacements[$original] = $stats_storage->fetchView($node->id())->getDayCount();
}
elseif ($name == 'last-view') {
$replacements[$original] = \Drupal::service('date.formatter')->format($stats_storage->fetchView($node->id())->getTimestamp());
}

@daffie Can you please suggest we can above code like this.
$statistics = $stats_storage->fetchView($node->id());
if ($name == 'total-count') {
if (($statistics instanceof StatisticsViewsResult)) {
$replacements[$original] = $stats_storage->fetchView($node->id())->getTotalCount();
}else{
$replacements[$original] = 0;
}

pavnish’s picture

daffie’s picture

Status: Postponed (maintainer needs more info) » Active

When I take a look at the interface of Drupal\statistics\StatisticsStorageInterface is see that the method fetchView() returns the expected result of FALSE:

  /**
   * Returns the number of times a single entity has been viewed.
   *
   * @param int $id
   *   The ID of the entity to fetch the views for.
   *
   * @return \Drupal\statistics\StatisticsViewsResult|false
   *   If the entity exists, a value object representing the number of times if
   *   has been viewed. If it does not exist, FALSE is returned.
   */
  public function fetchView($id);

My suggestion would be to test the return value and only then call getTotalCount(). Just like you are suggestion in comment #2.

durgeshs’s picture

Uploaded patch for this issue, @pavnish please review.

pavnish’s picture

Status: Active » Needs review
daffie’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

I do not like the patch from comment #6. The method fetchView() is called twice and the fetchView() calls fetchViews(). The fetchViews() runs every time it gets called a database query. I think that it is better to store the result of fetchView() is a variable and then test the value of that variable.

pavnish’s picture

Assigned: Unassigned » pavnish

Working on it so I am assigning this to myself.

pavnish’s picture

Assigned: pavnish » Unassigned
Status: Needs work » Needs review
FileSize
1.75 KB
1.75 KB

Hi @daffie Thanks for the valuable feedback
The changes as you suggested in #8 have been addressed in this patch.
I would be very thankful if you can review this patch.

daffie’s picture

Status: Needs review » Needs work

@pavnish: That is better, only now will the view be loaded every time there are tokens when the type is 'node' even when there are no tokens with the name: 'total-count', 'day-count' or 'last-view'. Therefore the view will be loaded lots of times when it is not necessary. The code change I was looking for is something like:

      if ($name == 'total-count') {
        $node_view = $stats_storage->fetchView($node->id());
        $replacements[$original] = ($node_view) ? $node_view->getTotalCount() : 0;
      }

The same for 'day-count' and 'last-view'. Also, we need testing for this change.

pavnish’s picture

Assigned: Unassigned » pavnish

Working on #11

pavnish’s picture

Assigned: pavnish » Unassigned
Status: Needs work » Needs review
FileSize
1.36 KB
1.5 KB

@daffie #11 has been addressed in this patch.

daffie’s picture

Status: Needs review » Needs work

Now we only need the testing to be added.

daffie’s picture

+++ b/core/modules/statistics/statistics.tokens.inc
@@ -44,13 +44,16 @@ function statistics_tokens($type, $tokens, array $data, array $options, Bubbleab
-        $replacements[$original] = \Drupal::service('date.formatter')->format($stats_storage->fetchView($node->id())->getTimestamp());
+        $node_view = $stats_storage->fetchView($node->id());
+        $replacements[$original] = \Drupal::service('date.formatter')->format($node_view->getTimestamp());

This change does not help fixing the bug, therefore it can be removed.

ayushmishra206’s picture

Status: Needs work » Needs review
FileSize
800 bytes
1.18 KB

Reverted the change suggested in #15. Please review.

daffie’s picture

Status: Needs review » Needs work

Now we only need the testing to be added.

WalkingDexter’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests
FileSize
3.23 KB

Added tests. I think we should also fix the error for the 'last-view' token.

daffie’s picture

Status: Needs review » Needs work

@WalkingDexter: Thak you for adding the tests!

The patch is for me almost RTBC.

  1. +++ b/core/modules/statistics/statistics.tokens.inc
    @@ -40,22 +40,29 @@ function statistics_tokens($type, $tokens, array $data, array $options, Bubbleab
    +    $node_view = NULL;
    ...
    +        $node_view = $node_view ?? $stats_storage->fetchView($node->id());
    ...
    +        $node_view = $node_view ?? $stats_storage->fetchView($node->id());
    ...
    +        $node_view = $node_view ?? $stats_storage->fetchView($node->id());
    ...
    +      $node_view = $node_view ?? $stats_storage->fetchView($node->id());
    

    I like this change. Now the view gets only loaded once.

  2. +++ b/core/modules/statistics/statistics.tokens.inc
    @@ -40,22 +40,29 @@ function statistics_tokens($type, $tokens, array $data, array $options, Bubbleab
    -      $replacements += $token_service->generate('date', $created_tokens, ['date' => $stats_storage->fetchView($node->id())->getTimestamp()], $options, $bubbleable_metadata);
    +      $node_view = $node_view ?? $stats_storage->fetchView($node->id());
    +      $replacements += $token_service->generate('date', $created_tokens, ['date' => $node_view ? $node_view->getTimestamp() : 0], $options, $bubbleable_metadata);
    

    There is no testing for this change.

WalkingDexter’s picture

Status: Needs work » Needs review
FileSize
4 KB

Improved tests.

daffie’s picture

@walkingdexter: Could you create an interdiff file. It makes reviewing a lot easier. See: https://www.drupal.org/docs/develop/git/using-git-to-contribute-to-drupa...

WalkingDexter’s picture

FileSize
1.63 KB

Sure.

Status: Needs review » Needs work

The last submitted patch, 20: 3190820-20.patch, failed testing. View results

WalkingDexter’s picture

Hmm...strange error. Running a new test.

WalkingDexter’s picture

Status: Needs work » Needs review

The test was successful, that's better :)

daffie’s picture

Status: Needs review » Reviewed & tested by the community

The bug is fixed in the patch.
There is also testing for the fix.
All code changes look good to me.
For me it is RTBC.

@walkingdexter: Thank you for working on the patch!

  • catch committed d8bba17 on 9.3.x
    Issue #3190820 by pavnish, WalkingDexter, ayushmishra206, durgeshs,...

  • catch committed 5a1c88a on 9.2.x
    Issue #3190820 by pavnish, WalkingDexter, ayushmishra206, durgeshs,...
catch’s picture

Version: 8.9.x-dev » 9.1.x-dev
Status: Reviewed & tested by the community » Fixed

Committed/pushed to 9.3.x, cherry-picked to 9.2.x and 9.1.x, thanks!

  • catch committed 4bc7f21 on 9.1.x
    Issue #3190820 by pavnish, WalkingDexter, ayushmishra206, durgeshs,...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.