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

Дополнение: Tickets

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

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

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

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, 11:27    Василий Столейков   G+  
3    340 0

Комментарии (8)

  1. Андрей 02 августа 2016, 12:34 # 0
    В сессии может?
    1. Василий Столейков 02 августа 2016, 13:04 # 0
      Да нет вроде, не нахожу нигде, ни в сессии на сайте, ни в таблице сессий modx_session — уже глаза себе выколол, но похоже нету там ничего.
      Видно прийдётся в исходниках Tickets копаться, как он их вытаскивает.
      Или он на лету их подсчитывает?
      1. Сергей Шлоков 02 августа 2016, 13:11 # +4
        Есть такая таблица modx_ticket_views. В ней хранится дата последнего просмотра ресурса текущим пользователем. Все комментарии ресурса, у которых дата создания позже даты из этой таблицы, считаются непрочитанными. Они высчитываются на лету.
        1. Василий Столейков 02 августа 2016, 13:53 # 0
          Очень интересно, огромное спасибо!
          Буду думать как использовать эту логику в своих сниппетах.
    2. Василий Столейков 02 августа 2016, 16:51 # 0
      Решение вопроса выложил в конец статьи, может будет кому-то ещё полезно.
      1. Сергей Шлоков 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));
        Ну и в принципе, я бы второй и третий запрос объединил джойном.
        1. Василий Столейков 02 августа 2016, 18:42 # 0
          Ага, выЛАЖиваю от слова ЛАЖа… ))))

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

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

          3. А можно насчет джойна подробнее? Я пытался, на после неудачных попыток откатился на этот вариант…
          1. Сергей Шлоков 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();
            	}
            }
            
            Должно работать. В теории :)
      Вы должны авторизоваться, чтобы оставлять комментарии.