Новые темы (непрочитанные)

Как мы знаем, на форуме может быть много пользователей и каждый из них может создавать новые темы. В результате главная страница будет содержать бесчисленный набор разных тем, в котором трудно определить, какие темы были уже прочитаны, а какие нет. Чтобы облегчить пользователям жизнь можно выделять новые (непрочитанные) темы жирным шрифтом. Как это сделать вы узнаете в данном разделе.

Первым делом исправим файл threads/index.blade.php. Этот файл отвечает за список всех тем форума, которые выводятся на главной странице. Найдем строчку {{ $thread->title }} и вместо нее вставим следующий код:
@if (auth()->check())
    @if ($thread->hasUpdatesFor(auth()->user()))
        <strong>
            {{ $thread->title }}
        </strong>
    @else
        {{ $thread->title }}
    @endif
@else
    {{ $thread->title }}
@endif
Здесь мы проверяем, является ли пользователь зарегистрированным, далее проверяем, существует ли запись в кэше, о том, что данный пользователь уже просматривал эту тему (метод hasUpdatesFor()), если нет, то выделяем название темы жирным шрифтом.

Добавим новый метод hasUpdatesFor() в модель Thread.
public function hasUpdatesFor($user)
{
    $key = $user->visitedThreadCacheKey($this);
    return $this->updated_at > cache($key);
} 
Переменная $key содержит ключ записи из кэша. Сама запись содержит дату и время просмотра темы пользователем. Если тема еще не была просмотрена или была обновлена после просмотра пользователем функция hasUpdatesFor() вернет true.

Добавим метод visitedThreadCacheKey() в модель User.
public function visitedThreadCacheKey($thread)
{
    return sprintf("users.%s.visits.%s", $this->id, $thread->id);
}  
В эту же модель также нужно добавить метод read(), который будет вызываться из контроллера ThreadsController (метод show()) при открытии пользователем каждой темы.
public function read($thread)
{
    cache()->forever(
        $this->visitedThreadCacheKey($thread),
        Carbon::now()
    );
}
Данный метод добавит в кэш время просмотра темы этим пользователем.

Для работы Carbon не забудьте в начале файла добавить:
use Carbon\Carbon;
Далее откроем файл контроллера ThreadsController и в метод show() добавим следующий код:
if (auth()->check()) {
    auth()->user()->read($thread);
} 
Здесь мы проверяем, если пользователь зарегистрирован, то следует добавить запись в кэш с текущей датой просмотра темы.

Теперь все должно работать, новые темы должны помечаться жирным шрифтом. Но что если пользователь прочитал тему, закрыл, а потом в этой теме были добавлены или удалены сообщения. Вдруг пользователь захочет просмотреть эти изменения. Чтобы оповестить об этом пользователя, будем снова выделять жирным шрифтом название темы. Для того чтобы это происходило нужно всего лишь обновлять значение темы updated_at при каждом изменении модели Reply.

Как обновить значение темы updated_at? Для этого нам нужно открыть модель Reply. Указать, что модель Reply принадлежит модели Thread.
public function thread()
{
    return $this->belongsTo(Thread::class);
} 
После чего, в этом же файле (Reply.php), в теле класса добавить следующий код:
protected $touches = ['thread']; 
Теперь при каждом обновлении модели Reply, у владеющей модели Thread будет обновляться поле updated_at и название темы будет выделяться жирным шрифтом.