Beta phase evaluation

Reference: https://www.drupal.org/core/beta-changes
Issue category Bug because it shows a PHP error warning
Issue priority Major because it is a non-fatal PHP error, or a PHP error triggered under rare circumstances or affecting only a small percentage of all users.
Unfrozen changes Unfrozen because it fixes a bug

Problem/Motivation

Follow-up of #2546210: Views subtokens are broken since the introduction of inline templates for replacements

Warning: strlen() expects parameter 1 to be string, array given in Drupal\Component\Utility\Unicode::validateUtf8()

This error is thrown when using any link field token in a view.

In \Drupal\views\Plugin\views\field\Field::addSelfTokens() is_scalar is only checked for the value when the parent item is an array, not when it's an object.

Proposed resolution

Add check when parent item is an object.

Remaining tasks

  • Add more link token tests?
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Lendude created an issue. See original summary.

Lendude’s picture

The last submitted patch, 2: 2567339-2_test-only.patch, failed testing.

The last submitted patch, 2: 2567339-2_test-only.patch, failed testing.

Lendude’s picture

cilefen’s picture

Component: link.module » views.module

The bug is actually in the views module according to the patch.

Lendude’s picture

Issue summary: View changes
FileSize
9.55 KB

Cleaned up the test a bit, and now it actually tests something.

dawehner’s picture

Issue tags: -Needs tests

I think we no longer needs tests, yeaah!

+++ b/core/modules/views/src/Plugin/views/field/Field.php
@@ -928,7 +928,7 @@ protected function addSelfTokens(&$tokens, $item) {
-          if (!empty($property)) {
+          if (!empty($property) && is_scalar($property->getValue())) {

It would be great to have some quick comment, why we need this check here.

Lendude’s picture

as per #8, added/changed comments.

Lendude’s picture

Once #2488540: Rewrite external links in views fields is in, I think we might need to add a task to test some more scenarios, or if this gets in first, expand the test coverage in #2488540: Rewrite external links in views fields

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

This for now solves a problem.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 9: 2567339-9.patch, failed testing.

Status: Needs work » Needs review

Lendude queued 9: 2567339-9.patch for re-testing.

Status: Needs review » Needs work

The last submitted patch, 9: 2567339-9.patch, failed testing.

Status: Needs work » Needs review

Lendude queued 9: 2567339-9.patch for re-testing.

Lendude’s picture

Status: Needs review » Reviewed & tested by the community

random fails, back to RTBC

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 9: 2567339-9.patch, failed testing.

Status: Needs work » Needs review

Lendude queued 9: 2567339-9.patch for re-testing.

Lendude’s picture

Status: Needs review » Reviewed & tested by the community

Random test fail, back to RTBC

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 9: 2567339-9.patch, failed testing.

The last submitted patch, 9: 2567339-9.patch, failed testing.

Lendude’s picture

Status: Needs work » Reviewed & tested by the community

More random test fails, back to RTBC

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 9: 2567339-9.patch, failed testing.

Status: Needs work » Needs review

Lendude queued 9: 2567339-9.patch for re-testing.

Lendude’s picture

Status: Needs review » Reviewed & tested by the community

Random test fail, back to RTBC

alexpott’s picture

Status: Reviewed & tested by the community » Needs review

Why is $property->getValue() returning an object and if said object implements __toString() is it not okay?

Lendude’s picture

$property->getValue() is returning an array in the case of the link token for {{ field_link__options }}. So no really good way to convert that to a string that I can see (beside imploding it on an arbitrary delimiter).
Not sure if $property->getValue() ever returns an object, but I guess checking for that and __toString() is an option. Added that to the patch.

penyaskito’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community
FileSize
105.19 KB

Edited the content view and played around with tokens for reproducing the issue.
Did the same with the patch applied and the error disappears.

Last patch resolves concerns at #26, so I think we can set it back to RTBC.

Added beta evaluation template.

catch’s picture

Status: Reviewed & tested by the community » Needs review

Is that a valid return value for the link token though?

Lendude’s picture

Issue summary: View changes

Updated the issue summary a bit, to make it clear that the problem comes form the parent item being an array or an object, not the actual return value.

There are checks in place to sanitize/discard the return value when the parent item is an array that are not in place when the parent item is an object.

Also the comment above this bit of code states:

// Use \Drupal\Component\Utility\Xss::filterAdmin() because it's user data
// and we can't be sure it is safe. We know nothing about the data,
// though, so we can't really do much else.

So as to what we can expect here it's apparently all a bit of a guess.

Does that answer your question? Or were you referring to something else?

rootwork’s picture

Just wanted to confirm that #27 does apply and fix the problem, as of RC1. Not sure about catch's question in #29 though but hoping to see this move forward.

Lendude’s picture

Talked to @catch about this on IRC a while ago, and he was really wondering about the bit

We know nothing about the data

and why that is. Didn't have an answer for him.

dawehner’s picture

We know nothing about the data

+++ b/core/modules/views/src/Plugin/views/field/Field.php
@@ -928,11 +928,17 @@ protected function addSelfTokens(&$tokens, $item) {
+          if (!empty($property) && is_scalar($property->getValue())) {
             $tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = Xss::filterAdmin($property->getValue());
           }
+          elseif (is_object($property->getValue()) && method_exists($property->getValue(), '__toString')) {
+            $tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = Xss::filterAdmin((string) $property->getValue());

Talked with fago today. We should check whether these things are primitive items ... in which case we know how to render them.

dawehner’s picture

Status: Needs review » Needs work

Back to needs work

Lendude’s picture

Status: Needs work » Needs review
FileSize
1.92 KB
10.18 KB

Now checking if TypedDataInterface is used and the just calling getString on that. Will check with @fago if this should be done safer and check for PrimitiveBase instead.

But for now lets see what this does.

Lendude’s picture

talked to @fago and he told me using the TypedDataInterface is fine.

Lendude’s picture

Proper order of the use statements and removed some newlines.

ultimike’s picture

I hit this issue and tried out the patch in comment 37 and it fixed my issue.

thanks,
-mike

dawehner’s picture

Status: Needs review » Needs work

Thank you @lendude!!

here are a couple of nitpicks / one small remark on the test.

+++ b/core/modules/views/src/Plugin/views/field/Field.php
@@ -932,8 +933,10 @@ protected function addSelfTokens(&$tokens, $item) {
+          if (!empty($property) && $property instanceof TypedDataInterface) {
+            $tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = Xss::filterAdmin($property->getString());
           }

I like this solution now!

  1. +++ b/core/modules/link/src/Tests/Views/LinkViewsTokensTest.php
    @@ -0,0 +1,99 @@
    +  protected $field_name = 'field_link';
    

    Let's just use camelcase ...

  2. +++ b/core/modules/link/src/Tests/Views/LinkViewsTokensTest.php
    @@ -0,0 +1,99 @@
    +  protected function setUp() {
    

    netpick: let's use {@inheritdoc}

  3. +++ b/core/modules/link/src/Tests/Views/LinkViewsTokensTest.php
    @@ -0,0 +1,99 @@
    +  function testLinkViewsTokens() {
    

    Nitpicks: Let's use public here.

  4. +++ b/core/modules/link/src/Tests/Views/LinkViewsTokensTest.php
    @@ -0,0 +1,99 @@
    +      $values[$this->field_name][] = ['uri' => $uri, 'title' => $title];
    +      $this->drupalCreateNode($values);
    ...
    +      // Options is an array and should return empty after token replace.
    +      $this->assertRaw("Raw options: .");
    

    Let's fill out options to ensure that also maps are filled out properly. Those fields also have a getString() implementation.

Lendude’s picture

Status: Needs work » Needs review
FileSize
2.14 KB
10.29 KB

@dawehner thanks for the review!

1. fixed
2. fixed
3. fixed
4. Filled the options setting and the settings get applied as you can see in the test. But the options still come back as an empty string. This is because on $values get set in the Map and not properties. I don't know if I need to set it in a different way or that there is something else going on. Since there seems to be no way to set 'options' through the UI (at least none that I could find), I'm not sure what it expects.

jibran’s picture

Looks ready to me. Just one question.

+++ b/core/modules/views/src/Plugin/views/field/Field.php
@@ -932,8 +933,10 @@ protected function addSelfTokens(&$tokens, $item) {
-            $tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = Xss::filterAdmin($property->getValue());
...
+            $tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = Xss::filterAdmin($property->getString());

Do we need an update function to fix this for all the existing views using this token?

mikeker’s picture

Do we need an update function to fix this for all the existing views using this token?

I don't believe so. The token doesn't change, just the value that replaces it.

dawehner’s picture

I don't believe so. The token doesn't change, just the value that replaces it.

Yeah, right. Let's try to not overthing update paths.

jibran’s picture

Status: Needs review » Reviewed & tested by the community

Ok then.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 40: 2567339-40.patch, failed testing.

Lendude’s picture

Status: Needs work » Reviewed & tested by the community

testbot glitch

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 40: 2567339-40.patch, failed testing.

Lendude’s picture

Status: Needs work » Reviewed & tested by the community

uhh it's still green, not sure why it says it failed...

alexpott’s picture

Status: Reviewed & tested by the community » Needs review
+++ b/core/modules/link/src/Tests/Views/LinkViewsTokensTest.php
@@ -0,0 +1,102 @@
+      // Raw options: {{ field_link__options }}<br />
+      // Options is an array and should return empty after token replace.
+      $this->assertRaw("Raw options: .");

What is the point of having a token that can't ever be displayed? Do we need to handle this better?

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

IMHO this is out of scope of this issue. This is just about fixing the field tokens itself, while your request is about fixing the general token functionality in views, IMHO.
Here is a follow up: #2657024: Hide non existing views tokens

Lendude’s picture

I agree with @dawehner that this feel like a bit of a scope creep to fix that here.

That said, I was surprised that the token stayed empty after adding some settings like I pointed out in #40.4, so I could totally get behind updating the comment to indicate that an empty sting this is not the expected behaviour for that token and referencing the issue that dawehner created.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

@dawehner thanks for creating #2657024: Hide non existing views tokens - I think if a token can't be made into a string then it can't be a token right... seems very wrong.

Committed ba13b1b and pushed to 8.0.x and 8.1.x. Thanks!

  • alexpott committed d907b8b on 8.1.x
    Issue #2567339 by Lendude, penyaskito, dawehner: PHP Warning when using...

  • alexpott committed ba13b1b on
    Issue #2567339 by Lendude, penyaskito, dawehner: PHP Warning when using...

Status: Fixed » Closed (fixed)

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