Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-10-18T01:42:15.170Z
Answers.LastActivityDate: 2022-10-19T04:49:13.483Z
Answers.LastEditDate: 2022-10-19T04:49:13.483Z
Answers.UserDisplayName: supazu
Body: <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>
  
Tags: <modules>
Title: Count consecutive years in Tag array in a module
ThreadText: # Count consecutive years in Tag array in a module
  
  (Asked by: username_0 on 2022-10-17)
  
  I'm coming back to [this question](https://craftcms.stackexchange.com/questions/37621/count-number-of-consecutive-years-in-category-array) 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);
  });
  
  ```
  
  
  ---
  
  