Где хранятся непрочитанные комментарии?

Мне нужно вывести в личном кабинете пользователя количество непрочитанных им комментариев в разных разделах.

Где хранится информация о непрочитанных комментариях? Что-то не могу найти в таблицах базы…

===================================================

UPD1: вылаживаю мой рабочий вариант (спасибо Сергею за подсказку):
Сниппет comments_unread(пробовал объединить запросы в один, не получилось, оставил по отдельности)
<?php
$user = $modx->user->id;
$page = $input;

// Выбираем время последнего посещения
$result = $modx->query("SELECT `timestamp` FROM `modx_tickets_views` WHERE uid = '{$user}' AND parent = '{$page}'");
$row = $result->fetch(PDO::FETCH_ASSOC);
$timestamp = $row['timestamp'];

// Выбираем время последнего комментария
$result_thread = $modx->query("SELECT `id`, `comment_time` FROM modx_tickets_threads WHERE resource = '{$page}'");
$row_thread = $result_thread->fetch(PDO::FETCH_ASSOC);
$thread = $row_thread['id'];
$comment_time = $row_thread['comment_time'];

if($timestamp < $comment_time) {
    $q = $modx->prepare("SELECT * FROM modx_tickets_comments WHERE thread = '{$thread}' AND createdon > '{$timestamp}' AND published = 1");
    $q->execute();
    $r = $q->fetchAll(PDO::FETCH_ASSOC);
    return count($r);
}
else {
    return "0";
}
Вызываем сниппет (Fenom):
{111|comments_unread} // 111 - это id страницы
либо обычный вызов:
[[!comments_unread?&input=`111`]]


UPD2: похоже можно было то же самое сделать и без написания своего сниппета, просто вызвав сниппет getTickets и указав ему параметр &resources=`111`.
Правда по скорости не проверял что быстрее, мне кажется проще пару строк написать, чем вызывать каждый раз целый комбайн ради одной цифры которая может и не быть.
Василий Столейков
02 августа 2016, 08:27
modx.pro
5
1 643
0
Поблагодарить автора Отправить деньги

Комментарии: 10

Андрей
02 августа 2016, 12:34
0
В сессии может?
    Василий Столейков
    02 августа 2016, 13:04
    0
    Да нет вроде, не нахожу нигде, ни в сессии на сайте, ни в таблице сессий modx_session — уже глаза себе выколол, но похоже нету там ничего.
    Видно прийдётся в исходниках Tickets копаться, как он их вытаскивает.
    Или он на лету их подсчитывает?
      Сергей Шлоков
      02 августа 2016, 13:11
      1
      +4
      Есть такая таблица modx_ticket_views. В ней хранится дата последнего просмотра ресурса текущим пользователем. Все комментарии ресурса, у которых дата создания позже даты из этой таблицы, считаются непрочитанными. Они высчитываются на лету.
        Василий Столейков
        02 августа 2016, 13:53
        0
        Очень интересно, огромное спасибо!
        Буду думать как использовать эту логику в своих сниппетах.
    Василий Столейков
    02 августа 2016, 16:51
    0
    Решение вопроса выложил в конец статьи, может будет кому-то ещё полезно.
      Сергей Шлоков
      02 августа 2016, 18:24
      0
      вылаживаю мой рабочий вариант
      Думаю, ты имел ввиду «выкладываю» ;)

      Предложу небольшую оптимизацию.
      Нужно все-таки проверять $timestamp. А если пользователь ещё не видел ни одного комментария?
      Строчки
      $q = $modx->prepare("SELECT * FROM modx_tickets_comments WHERE thread = '{$thread}' AND createdon > '{$timestamp}' AND published = 1");
      $q->execute();
      $r = $q->fetchAll(PDO::FETCH_ASSOC);
      return count($r);
      можно заменить на
      return $modx->getCount('TicketComment', array('thread'=>$thread, 'createdon:>'=>$timestamp, 'published'=>1));
      Ну и в принципе, я бы второй и третий запрос объединил джойном.
        Василий Столейков
        02 августа 2016, 18:42
        0
        Ага, выЛАЖиваю от слова ЛАЖа… ))))

        1. За таймштамп спасибо!

        2. Замена строчек чем оправдана, большим удобством или скоростью?

        3. А можно насчет джойна подробнее? Я пытался, на после неудачных попыток откатился на этот вариант…
          Сергей Шлоков
          02 августа 2016, 19:39
          +1
          2. Уже есть метод. Зачем его дублировать.
          3. После первого запроса заменить код
          if (empty($timestamp)) {
          	$query = $modx->newQuery('TicketThread', array('resource' => $page));
          	$query->select('comments');
          	return $modx->getValue($query->prepare());
          } else {
          	$q = $modx->newQuery('TicketComment');
          	$q->innerJoin('TicketThread','Thread', "TicketComment.thread = Thread.id AND Thread.resource = {$page}");
          	$q->select('TicketComment.id');
          	$q->where('TicketComment.createdon > Thread.comment_time');
          	if ($q->prepare() && $q->stmt->execute()) {
          		return $q->stmt->rowCount();
          	}
          }
          Должно работать. В теории :)
      Кирилл Спеваков
      13 августа 2017, 15:16
      0
      Подскажите, а если не с одной странице нужно выводить (как в примере 111), а с нескольких?
      есть раздел в личном кабинете — обращения, пользователь создает тикет, а администратор отвечает на него через комментарии, как можно вывести общее кол-во непрочитанных сообщений с разных тикетов?
        Василий Столейков
        13 августа 2017, 21:56
        +1
        Либо модифицировать сниппет из статьи указав не конкретный id, а список id через запятую (типа parent IN (1,2,3)), либо при вызове getTickets вбивать данные в плейсхолдеры и потом плюсовать их.
        Мне кажется для твоего случая лучше именно отдельный сниппет.
        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
        10