Tickets 0.8.0 \ 0.8.1 beta

Вышла очередная версия компонента Tickets.


Главное изменение — редактирование комментариев во фронтенде! Если вы обновляете пакет, обратите внимание, что вам нужно изменить чанки:
В tpl.Tickets.comment.form добавить в форму
<input type="hidden" name="id" value="0" />
и заглушку для таймера
<span class="time"></span>

А в tpl.Tickets.comment.one.auth нужно дописать
<!--ticket_comment_edit_link <a href="#edit" onclick="return Comments.forms.edit([[+id]])">[[%ticket_comment_edit]]</a>-->
<!--ticket_comment_was_edited <span class="ticket-comment-edited">([[%ticket_comment_was_edited]])</span></a>-->
И выставить плейсхолдеры
[[+ticket_comment_edit_link]]
[[+ticket_comment_was_edited]]

Если что, актуальные версии чанков всегда тут.

Внимательный читатель может заметить некоторую связь между именами плейсхолдеров и закомментированными строками в чанке — и будет прав.
Обработка чанков сильно улучшилась, и научилась выдавать разное оформление комментария в быстром режиме, т.е. при &fastMode=`1`. Также немного ускорился и медленный режим, но разница по прежнему в разы.

Как работает редактирование.

При создании комментария, компонент смотрит в новую системную настройку tickets.comment_edit_time, в которой указано количество секунд для редактирования комментария. В течении этого времени, комментарий выводится своему автору со ссылкой для изменения. При рендере чанка, понятно, закомментированные строки подставляются в плейсхолдеры.

При клике по ссылке, на сервер идёт запрос и возвращается текст комментария, не обработанного Jevix. То есть, юзер меняет исходник, а показывается потом уже фильтрованный текст. Отсюда никаких проблем с символами переноса и ссылкам.

При попытке изменения проверяются 3 параметра: время для редактирования, автор и наличие ответов. Если у комментария уже есть ответы — его нельзя изменить. Проверка идёт при начале редактирования, и при сохранении.

Также выводится таймер оставшегося времени. Если вы не уложились — комментарий сохранить нельзя.

Измененному комментарию добавляется плейсхолдер [[+ticket_comment_was_edited]], куда вставляется соответствующая строчка из лексикона.

Остальные изменения

— Наконец-то, можно менять секцию тикета. То есть, можно перемещать заметку из одного блога в другой.

— Плагин Tickets реагирует на запрос старого адреса перемещенного тикета, и редиректит на его новый адрес. Фишка работает только для сайтов со включенным friendly urls.Иначе — оно и не надо, id не меняется.

— Добавлена вкладка со всеми комментариями, в админку. Этакий «прямой эфир».

— Сниппет dateAgo интегрирован прямо в компонент. На самом деле, это код из компонента выделен в сниппет, но сниппет вышел раньше.
Это даёт возможность указывать плейсхолдер [[+date_ago]] в чанках комментариев и последних событий.

— Доработал класс TicketsSection, у него тоже появились виртуальные поля comments,views и tickets, чтобы можно было выводить список разделов, как тут.

— Ну и наконец сделал нормальный вывод тегов MODX при редактировании тикета на фронтенде. Больше никаких html-сущностей вместо скобок.

Пакет в репозитории, история изменений тут
.
Ещё раз напоминаю, что чанки не обновляются при обновлении пакета, чтобы не затереть ваши изменения. Поэтому, для включения редактирования, обновите их вручную.

Эксперементальные сниппеты

В новой версии идут 2 сниппета, которые не устанавливаются по умолчанию: это getTickets и getSections. Они работают при помощи эксперементальной разработки pdoTools.

Если есть желание — вы можете создать эти сниппеты и указать их вместо getResources. ТВ параметры они не понимают, но работают гораздо быстрее.

Для дополнительного ускорения нужно как можно меньше использовать вложенные плейсхолдеры и условия. То есть, вместо [[~[[+id]]]] надо использовать [[+uri]]. Это потому, что в чанке сначала вручную заменяются все возможные плейсхолдеры, а остальные уже обрабатываются методами MODX.

Вот мой чанк для главной страницы, адаптированный под getTickets:
<div class="question">
	<small><a href="[[+section_uri]]">[[+section_name]]</a> /</small>
    <h3 class="title"><a href="[[+uri]]">[[+pagetitle]]</a></h3>
	<div class="content">
		[[+introtext:isnot=``:then=`[[+introtext]]<a href="[[+uri]]#cut" class="btn read-more">Читать дальше →</a>`:else=``]]
	</div>
	<div class="row">
		<div class="span2 gray">[[dateAgo?input=`[[+publishedon]]`]]</div>
        <div class="span3"><i class="icon-user"></i> <a href="/user/topics/[[+username]]/" class="black">[[+fullname]]</a></div>
        <div class="span1"><i class="icon-eye-open"></i> [[+views]]</div>
		<div class="span1"><a href="[[+uri]]#comments"><i class="icon black icon-comment"></i> [[+comments]]</a></div>
	</div>
</div>

Есть и fastMode, если вы сможете сделать чанк вообще без условий. Но и без него моя главная страница открывается за 0,3 сек.

P.S.
Сразу выпустил и 0.8.1, где исправил отправку емайла при каждом изменении комментария.
Заодно провёл тюнинг и TicketComments теперь можно вызывать кэшированным.

Если будете так делать — активируйте и новую настройку tickets.clear_cache_on_comment_save. тогда при создании \ обновлении \ удалении \ уничтожении комментария, кэш его ресурса будет полностью очищаться.

Не на всех сайтах это полезно, особенно если страница сложная — тогда её генерация просто убъёт весь профит от кэширования сниппета комментариев. Для этого и сделал настройку — решайте сами.

Следующая заметка
Tickets 0.9.0 beta
Предыдущая заметка
Сниппет dateAgo


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

  1. Виталик Дощенко 07 января 2013, 16:51 # 0
    раз
    1. Виталик Дощенко 07 января 2013, 16:59 # 0
      Отличная работа, спасибо! Особенная заслуга заключается в том, что Вася выделил кусок праздничных дней, чтобы выпустить обновление.

      P.S. Единственно, алгоритм редактирования я бы немного пересмотрел в сторону опыта basecamp-а. Мне не хватило времени, чтобы отредактировать комментарий. Может быть стоит давать 3 минуты на редактирование, но давать сохранить изменение по истечении 3 минут?
      1. Виталик Дощенко 07 января 2013, 17:14 # 0
        — Сообщение №4935 я тоже изменял, а пометка "(Комментарий был изменён)" не появилась почему-то.
        — Если вставлять html-теги, выдается ошибка — d.pr/i/9n2a
        1. Василий Наумкин 07 января 2013, 18:36 # 0
          — Появилась, видимо после обновления страницы.

          — На некоторые html сущности jevix так реагирует, не разбирался еще почему. Может, считает это попыткой взлома.
          1. Василий Наумкин 08 января 2013, 08:40 # 0
            Выяснил, что при наличии html сущностей, типа & nbsp; или & raquo; не работает регулярное выражение в Jevix, которое разбивает текст на массив, для обработки.
            Часов пять ковырял его, потом сервер и функции mbstring, даже обновлял php.

            А потом оказалось, что ошибка совершенно тупая — я не указал кодировку в одном месте. В общем, хорошо изучил, как работает Jevix и заборол ошибку.
          2. Василий Наумкин 07 января 2013, 18:39 # 0
            Время можно указать любое.

            3 минуты я взял с Хабра — там хватает. Считается, что это время достаточно для исправления пары опечаток.
            Будут жалобы — увеличу.

            А технически разделить время на редактирование и сохранения не представляется возможным.
        2. Евгений Webinmd 07 января 2013, 23:12 # 0
          Планируется ли в сниппетах getTickets и getSections работа с ТВ в следующих версиях?
          1. Василий Наумкин 08 января 2013, 05:07 # 0
            Пока нет.

            Сниппеты нацелены на максимальную производительность, путём выборки всех нужных данных за один SQL запрос. Получение пачки ТВ в эту идею не особо вписывается.

            В таком случае проще использовать getResources, он это лучше умеет.
            1. Евгений Webinmd 08 января 2013, 13:26 # 0
              Раз уж начал про TV, я не особо знаком со всеми тонкостями modx — для добавления других полей (например емайла) в форму создания тикета необходимо писать хук для formIt или это предусмотрено?
              1. Василий Наумкин 08 января 2013, 14:02 # 0
                Тикеты могут создавать только авторизованные юзеры.
                То есть, они свой email вводят при регистрации, или как у меня — указывают при первом заходе вот тут.

                FormIt нигде не используется. Ты можешь добавить любые поля и пихать их в тикет при сохранении плагином на событие OnBeforeDocFormSave. В общем, тот же хук, только покруче, на системном уровне.

                Можно и проверять что-то в этом же плагине, и не давать сохранить тикет.
          2. Михаил Т. 10 января 2013, 01:29 # 0
            А пре-модерации ни-ни да?
            1. Василий Наумкин 10 января 2013, 05:07 # 0
              bezumkin.ru/sections/components/508/
              Теперь вы можете сделать модерацию комментариев простым плагином:
              switch ($modx->event->name) {
              	case "OnBeforeCommentSave":
              		if ($mode == 'new') {
              			$object->set('deleted',1);
              		}
              	break;
              }
              1. Михаил Т. 10 января 2013, 12:50 # 0
                Спасибо, попробуем.
            2. Михаил Т. 11 января 2013, 01:34 # 0
              А кстати а какой уровень вложенности ответов к комментариям? Его как-то можно ограничить, как в quip, например.
              1. Василий Наумкин 11 января 2013, 06:20 # 0
                Бесконечный.

                Ограничить его можно в CSS — не показывая отступ после определенного уровня. А технически не вижу смысла ограничивать.
                1. Михаил Т. 11 января 2013, 12:47 # 0
                  Когда комментарий становиться 4 см. шириной выглядит это совсем не очень, поэтому бесконечность ответов и вызывает сомнения. А если использовать ограничение css, то визуальная логичность ветки и вовсе теряется.
                  1. Василий Наумкин 11 января 2013, 12:50 # 0
                    Авторы Хабрахабра и LiveStreet об этом не в курсе.

                    Как принудительное ограничение глубины ответов поможет беседе?
              2. Михаил Т. 11 января 2013, 13:03 # 0
                Я не знаю о чем в курсе создатели лайвстрит, я с ними не знаком.

                Беседу можно провести и в личной переписке, а комментарии не всегда нужны для батальных дискуссий. Порой, одного уровня ответов достаточно.
                1. Василий Наумкин 11 января 2013, 13:05 # 0
                  Тогда Tickets тебе не подойдет.

                  Используй Quip.
                  1. Василий Наумкин 11 января 2013, 13:16 # 0
                    Кстати, если нужен только 1 уровень комментариев, то можно просто убрать ссылку на «ответить» из чанка.
                    1. Михаил Т. 11 января 2013, 13:49 # 0
                      Я имею ввиду один уровень, как в Facebook или в VK. Или тут
                      В Quip можно. Я бы его с радостью использовал если-бы там не было лагов с сортировкой.
                      1. Василий Наумкин 11 января 2013, 14:04 # 0
                        Никогда не понимал комментариев Вконтакте и подобных. Как угадать, кто кому ответил? Где ветка какой беседы?

                        Но раз сильно хочется — вот тебе решение. С версии 0.7.0 есть возможность самостоятельно обрабатывать комментарии своим сниппетом.

                        Значит, нужно при выводе проверять поле parent, и если оно не равно 0 — убирать ссылку «ответить». Таким образом возможность ответа будет только у первого уровня, а у второго — нет.
                        1. Александр Наумов 12 января 2013, 01:30 # 0
                          Спасибо, мне тоже пригодится совет, все дело в том, что для адаптивного дизайна больше чем один уровень не делают.
                          1. Василий Наумкин 12 января 2013, 08:48 # 0
                            У меня адаптивный дизайн.

                            Так что, делают.
                            1. Александр Наумов 12 января 2013, 11:07 # 0
                              Вот здесь http://bezumkin.ru/sections/components/487/#comment-5075 если ширина меньше 760px появляется прокрутка, на смартфоне читать комментарии с этой страницы крайне не удобно.
                              1. Василий Наумкин 12 января 2013, 12:07 # 0
                                Ок
                  2. Александр Донский 16 января 2013, 02:12 # 0
                    Почему-то у меня ajax или что-то другое не работает-нажимаю «Написать», «Предпросмотр» — 0 реакции :(
                    1. Василий Наумкин 16 января 2013, 06:09 # 0
                      Смотри в консоли браузера ошибки javascript.
                      1. Александр Донский 16 января 2013, 11:10 # 0
                        Uncaught ReferenceError: $ is not defined > ticket.html
                        Uncaught ReferenceError: jQuery is not defined > comments.js:7
                        Uncaught ReferenceError: jQuery is not defined > jquery.markitup.js:597
                        Port error: Could not establish connection. Receiving end does not exist. > extensions/miscellaneous_bindings.js:146
                        4 Uncaught ReferenceError: $ is not defined > comments.js:47
                        
                        1. Василий Наумкин 16 января 2013, 11:32 # 0
                          Полагаю, jQuery не подключен?
                          1. Александр Донский 16 января 2013, 11:40 # 0
                            дааа, не был подключен :) вот затупил
                            1. Александр Донский 09 февраля 2013, 18:27 # 0
                              Я использовал последнюю версию jquery-1.9.0.min.js, и markItUp отказался работать:
                              Uncaught TypeError: Cannot read property 'safari' of undefined
                              	jquery.markitup.js:109
                              Uncaught TypeError: Cannot read property 'msie' of undefined
                              	jquery.markitup.js:376
                              
                              Как оказалось $.browser удалено из версии 1.9:
                              The problem source is that you have updated JQuery and $.browser is removed in ver 1.9
                              После обновления markItUp, редактор заработал.
                              1. Василий Наумкин 09 февраля 2013, 18:49 # 0
                                Спасибо, добавил в план работ.
                    2. Александр Донский 16 января 2013, 16:20 # 0
                      У меня не сохраняются комментарии, после обновления страницы они пропадают, и markitup не работает: Uncaught TypeError: Cannot read property 'msie' of undefined — jquery.markitup.js:376
                      1. Александр Донский 16 января 2013, 19:46 # 0
                        И в журнале ошибок:
                         [2013-01-16 19:22:10] (ERROR @ /assets/components/tickets/connector.php) Encountered empty IN condition with key resource
                        [2013-01-16 19:22:10] (ERROR @ /assets/components/tickets/connector.php) Error 42000 executing statement: 
                        Array
                        (
                            [0] => 42000
                            [1] => 1064
                            [2] => You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') ORDER BY `TicketComment`.`createdon` DESC LIMIT 20' at line 1
                        )
                        
                        [2013-01-16 19:25:29] (ERROR @ /connectors/resource/index.php) Error removing dependent object: Array
                        (
                            [parent] => 23
                            [uid] => 2
                            [timestamp] => 2013-01-16 19:22:37
                        )
                        
                        [2013-01-16 19:25:29] (ERROR @ /connectors/resource/index.php) Error removing dependent object: Array
                        (
                            [parent] => 24
                            [uid] => 2
                            [timestamp] => 2013-01-16 19:23:08
                        )
                        
                        
                        1. Василий Наумкин 16 января 2013, 20:19 # 0
                          Ты в курсе, что версия beta и еще не 1.0?
                          1. Александр Донский 16 января 2013, 23:08 # 0
                            я увлекся, извини.
                            Кстати, в комментариях дата верная, а в созданных тикетах указывается:
                            01 Jan 1970, 03:33
                            1. Василий Наумкин 17 января 2013, 07:24 # 0
                              Где именно?

                              Давай ссылку на созданный тикет с неверной датой.
                              1. Александр Донский 17 января 2013, 15:35 # 0
                                В разделе тикетов все тикеты с этой датой. Ссылку можно как-то в личку или как?
                                1. Andrei Kilin 17 января 2013, 15:58 # 0
                                  На твоем сайте?
                                  Смотришь неопубликованные тикеты может, залогинившись в админку, а в шаблоне дата формируется от поля publishedon, которое в этом случае будет пустым и дата будет 1970.
                                  1. Александр Донский 17 января 2013, 16:42 # 0
                                    ну да на сайте, тикеты опубликованы, я ничего не менял, все по-умолчанию: тикеты выводятся чанком tpl.Tickets.list.row в разделе тикетов, строчка где дата
                                    <div class="span2 gray">[[+createdon:date=`%d %b %Y, %H:%M`]]</div>
                                    1. Василий Наумкин 17 января 2013, 17:09 # 0
                                      А, ясно.

                                      Сделай так:
                                      <div class="span2 gray">[[+createdon:strtotime:date=`%d %b %Y, %H:%M`]]</div>
                                      1. Александр Донский 18 января 2013, 00:59 # 0
                                        дата стала правильной, спасибо
                        2. Andrei Kilin 17 января 2013, 14:01 # 0
                          Сталкивался может кто?
                          При редактировании тикета во фронтэнде выдает: «В форме содержатся ошибки. Пожалуйста, исправьте их.»
                          Как отловить, что за ошибка?
                          1. Василий Наумкин 17 января 2013, 14:05 # 0
                            Ticket требует всего три обязательных поля — родитель, заголовок и контент.

                            Перед сохранением все поля проходят обработку, возможно у тебя там некорректные символы — проверяй.
                            1. Andrei Kilin 17 января 2013, 14:25 # 0
                              Беда в том, что если новый тикет создаю, то все ок, он сохраняется. Тут же тыкаю на «изменить», меняю — не дает больше сохранить.

                              Причем, проверил на другом сайте, там работает. Сижу, репу чешу %)
                              1. Василий Наумкин 17 января 2013, 16:26 # 0
                                А никакой плагин не меняет тикет или ресурсы при обновлении?
                                1. Andrei Kilin 17 января 2013, 16:35 # 0
                                  Нет. Есть только плагин, который 404 обрабатывает.
                                  1. Василий Наумкин 17 января 2013, 17:10 # 0
                                    Сравни чанки создания и обновления, поди во втором опечатка где-нить в имени отправляемых полей.
                                    1. Andrei Kilin 18 января 2013, 10:19 # 0
                                      Чанки в порядке: и сам проверял, и с гитхаба копировал.
                                      1. Василий Наумкин 18 января 2013, 15:46 # 0
                                        Ну прям не знаю тогда, что и посоветовать.

                                        Пришли на мыло логин\пароль сайта, посмотрю как время будет.
                                        1. Василий Наумкин 20 января 2013, 09:41 # 0
                                          Нашел баг, возможно, он у тебя.

                                          Если не включена автогенерация алиасов для дружественных урлов — тикет не сохраняется. В новой версии исправлю.
                                          1. Andrei Kilin 20 января 2013, 15:02 # 0
                                            Да, автогенерация была выключена. Включил, все заработало. Спасибо!
                            2. Denys Butenko 17 января 2013, 23:22 # 0
                              В минишопе при оформлении заказа создается учетка для пользователя, то есть заказ в любом случае привязан к пользователю. А что если создать пользователя «Аноним» и от его имени постить комментарий если человек не авторизирован?
                              1. Василий Наумкин 17 января 2013, 23:30 # 0
                                И логинить всех юзеров в эту одну учётку?

                                Да на здоровье.
                                1. Denys Butenko 17 января 2013, 23:55 # 0
                                  Нет, зачем логинить? miniShop же не логинит пользователя при создании заказа?
                                  Сейчас если пользователь авторизован — показываем форму, если нет — надпись авторизуйтесь. А будет: показываем форму и при отправке комментария проверяем, если пользователь авторизован пишем от его имени, а если нет пишем от пользователя аноним. По сути все анонимные комментарии будут от одного пользователя, но тем не менее это решит проблему анонимных комментариев. В любом случае у каждого комментария есть IP и в случае чего, можно блокировать.
                                  1. Василий Наумкин 18 января 2013, 06:38 # 0
                                    Нет никакой проблемы. Комментировать на сайте должен только авторизованный пользователь.

                                    В коде везде используется
                                    $this->modx->user->id;
                                    $this->modx->user->isAuthenticated();
                                    $this->modx->hasPermission();
                                    и т.д.

                                    Не могу представить ситуации, когда, желающий прокомментировать что-то, не может авторизоваться через Вконтакте или Яндекс в 2 клика.

                                    Система разрабатывалась для техподдержки, сейчас превращается в лёгкий аналог LiveStreet. Ни там, ни там нет анонимных юзеров.
                                    1. Denys Butenko 18 января 2013, 07:37 # 0
                                      Да, я не говорю, что есть проблема. Меня устраивает компонент полностью.
                                      Просто, вспомнилось кто-то хотел комментировать без авторизации, вот и подкинул идею.
                              2. Виталий Воропаев 18 января 2013, 16:01 # 0
                                Я например хотел (при организации виртуальной справки), сделать следующее: для того чтобы не удручать менеджера бекенда, отвечая на вопросы посетителей авторизовываться еще и во фронте. Решил проблему, наделив учетку менеджера определенными привелегиями, для того чтобы считать его авторизованным в обоих контекстах, с нужными для комментирования ролями.

                                Ну, а для пользователей авторизация нужна, как не крути.

                                Единственное, чего хотелось бы возможность добавлять комментарии из бекенда, например: для этой же виртуальной справки, удобно и в одном месте.
                                Добавление новых комментариев отключено.