2

I've upgraded a project to craft 4, and now I'm getting an error on my entry query.

Below is the code I have:

{% set queryFeaturedEvents = entry.featuredEventsLimited.limit(3) %}

{% set queryEventsOngoing = craft.entries.section('events')
    .type(['event', 'uitEvent'])
    .id(['not', queryFeaturedEvents.ids()])
    .datetimeStart('<= ' ~ now | date('Y-m-d') | date('c'))
    .datetimeEnd('>= ' ~ now | date('Y-m-d') | date('c')) %}

{% set queryEventsUpcoming = craft.entries.section('events')
    .type(['event', 'uitEvent'])
    .id(['not', queryFeaturedEvents.ids() | merge(queryEventsOngoing.ids())])
    .datetimeStart('>= ' ~ now | date('Y-m-d') | date('c')) %}

I get an array to string conversion error, that seemingly gets triggered by the queryEventsOngoing.ids() (when I put that in a seperate variable, the code stops there.) I have a feeling it has something to do with my id exclusion in the first query. When I look further into the error stack I see following: in C:\Users\julie\Documents\CabinetC\Repos\merode\vendor\craftcms\cms\src\elements\db\ElementQuery.php at line 1330– craft\helpers\Db::parseNumericParam('elements.id', ['not', [2849138, 2932212, 2464675]]) I would think that it should be ['not', 2849138, 2932212, 2464675] ? The code did work with craft 3 so I'm a bit at a loss as to why it doesn't work any more. Anyone have any ideas on how I can fix this?

2 Answers 2

2

You are correct in your assumption, the element query will not take an array as values, and they should be flat out.

In Craft 4, all element queries can now be returned as collections. So you can leverage their functionality to actually make this easier.

{# array #}
{% set queryFeaturedEvents = entry.featuredEventsLimited.limit(3).ids() %}

{# array #}
{% set queryEventsOngoing = craft.entries.section('events')
    .type(['event', 'uitEvent'])
    .id(['not', queryFeaturedEvents.ids()])
    .datetimeStart('<= ' ~ now | date('Y-m-d') | date('c'))
    .datetimeEnd('>= ' ~ now | date('Y-m-d') | date('c'))
    .ids()
%}

{% set parameter = collect(['not']) %}

{% set excludedIds = parameter.merge(queryFeaturedEvents).merge(queryEventsOngoing) %}

The above should generate your array as ['not', 2849138, 2932212, 2464675]

And then you should be simply able to do:

{% set queryEventsUpcoming = craft.entries.section('events')
    .type(['event', 'uitEvent'])
    .id(excludedIds)
    .datetimeStart('>= ' ~ now | date('Y-m-d') | date('c'))
    .collect()
%}

Hope this helps!

8
  • Thank you for the help. Unfortunatly, I'm still getting errors. Now I'm getting 'Impossible to invoke a method ("collect") on an array.' , featuredEventsLimited is an entry-field type Commented Mar 8, 2023 at 13:56
  • Where exactly (which line) would you get this error right now? I'm assuming it's on the parameter variable? Commented Mar 8, 2023 at 13:58
  • 1
    I don't think it's accurate to say that In Craft 4, all element queries are now returned as collections - they're only returned as collections if you use .collect() instead of one of the standard execution methods like .one() or .all()... or in this case .ids(). The exception is for eager loaded elements, which are always returned as collections, which still trips me up. Commented Mar 8, 2023 at 14:15
  • its the .ids().collect() on the first line of code that went wrong for me. If I change the first line of code to just .ids() and then use the 'set parameter = collect logic' for that first block, I can get it to work Commented Mar 8, 2023 at 14:40
  • I edited my answer. You are right tho .ids() are automatically arrays. Thank you for pointing out my choice of words @JamesSmith. Although Element Queries are indeed just returned as collections when .collect() is used. Imo it's a good practice to use them as they bring so many benefits to the table! Commented Mar 8, 2023 at 14:49
1

I'm slightly surprised this worked before, as .ids() does return an array and I didn't think ('not', [1,2,...]) was valid in 3.x

Anyways, wrap queryFeauturedEvents.ids() in implode() and you should be good!

https://www.php.net/manual/en/function.implode.php

3
  • 1
    yeah, beats me why it worked before. As I'm doing this in twig, implode is not available to me (tried the twig join, did not work either). Using that twig 'collect' function did the trick. Commented Mar 8, 2023 at 14:49
  • 1
    It shouldn't have worked in Craft 3 either, that is correct. But I think it's nicer to simply use the new Collection properties which are baked in rather than using native PHP functions tho! Commented Mar 8, 2023 at 14:51
  • Collections are great. Not sure why I read this as php in my head, sorry!
    – cherrykoda
    Commented Mar 8, 2023 at 15:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.