<p>After thinking about it some more, it seems to make sense to run it on <code>EVENT_BEFORE_SAVE</code> on user elements. Not 100% sure the rest of the code is great but it's working ok. Open to suggestions on how to improve!</p>
<pre><code>Event::on(User::class, Element::EVENT_BEFORE_SAVE, function (ModelEvent $event) {
    $user = $event-&gt;sender;
    $currentYear = date('Y');
    $years = Tag::find()-&gt;groupId(1)-&gt;relatedTo($user)-&gt;all();
    arsort($years);
    $loyalty = 0;
    $previousYear = null;
    foreach ($years as $year) {
        if ($year-&gt;title == $currentYear) {
            $loyalty++;
            $previousYear = bcsub($year-&gt;title, 1);
        }
    }
    if (!empty($previousYear)) {
        if ($year-&gt;title == $previousYear) {
            $loyalty++;
            $previousYear = bcsub($year-&gt;title, 1);
        }
    }
    $user-&gt;setFieldValue('loyalty', $loyalty);
});
</code></pre>

CC BY-SA 4.0
2022-10-18T01:42:15.170Z
2022-10-19T04:49:13.483Z
2022-10-19T04:49:13.483Z
supazu
<p>I'm coming back to <a href="https://craftcms.stackexchange.com/questions/37621/count-number-of-consecutive-years-in-category-array">this question</a> after some time because I feel like I have a bit more knowledge to be able to tackle it. Starting from Andy's pseudo-code, this is what I've got and it seems to be working ok, but I wonder if there's a better way to do it.</p>
<p>I also wonder if I need to code a bit more defensively. I guess this runs on every request, so I'm not sure if it's something that could be optimized. The tags are added to the user after purchasing a membership through our Commerce store (in another module.)</p>
<p>Andy mentioned setting it up as a Twig filter but I haven't got to that point yet.</p>
<pre><code>$user = Craft::$app-&gt;getUser()-&gt;getIdentity();

if (!$user) {
    return;
}

$loyalty = 0;
$currentYear = date('Y');
$previousYear = null;
$years = Tag::find()-&gt;groupId(1)-&gt;relatedTo($user)-&gt;all();
arsort($years);

foreach ($years as $year) {
    if ($year-&gt;title == $currentYear) {
        $loyalty++;
        $previousYear = bcsub($year-&gt;title, 1);
    }
    if (!empty($previousYear)) {
        if ($year-&gt;title == $previousYearMinusOne) {
            $loyalty++;
            $previousYear = bcsub($year-&gt;title, 1);
        }
    }
}
$user-&gt;setFieldValue('loyalty', $loyalty);
Craft::$app-&gt;getElements()-&gt;saveElement($user);
</code></pre>
<p>I'd appreciate any tips!</p>

<modules>
Count consecutive years in Tag array in a module
# Count consecutive years in Tag array in a module

(Asked by: username_0 on 2022-10-17)

I'm coming back to this question after some time because I feel like I have a bit more knowledge to be able to tackle it. Starting from Andy's pseudo-code, this is what I've got and it seems to be working ok, but I wonder if there's a better way to do it.
I also wonder if I need to code a bit more defensively. I guess this runs on every request, so I'm not sure if it's something that could be optimized. The tags are added to the user after purchasing a membership through our Commerce store (in another module.)
Andy mentioned setting it up as a Twig filter but I haven't got to that point yet.
$user = Craft::$app->getUser()->getIdentity();

if (!$user) {
    return;
}

$loyalty = 0;
$currentYear = date('Y');
$previousYear = null;
$years = Tag::find()->groupId(1)->relatedTo($user)->all();
arsort($years);

foreach ($years as $year) {
    if ($year->title == $currentYear) {
        $loyalty++;
        $previousYear = bcsub($year->title, 1);
    }
    if (!empty($previousYear)) {
        if ($year->title == $previousYearMinusOne) {
            $loyalty++;
            $previousYear = bcsub($year->title, 1);
        }
    }
}
$user->setFieldValue('loyalty', $loyalty);
Craft::$app->getElements()->saveElement($user);

I'd appreciate any tips!

**Tags:** modules

---

## 1 answers

### Answer by username_0 on 2022-10-18. Score: 1

After thinking about it some more, it seems to make sense to run it on EVENT_BEFORE_SAVE on user elements. Not 100% sure the rest of the code is great but it's working ok. Open to suggestions on how to improve!
Event::on(User::class, Element::EVENT_BEFORE_SAVE, function (ModelEvent $event) {
    $user = $event->sender;
    $currentYear = date('Y');
    $years = Tag::find()->groupId(1)->relatedTo($user)->all();
    arsort($years);
    $loyalty = 0;
    $previousYear = null;
    foreach ($years as $year) {
        if ($year->title == $currentYear) {
            $loyalty++;
            $previousYear = bcsub($year->title, 1);
        }
    }
    if (!empty($previousYear)) {
        if ($year->title == $previousYear) {
            $loyalty++;
            $previousYear = bcsub($year->title, 1);
        }
    }
    $user->setFieldValue('loyalty', $loyalty);
});


---

