1

I need to count the number of consecutive years a user has been a member of our organization. For example, if they've been a member from in 2018, 2019, 2020 and 2021, their loyalty will be 4 years.

If they've been a member in 2018, 2019 and 2021, their loyalty will be 1 year (they missed 2020.)

I'm currently using Categories to assign a year to Users in Craft to do the assignment of a year to a person.

Hope that makes sense. I would very much appreciate some help on how to tackle it!

2

If you don't want to build a custom plugin, this would be a good time to use Twig's reduce filter, which takes a set of values and iterates over them to output a single value based on supplied logic.

Using Andy's answer as the basis might look like this (untested):

{% set currentYear = now|date('Y') %}

{% set loyaltyScore = currentUser.years.all()|reduce(
    (score, year) => 
        score == 0 and year == currentYear or 
        score > 0 and year == currentYear - 1 ?
        score + 1,
        0
) %}

I'm assuming your data is already in the right order if it's a category group.

3
  • Thanks so much for this! So my categories are in the format of 2021/22, so I updated a bit to the following, but when I dd on loyaltyScore it's blank. I've not used reduce before so a bit unsure. {% set currentYear = now|date('Y') ~ '/' ~ now|date_modify("+1 year")|date('y') %}
    – brynli64
    Apr 27 at 5:46
  • Trying to do maths on something that's not a number is going to be tricky! You should look to convert the format into a proper number with just a single year. You could convert "2021/22" to "2021" using Twig's slice filter: {{ '2021/22'|slice(4) }} Apr 28 at 8:21
  • Thanks for your help - looks like this one is a bit beyond me.
    – brynli64
    Apr 30 at 1:04
1

Pseudo-code:

  • Fetch all category values, push the year string to an array.

  • Sort that array in descending order by value.

  • Initialise a counter, loop over the array, cast each value as an integer:

    -- if first array value is same as the current year, increase a counter, otherwise break.

    -- if loop year equals previous loop year minus 1, increase a counter otherwise break.

Your loyalty value is the counter.

2
  • The code is the part I'm having trouble with 😅
    – brynli64
    Apr 30 at 1:05
  • That's fairly straightforward PHP, trying to do it in Twig is just making things more complicated (and really, you should minimise the amount of logic/processing in a Twig template). It would be worth looking at creating a Twig filter in a Craft module, which you could pass the user's years history to, e.g. currentUser.years|myfilter
    – Andy
    Apr 30 at 7:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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