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!

supazu
  • 576
  • 4
  • 12

2 Answers2

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.

James Smith
  • 5,154
  • 14
  • 15
  • 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') %}

    – supazu Apr 27 '21 at 05: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) }} – James Smith Apr 28 '21 at 08:21
  • Thanks for your help - looks like this one is a bit beyond me. – supazu Apr 30 '21 at 01: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.

Wallace
  • 611
  • 3
  • 8
  • The code is the part I'm having trouble with – supazu Apr 30 '21 at 01: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 – Wallace Apr 30 '21 at 07:55