Problem/Motivation

PHP Fatal error:  Call to a member function getCanonicalRepresentation() on a non-object in core/lib/Drupal/Core/Plugin/Context/Context.php on line 50

The typed data object is null here because it has not been intialized yet.

Proposed resolution

Always use the getTypedDataManager() method provided by the TypedDataTrait to make sure the manager is initialized on demand.

Remaining tasks

Review patch.

User interface changes

none.

API changes

none.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

klausi’s picture

Status: Active » Needs review
FileSize
2.03 KB

klausi opened a new pull request for this issue.

klausi’s picture

FileSize
1.51 KB

Test only patch to demonstrate the fatal error.

klausi’s picture

Issue tags: +d8rules

This affects Rules for D8.

fago’s picture

Status: Needs review » Needs work
  1. +++ b/core/lib/Drupal/Core/Plugin/Context/Context.php
    @@ -46,7 +46,7 @@ public function getContextValue() {
    -    return $this->typedDataManager->getCanonicalRepresentation($this->contextData);
    +    return $this->getTypedDataManager()->getCanonicalRepresentation($this->contextData);
    

    ouch, yes - totally.

  2. +++ b/core/modules/system/src/Tests/Context/ContextIntegrationTest.php
    @@ -0,0 +1,40 @@
    +   * This test ensures that the typed data manager is set correctly on the
    +   * Context class. We cannot test this with a PHPUnit test because we want to
    +   * make sure that the TypedDataTrait works correctly on the Context class.
    

    I do not get this reasoning - why shouldn't it be possible to the test this with phpunit?

    Also, the test case is named a bit weird. integrating with what? Maybe, it should be called ContextTypedDataTest to ensure context works properly with typed data in general?

The last submitted patch, 2: 2467411-testonly.patch, failed testing.

klausi’s picture

Status: Needs work » Needs review
FileSize
2.46 KB

klausi pushed some commits to the pull request.

For an interdiff please see the list of recent commits.

klausi’s picture

You are right, we can actually test this with phpunit. I just never populated \Drupal in a unit test before, but I found other tests doing that, so copied from there.

fago’s picture

Status: Needs review » Needs work
+++ b/core/tests/Drupal/Tests/Core/Plugin/Context/ContextTypedDataTest.php
@@ -0,0 +1,54 @@
+    $typed_data_manager->expects($this->once())
+      ->method('getCanonicalRepresentation')
+      ->willReturn($typed_data);

Thanks, code looks good now except this:

That's cheating. It should be able to return the right value from setting it. Also, the canonical representation for strings is the string.
I think best, you'd set a callback as getCanonicalRepresentation() on the TDM mock which just returns the string. Then, the test should check that the returned context value really is a plain string - it's a test for getContextValue() after all.

klausi’s picture

Status: Needs work » Needs review
FileSize
2.53 KB

klausi pushed some commits to the pull request.

For an interdiff please see the list of recent commits.

klausi’s picture

We don't need a callback, the mocked typed data manager can just return the string. Implemented that and added an assertion on the returned value.

klausi’s picture

FileSize
2.96 KB

klausi pushed some commits to the pull request.

For an interdiff please see the list of recent commits.

klausi’s picture

Talked with fago about this at DevDays and we agreed that implementing this with a return callback on the mocked typed data manager makes more sense to actually invoke the typed data object that is used by the Context class.

fago’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +Contributed project blocker

Thanks, the test makes sense to me like that now.

Added tag as this causes failures in Rules.

webchick’s picture

Priority: Normal » Major
Status: Reviewed & tested by the community » Fixed

Nice catch. Sounds major to me.

Committed and pushed to 8.0.x. Thanks!

  • webchick committed d4431a1 on 8.0.x
    Issue #2467411 by klausi, fago: Context class does not use typed data...

Status: Fixed » Closed (fixed)

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