Problem/Motivation

version 2.1.1 giving WSOD when calling calender_link() inside views global:custom text field twig, Here is the drupal log error:
Drupal\calendar_link\CalendarLinkException: Could not get valid string from input. in Drupal\calendar_link\Twig\CalendarLinkTwigExtension->getString() (line 204 of /mnt/www/html/sitecom/docroot/modules/contrib/calendar_link/src/Twig/CalendarLinkTwigExtension.php).

Steps to reproduce

Place this code in the Global: custom text field in view(page).
{% set link = calendar_link('ics', title, date(field_event_dates_1), date(field_event_dates_2), FALSE, field_event_city) %}
or
{% set link = calendar_link('ics', 'testing title', date('Dec 16, 2021'), date('Dec 17, 2021'), FALSE, 'testing description', 'houston') %}
<div class="myCal" data="{{ link }}">Add to Calendar</div>

screenshot

Comments

bakulahluwalia created an issue. See original summary.

bakulahluwalia’s picture

Issue summary: View changes
StatusFileSize
new108.35 KB
liquidcms’s picture

I get the same issue but with more details:

passing title (a views field token) gives me:
some error about title but i cant see it now as it only chokes on the date error.. odd.

passing various date formatted fields gives me:
Drupal\calendar_link\CalendarLinkException: Could not get valid \DateTime object from input

- suggesting i need to pass a DateTime object - not sure why this module would make it so difficult; why not have the module convert to Datetime()?

wells’s picture

The twig function attempts to coerce various data types in to \DateTime (see src/Twig/CalendarLinkTwigExtension.php#L218). I think the issue here is that the date and string coercion methods are not accounting properly for data types passed from Views (I have never used the functions from Views so hadn't thought to test them this way).

Tasks required for this ticket are:

  • Determine data types passed from views.
  • Refactor twig functions to account for those data types. Probably to check for interface instances instead of specific classes.
  • Add tests for Views use cases.
  • BONUS: Improve exception output to be more useful (i.e., identify the data type that cannot be coerced).

I'd be thrilled to get an MR for this but otherwise I'll get around to looking when I am able.

liquidcms’s picture

i made changes to get this working in Views by simply checking if datetime object and if not, converting it and the same for string function which checks if twig markup, i added similar to check if std core markup object.

pretty minor changes but now works with a Views custom field like this:

{% set link = calendar_link('google', title ~ " (" ~ field_session_language ~ ")", field_session_date | split(' - ')[0] | striptags,  field_session_date | split(' - ')[1] | striptags, FALSE, body, "My Location") %}
<a href="{{ link }}">Add to Calendar</a>

the split function, if not obvious, is because i am using a date range field and there is no mechanism yet to output only start or end. So this simply uses twig to split them apart.

this works great for google as my example shows but doesn't work for ICS (nothing to do with my change). The link i get for ICS is something like:

http://mysite.com/en/news/events/text/calendar;charset=utf8;base64,QkVHSU46VkNBTEVOREFSDQpWRVJTSU9OOjIuMA0KQkVHSU46VkVWRU5UDQpVSUQ6YjcxM2RlZmI3YzY0YzFkMzBkN2U5M2M2NmM4MjhhZDANClNVTU1BUlk6TmV3IEV2ZW50IDEgKEJpbGluZ3VhbCkNCkRUU1RBUlQ7VFpJRD1BbWVyaWNhL1Rvcm9udG86MjAyMTExMjlUMDIwMDAwDQpEVEVORDtUWklEPUFtZXJpY2EvVG9yb250bzoyMDIxMTEyOVQwMzAwMDANCkRFU0NSSVBUSU9OOjxwPkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0XCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdFwsIHNlZCBkaWFtIG5vbnVtbXkgbmliaCBldWlzbW9kIHRpbmNpZHVudCB1dCBsYW9yZWV0IGRvbG9yZSBtYWduYSBhbGlxdWFtIGVyYXQgdm9sdXRwYXQuIER1aXMgYXV0ZW0gdmVsIGV1bSBpcml1cmUgZG9sb3IgaW4gaGVuZHJlcml0IGluIHZ1bHB1dGF0ZSB2ZWxpdCBlc3NlIG1vbGVzdGllIGNvbnNlcXVhdFwsIHZlbCBpbGx1bSBkb2xvcmUgZXUgZmV1Z2lhdCBudWxsYSBmYWNpbGlzaXMgYXQgdmVybyBlcm9zIGV0IGFjY3Vtc2FuIGV0IGl1c3RvIG9kaW8gZGlnbmlzc2ltIHF1aSBibGFuZGl0IHByYWVzZW50IGx1cHRhdHVtIHp6cmlsIGRlbGVuaXQgYXVndWUgZHVpcyBkb2xvcmUgdGUgZmV1Z2FpdCBudWxsYSBmYWNpbGlzaS48L3A+XG5cbjxwPlN0ZXQgY2xpdGEga2FzZCBndWJlcmdyZW5cLCBubyBzZWEgdGFraW1hdGEgc2FuY3R1cyBlc3QgTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQuIEF0IHZlcm8gZW9zIGV0IGFjY3VzYW0gZXQganVzdG8gZHVvIGRvbG9yZXMgZXQgZWEgcmVidW0uIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0XCwgY29uc2V0ZXR1ciBzYWRpcHNjaW5nIGVsaXRyXCwgc2VkIGRpYW0gbm9udW15IGVpcm1vZCB0ZW1wb3IgaW52aWR1bnQgdXQgbGFib3JlIGV0IGRvbG9yZSBtYWduYSBhbGlxdXlhbSBlcmF0XCwgc2VkIGRpYW0gdm9sdXB0dWEuPC9wPlxuDQpMT0NBVElPTjpNeSBMb2NhdGlvbg0KRU5EOlZFVkVOVA0KRU5EOlZDQUxFTkRBUg==

I am not entirely sure how that is supposed to work although i get it is encoding the ICS file and passing on url (i guess rather than how the Calendar Links Token module does it which is using the same library but creates a public ics file and a link to that file). When i click that link i simply get 404 (which makes sense as no route to that link). When i sort out the ics issue i'll post patch.

liquidcms’s picture

i tried using this for my A tag:
<a href="/{{ link }}">Add to Calendar</a>

and this gives me:

http://ssc.peter/data:text/calendar;charset=utf8;base64,QkVHSU46VkNBTEVOREFSDQpWRVJTSU9OOjIuMA0KQkVHSU46VkVWRU5UDQpVSUQ6YjcxM2RlZmI3YzY0YzFkMzBkN2U5M2M2NmM4MjhhZDANClNVTU1BUlk6TmV3IEV2ZW50IDEgKEJpbGluZ3VhbCkNCkRUU1RBUlQ7VFpJRD1BbWVyaWNhL1Rvcm9udG86MjAyMTExMjlUMDIwMDAwDQpEVEVORDtUWklEPUFtZXJpY2EvVG9yb250bzoyMDIxMTEyOVQwMzAwMDANCkRFU0NSSVBUSU9OOjxwPkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0XCwgY29uc2VjdGV0dWVyIGFkaXBpc2NpbmcgZWxpdFwsIHNlZCBkaWFtIG5vbnVtbXkgbmliaCBldWlzbW9kIHRpbmNpZHVudCB1dCBsYW9yZWV0IGRvbG9yZSBtYWduYSBhbGlxdWFtIGVyYXQgdm9sdXRwYXQuIER1aXMgYXV0ZW0gdmVsIGV1bSBpcml1cmUgZG9sb3IgaW4gaGVuZHJlcml0IGluIHZ1bHB1dGF0ZSB2ZWxpdCBlc3NlIG1vbGVzdGllIGNvbnNlcXVhdFwsIHZlbCBpbGx1bSBkb2xvcmUgZXUgZmV1Z2lhdCBudWxsYSBmYWNpbGlzaXMgYXQgdmVybyBlcm9zIGV0IGFjY3Vtc2FuIGV0IGl1c3RvIG9kaW8gZGlnbmlzc2ltIHF1aSBibGFuZGl0IHByYWVzZW50IGx1cHRhdHVtIHp6cmlsIGRlbGVuaXQgYXVndWUgZHVpcyBkb2xvcmUgdGUgZmV1Z2FpdCBudWxsYSBmYWNpbGlzaS48L3A+XG5cbjxwPlN0ZXQgY2xpdGEga2FzZCBndWJlcmdyZW5cLCBubyBzZWEgdGFraW1hdGEgc2FuY3R1cyBlc3QgTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQuIEF0IHZlcm8gZW9zIGV0IGFjY3VzYW0gZXQganVzdG8gZHVvIGRvbG9yZXMgZXQgZWEgcmVidW0uIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0XCwgY29uc2V0ZXR1ciBzYWRpcHNjaW5nIGVsaXRyXCwgc2VkIGRpYW0gbm9udW15IGVpcm1vZCB0ZW1wb3IgaW52aWR1bnQgdXQgbGFib3JlIGV0IGRvbG9yZSBtYWduYSBhbGlxdXlhbSBlcmF0XCwgc2VkIGRpYW0gdm9sdXB0dWEuPC9wPlxuDQpMT0NBVElPTjpNeSBMb2NhdGlvbg0KRU5EOlZFVkVOVA0KRU5EOlZDQUxFTkRBUg==

which seems closer; but still blocked by Drupal. Not a 404 though, simply a 403 (forbidden) so thinking an .htaccess thing and possibly pointing to the idea that this is not the correct way to do this? Maybe the create/link .ics file is the way to go?

liquidcms’s picture

back with my original <a href="{{ link }}">Add to Calendar</a>

and i see that even though on hover it shows: mysite.com/en/news/events/text/calendar.... etc, if i inspect the HTML source it is actually:

<a href="text/calendar;charset=utf8;base64,QkVHSU46VkNBTEVOREFSDQpWRVJT...">Add to Calendar</a>

which is almost right except something has removed the data: at the beginning. If i modify the url directly with browser dev tools and add it back in; the link works correctly.

liquidcms’s picture

Title: version 2.1.1 giving WSOD when calling calender_link() inside views global:custom text field twig » Views support
Version: 2.1.1 » 2.x-dev
Category: Bug report » Feature request
Priority: Major » Normal
Status: Active » Needs review
StatusFileSize
new1.33 KB

This patch allows this to work with Views; but as mentioned above, something in Drupal removes the data: prefix to the href for ICS links. Got tired of looking for a proper solution so i just fixed it with js using this:

    $("a.ics-link").each(function() {
      var href = $(this).attr('href');
      href = href.replace("text/calendar", "data:text/calendar");
      $(this).attr('href', href);
    });
wells’s picture

Thanks for your efforts here @liquidcms. I’ll review this in the next few days. Did you or @bakulahluwalia have this working on Views before the 2.1.x releases? If so the URL data stripping part of this seems curious…

bakulahluwalia’s picture

@wells, yes it's still working fine with views on 2.0.0.
@liquidcms we have another issue where we discussed the Javascript solution for making that data: working. Check here: https://www.drupal.org/project/calendar_link/issues/3188283

liquidcms’s picture

Not sure how that could have ever worked in Views unless 2.1 is completely different than 2.0. Sorry, I've never used this module before so hadn't tried it.

And yes, the data: stripping thing is odd. If someone tells me this doesn't happen, I'll dig into it further. Not sure why it would work directly in twig if filtered elsewhere. But have never tried the direct twig use. That should be tested with my patch though to make sure this didn't break the original use case.

liquidcms’s picture

Hmm, not sure how I missed that other issue when looking at this but yes, it does sound like this used to work in Views. Must have been done much different then.

And thanks for shedding light on the data: stripping thing. That was what I suspected was going on. I don't see how its a security issue and certainly isn't in my specific use case (intranet site). Perhaps something to do with user input adding a link with a PHP file in it? Not sure.

And my js approach is better. :)

bakulahluwalia’s picture

@liquidcms the patch submitted at #8 is not working. The reason's not working: In your patch, you are checking if it's not a date object then convert it. But, if someone is using date field(add date field in your content type and use it in view) inside views and passing it as via token then views add the tag in it for display. This makes the whole date field a string that looks like this: <time datetime="2022-01-17T12:00:00Z" class="datetime">2022-01-17</time>.

Here is the error:
Twig\Error\RuntimeError: An exception has been thrown during the rendering of a template ("DateTime::__construct(): Failed to parse time string (<time datetime="2022-01-17T12:00:00Z" class="datetime">2022-01-17</time> ) at position 0 (<): Unexpected character") in "__string_template__981c174dcaef85a57a5dbeeedb731c76de6b859aed79a9563d50055a433f9e89" at line 2. in Twig\Template->displayWithErrorHandling() (line 419 of /app/vendor/twig/twig/src/Template.php).

bakulahluwalia’s picture

oops, the editor removed the tags.
This is how the string looks like:
<time datetime="2022-01-17T12:00:00Z" class="datetime">2022-01-17</time>

liquidcms’s picture

@bakulahluwalia, thanks for testing this with the original fields use case. I don't use that case so not too concerned about it.. but please submit patch to fix my mistake. :)

bakulahluwalia’s picture

@liquidcms, the patch might not be required for my use case, I found the solution. But I am happy to test your patch again for your use case. Please provide instructions on how you are passing values to views and from views to calendar_link() method.

@wells, Changing the formatter type dropdown from default to plain in the views date field worked for me. Maybe we can just add some documentation on how to use calendar_link() with views that might help others. But we should do something about the WSOD screen with default formatter case. It should at least not take the page down. I can provide the patch for that. Please advice.

wells’s picture

Status: Needs review » Needs work

@bakulahluwalia @liquidcms I don't necessarily love the approach being pursued here. I see that the Views output when using the twig functions this way is just plain text and converting that to a DateTime object works (for plain output) using the patch in #8. But I don't like the idea of applying the system timezome to the created DateTime object. This does support, for example, modifying the timezone of the outputted field in Views. What would be the drawback of just using the UTC value that Views outputs?

As for the default formatter -- it does seem we should handle that as well. I guess my parsing the HTML time tag even though that seems like such overkill...

bakulahluwalia’s picture

@wells, I agree on the timezone part. Can you please conclude it? Based on the conclusion I can write some code and submit a patch.
Here are some notes:
1) Update code to handle both plain text and default formatter version while calling calendar_links() method from views
2) Update the module page documentation on how to use it with views
3) Handle the exception for the current WSOD screen

wells’s picture

@bakulahluwalia I'm not totally sure what to conclude. It seems like handling the default will dictate how we should deal with timezones, right? That or we simply don't support the default and update the documentation to reflect. Regardless, I'd be happy to review your approach to the items you list in your notes.

wells’s picture

Status: Needs work » Needs review
StatusFileSize
new5.55 KB
new3.8 KB

Here's a new pass at this. Attached patch attempts to handle string-based date representations and works with the default views formatter for dates, plain text, and even specific forms of relative dates.

Also attempting to add some new tests to start covering these various use cases. More work to be done there.

wells’s picture

StatusFileSize
new3.77 KB
new5.24 KB

Re-rolling #20 after fixes to base branch tests.

The last submitted patch, 21: 3249457-21-tests-only.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 21: 3249457-21.patch, failed testing. View results

wells’s picture

Status: Needs work » Needs review
StatusFileSize
new3.78 KB
new5.25 KB

Fixing missed declaration in tests twig syntax.

The last submitted patch, 24: 3249457-24-tests-only.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 24: 3249457-24.patch, failed testing. View results

wells’s picture

Status: Needs work » Needs review
StatusFileSize
new5.3 KB

Adjusting expected test results to use encoding ampersands.

Status: Needs review » Needs work

The last submitted patch, 27: 3249457-27.patch, failed testing. View results

wells’s picture

Status: Needs work » Needs review
StatusFileSize
new5.33 KB

Add TZ to string-based test.

Status: Needs review » Needs work

The last submitted patch, 29: 3249457-29.patch, failed testing. View results

wells’s picture

Status: Needs work » Needs review
StatusFileSize
new5.32 KB

Use UTC to simplify basic string test.

Status: Needs review » Needs work

The last submitted patch, 31: 3249457-31.patch, failed testing. View results

wells’s picture

Status: Needs work » Needs review
StatusFileSize
new6.36 KB
new7.98 KB

Ok so the results from #20 onward actually don't resolve the lack of TZ data provided by Views outputs. Attaching a new approach that only supports the default Views formatter creating a time HTML element. Other formatters (plain text, primarily) simply don't give enough context for accurate handling of dates. The module documentation will also need to be updated to note this.

The last submitted patch, 33: 3249457-33-tests-only.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 33: 3249457-33.patch, failed testing. View results

wells’s picture

Status: Needs work » Needs review
StatusFileSize
new6.36 KB
new7.99 KB

D'oh! Reapply Twig syntax fix.

The last submitted patch, 36: 3249457-36-tests-only.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 36: 3249457-36.patch, failed testing. View results

wells’s picture

Status: Needs work » Needs review
StatusFileSize
new3.35 KB
new4.98 KB

Revert accidental change to expected output of testCalendarLinksFunction.

The last submitted patch, 39: 3249457-39-tests-only.patch, failed testing. View results

  • wells committed ba90c3d on 2.x
    Issue #3249457 by wells, liquidcms, bakulahluwalia: Views support
    
wells’s picture

Status: Needs review » Fixed

Status: Fixed » Closed (fixed)

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

joseph.olstad’s picture

This functionality is broken after upgrading from Drupal 10.2 to Drupal 10.3.

TO get this functionality working

downgrade to Drupal 10.2