/**
  * Sync a notification so that it is visible to the specified users, and not
  * visible to anyone else. If it is being made visible for the first time,
  * attempt to send the user an email.
  *
  * @param \Flarum\Core\Notifications\NotificationInterface $notification
  * @param \Flarum\Core\Models\User[] $users
  * @return void
  */
 public function sync(NotificationInterface $notification, array $users)
 {
     $attributes = ['type' => $notification::getType(), 'sender_id' => $notification->getSender()->id, 'subject_id' => $notification->getSubject()->id, 'data' => ($data = $notification->getData()) ? json_encode($data) : null];
     $toDelete = Notification::where($attributes)->get();
     $toUndelete = [];
     $newRecipients = [];
     foreach ($users as $user) {
         $existing = $toDelete->where('user_id', $user->id)->first();
         if (($k = $toDelete->search($existing)) !== false) {
             $toUndelete[] = $existing->id;
             $toDelete->pull($k);
         } elseif (!$this->onePerUser || !in_array($user->id, $this->sentTo)) {
             $newRecipients[] = $user;
             $this->sentTo[] = $user->id;
         }
     }
     if (count($toDelete)) {
         Notification::whereIn('id', $toDelete->lists('id'))->update(['is_deleted' => true]);
     }
     if (count($toUndelete)) {
         Notification::whereIn('id', $toUndelete)->update(['is_deleted' => false]);
     }
     if (count($newRecipients)) {
         $now = Carbon::now('utc')->toDateTimeString();
         Notification::insert(array_map(function ($user) use($attributes, $notification, $now) {
             return $attributes + ['user_id' => $user->id, 'time' => $now];
         }, $newRecipients));
         foreach ($newRecipients as $user) {
             if ($user->shouldEmail($notification::getType())) {
                 $this->mailer->send($notification, $user);
             }
         }
     }
 }