[Tickets] Версия 1.4.0-beta4 - Загрузка файлов

Готова новая бета-версия Tickets, в которой можно загружать файлы к тикету. Это очередной пример дружного финансирования разработок, полезных для сообщества, этим самым сообществом.

Кто не видел - вот исходная тема. Начиналось всё довольно безобидно: попросили соединить Uploadify и Tickets. В процессе соединения оказалось, что выходит ерунда, поэтому пришлось делать всё по-полной.

Итого, я провозился аж 4 дня, вместо 1 запланированного. Но результат того стоит:

Подробности под катом.

Логика работы

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

Правила загрузки и генерации превью, как обычно, прописаны в источнике медиа. Стандартный для Tickets устанавливается вместе с обновлением. Обратите внимание: в отличии от MS2 всегда генерируется только одна превьюшка, поэтому формат JSON массива немного другой.

Сразу после загрузки файлам присваивается пользователь-владелец и нулевой документ-родитель. Пока вы не сохраните тикет вместе с загруженным файлом - он считается новым и показывается вам в окошке создания и редактирования тикета.

Если картинка вам не нужна - её можно удалить, вернее, поставить флаг deleted. Физически же файл и запись в БД будут удалены при обновлении формы (только для новых файлов) или при сохранении тикета (для всех).

То есть, файл еще не привязанный к тикету удаляется проще, чем привязанный. Сама привязка происходит при сохранении тикета. Пока вы его не сохраните - файл болтается неприкаянный и показывается вам в форме тикета.

Удаляемый тикеты обводятся красной рамкой, новые - синей. Все стили, как обычно, в default.css.

Новые параметры сниппета TicketForm: - allowFiles - Разрешить загрузку файлов? Если да - то подключится загрузчик и нужные скрипты.

  • source - Источник медиа-файлов, в который будут сохранены изображения. По умолчанию берется системны настройка tickets.source_default, в которую прописывается источник Tickets Files.
  • tplFiles - Чанк-обертка всего блока работы с файлами. Загружчик, список файлов и прогрессбар.
  • tplFile - Чанк оформление файла, который не является изображением.
  • tplImage - Чанк офомрления картинок.

Советую зайти в источник файлов и вдумчиво почитать описания фиолетовых параметров - они влияют на работу загрузчика и сохранение файлов.

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

Загрузчик

Непосредственно загрузкой файлов занимается мега-скрипт Plupload, который работает везде, умеет drug & drop, ресайз на клиенте и еще много чего.

В частности, он не позволит вам загрузить слишком большой файл, проверяя его размер при добавлении. Огромные картинки будут отресайзены до значений, указанных в источнике файлов также - прямо у вас на компе, еще до загрузки на сервер.

Также на клиенте будет проверено расширение файла, а в окне выборе будут активны только разрешенные типы.

Контроль целостности

Ссылку на загруженный файл можно сразу вставить в тикет - пока он не сохранен путь у картинок будет такой:

/assets/images/tickets/0/имяфайла.png
/assets/images/tickets/0/имяфайла_thumb.jpg

Обратите внимание, что путь указывает на нулевой ресурс. При сохранении этот путь заменится на реальный id документа.

Если вы удаляете файл, но оставляете ссылку на него в документе - она тоже будет удалена при сохранении тикета. Таким образом, битых ссылок быть не должно. Проверяются content и introtext.

Физический перенос файла в новую директорию прописан в методе TicketFile::save() и срабатывает при смене родителя.

Вывод загруженных файлов

Выводом загруженных файлов посетителям занимается сниппет TicketMeta. У него появились новые параметры, и по умолчанию он показывает только те файлы, ссылки на которые отсутствуют в контенте тикета. - getFiles - Выводить список загруженных файлов?

  • tplFile - Чанк оформления сслыки на файл.
  • unusedFiles - Выводить только файлы, неиспользованные в контенте документа.

Обертка для вывода файлов прописана в чанке tpl.Tickets.meta, в быстром плейсхолдере has_files.

Понятное дело, что файлы можно выводить и при помощи pdoResources:


[[!pdoResources?
    &class=`TicketFile`
    &where=`{"parent":16}`
    &sortby=`createdon`
    &sortdir=`ASC`
]]

Сортировку нужно указать обязательно, иначе сниппет попытается сортировать по колонке publishedon, которая у TicketFile отсутствует.

Заключение

Вот и появился у нас компонент, который умеет создавать страницы с фронтенда, комментировать, голосовать и даже загружать файлы.

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

Напоминаю, что это по-прежнему бета-версия, которую нужно тестировать. Учитывая, что используется Plupload, загрузка должны работать везде, даже на HTML4, а вот отсутствие глюков в php я вам не обещаю. Свой сайт я пока не обновляю, скорее всего, новый Tickets будет использоваться уже сразу на http://modx.pro.

При обновлении советую обратить внимание на чанки: - tpl.Tickets.form.create

  • tpl.Tickets.form.update
  • tpl.Tickets.meta

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

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

← Предыдущая заметка
[Tickets] Версия 1.4.0-beta - Настройки секции
Следующая заметка →
[Sendex] Версия 1.0.0-pl — Отправка нескольких писем вручную
Комментарии (60)
Чикин Артур
25.03.2014 14:32

Спасибо.

inetloverАлександр Наумов
25.03.2014 17:19

Спасибо!!!

vsemee2Андрей
25.03.2014 17:20

Здравствуйте Василий! Ссылка

<span class="col-md-2"><a href="[[~[[+section.id]]]]"><i class="glyphicon glyphicon-folder-open"></i> [[+section.pagetitle]]</a></span>

в чанке tpl.Tickets.meta почему-то отправляет меня на главную страницу сайта

bezumkinВасилий Наумкин
25.03.2014 17:42

Поправил, обновись.

vsemee2Андрей
25.03.2014 17:46

Ок, спасибо!

CleanClean
25.03.2014 18:34

Василий, возможности потестировать твою мегафичу сейчас нет, но по тексту смотри


Ссылку на загруженный файл можно сразу вставить в тикет — пока он не сохранен путь у картинок будет такой:
/assets/images/tickets/0/имяфайла.png
/assets/images/tickets/0/имяфайла_thumb.jpg

Мне кажется произойдет факап, если в один момент два пользователя из под разных сессий загрузят файл с одним и тем же именем?Я так понимаю победит тот, кто загрузит файл последним..Возможно есть смысл расширить путь например до ID юзера:

/assets/images/tickets/0/[[+modx.user.id]]/имяфайла.png
Rоман Роман
25.03.2014 23:45

у меня есть одно нуууочень кастомное решение на Revo, когда прикручивал к нему BlueImp Fileupload, несохраненные фотографии складывал в /assets/images/номер_объявления/temp/, а при сохранении phpthumb рендерил их в /assets/images/номер_объявления/ с префиксами "1_" "2_" и "3_". А имена файлов потом кучей в JSON и так далее

bezumkinВасилий Наумкин
26.03.2014 04:12

Да ты прав, только это не помешает юзеру перезаписать свой же файл. То есть, создал тикет, загрузил туда "image.jpg", а через пару дней загружаешь другой "image.jpg" - содержимое у них разное, а имена одинаковые и один затрёт другой, что может быть неприятным сюрпризом - ты же не помнишь, что загружал в прошлый раз?

Так что добавлю проверку не только по содержимому, но и по имени. Если такое имя уже есть в нулевой директории или в директории тикета - будет ошибка, переименовывай перед загрузкой. Ну и по умолчанию лучше включить не-friendly имена картинок в настройках media source.

Алексей Карташов
26.03.2014 07:54

А не проще вместо имени юзера использовать session_id()? Уж это значение точно у каждого посетителя уникально. К тому же можно точный "сборщик мусора" сделать - по крону в нулевой папке чистить изображения с несуществующими в базе id сессий.

Чикин Артур
26.03.2014 07:57

Так то в базе тоже сессии переодически чистятся.

bezumkinВасилий Наумкин
26.03.2014 08:19

Чем проще? Авторизовался из другого браузера - другой session_id().

Вопрос уже решен проверкой имени файла и его содержимого при загрузке.

Чикин Артур
26.03.2014 10:34

Переименовывать картинку в ее хеш это тоже не подходит?

bezumkinВасилий Наумкин
26.03.2014 10:38

Зачем помогать человеку загрузить 2 файла с одинаковым именем или содержимым?

Ну вот реально, зачем? Чтобы на странице было 2 файла с одинаковым именем, или чтобы было 2 одинаковых картинки?

Чикин Артур
26.03.2014 13:46

разве если просто посчитать md5 файла то у 2 одинаковых файлов он будет разный?

CleanClean
26.03.2014 20:37

Хэш от одного и того-же входного параметра,всегда одинаков.

Максим Франц
26.03.2014 08:51

будет ошибка, переименовывай перед загрузкой

Не совсем юзер френдли получится. Индексы не вариант? image.jpg image(1).jpg image(2).jpg

bezumkinВасилий Наумкин
26.03.2014 08:54

Присылай свою реализацию на github - посмотрю.

Максим Франц
26.03.2014 09:01

Котерова дочитаю - возможно...

k07nAndrei Kilin
31.03.2014 18:49

Салют!

А не упростит ли задачу, если создание тикета разбить на 2 этапа? 1. Пользователь вводит только название тикета, выбирает секцию и тыкает на "продолжить". 2. Тут создается неопубликованный тикет и сразу перекидывает на его редактирование, где уже все плюшки есть: поле редактора, картинки, публикация и прочее.

м?

Николай
25.03.2014 18:56

И после вот такого, находятся умники кричащие какое это плохое сообщество с зазнавшимся автором. Рад был бы лично, Василий пожать тебе руку за подобные труды! Жаль географическое положение не позволяет.

asxАлександр Котлов
25.03.2014 21:03

Спасибо!

Константин Кононов
26.03.2014 05:13

Спасибо огромное!

Илья
26.03.2014 06:55

Огромное спасибо! А реально http://demo.modx.pro/tickets обновить, чтобы в живую поюзать, перед глобальным обновлением?

bezumkinВасилий Наумкин
26.03.2014 10:35
ВолодянВолодя
26.03.2014 10:38

Кулл!!! Молодчик ))) p.s. Василий случайно сюда зашел - http://demo.modx.pro/minishop2 Вроде ссылок на сравнение нет...

bezumkinВасилий Наумкин
26.03.2014 10:43

Спасибо, поправил.

Обновил MS2 с перезаписью чанков =)

starche78Станислав
01.04.2014 16:21

Василий, вчера все прекрасно работало, а сегодня пишет - Доступ запрещен. На демо такое же поведение. Начинает работает если в tickets.class.php в config дописать 'allowFiles','source','tplImage','tplFile'.

bezumkinВасилий Наумкин
01.04.2014 16:27

Поправил, обновись.

starche78Станислав
01.04.2014 17:28

тоже и для "Удалить"

bezumkinВасилий Наумкин
02.04.2014 01:36

Еще раз поправил, можно обновляться.

vanchelloИван Брежнев
26.03.2014 12:41

Firefox 28.0

LEONesoПавел Левин
26.03.2014 14:25

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

CleanClean
26.03.2014 20:39

Хочется верить что после полировки этой доработки, следующей будет http://bezumkin.ru/sections/work/2586/ , при таких раскладах MODx получит практически максимальный функционал для фронт-енд использования.

Наумов Алексей
27.03.2014 12:17

Раз такая пьянка, может надо сделать и прикрепление файлов (изображений) к комментариям? ))) Например так: http://fishspace.ru/places/to/kireevskij/gamovo/

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

vanchelloИван Брежнев
27.03.2014 12:28

А я считаю что это нормально вставлять изображения в текст комментария, кто будет открывать эти вложения?

Чикин Артур
28.03.2014 04:27

Зависит от цели которую ты преследуешь.

vanchelloИван Брежнев
28.03.2014 04:32

скорее всего

Наумов Алексей
28.03.2014 05:53

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

vanchelloИван Брежнев
28.03.2014 05:56

Тогда нужно делать для вашей целевой аудитории и так как им будет проще и доступнее

bezumkinВасилий Наумкин
27.03.2014 12:30

Нагрузка на отрисовку ветки комментариев может прилично так вырасти.

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

Чикин Артур
28.03.2014 04:12

Ajax подгрузка картинок при скроле в низ? Таких микро плагинов для jQuery помойка вроде как.

bezumkinВасилий Наумкин
28.03.2014 04:14

Ну тогда жду от тебя реализации на github.

Все всё знают и умеют, кроме меня - так давайте делать уже.

Rоман Роман
30.03.2014 19:00

В ЖЖ по-другому же сделано: открыты 2 первых комментария в ветке, а что дальше идет в треде - подгружается по запросу, и открывает только текущий тред

bezumkinВасилий Наумкин
30.03.2014 19:04

Лично мне это совершенно не нравится.

Давид Мовсесян
27.03.2014 12:56

Может не в тему, в настройках секции тикетов не запоминается настройка секции "Выполнять теги MODX"

Дмитрий Куликов
28.03.2014 07:37

Вопрос: как вывести только те тикеты, к которым нет комментариев?. Понимаю нужно написать,условие вроде &where=\[{"comments":\[0\]}\] Но не совсем понимаю как правильно его написать. Помогите пожалуйста!

bezumkinВасилий Наумкин
28.03.2014 08:00

Как работает SQL представляешь? Понятно ли, что тикеты - это одна таблица, а комментарии - другая? Нужно как минимум сделать join этих таблиц, чтобы задавать условия для выборки.

Дмитрий Куликов
28.03.2014 10:36

Недавно начал разбираться с SQL. Т,е. мне прямо в условии where нужно построить sql запрос который выберет все тикеты, у которых есть комментарии?

Rоман Роман
30.03.2014 19:02

Вот как примерно-приблизительно разберешься с SQL, примерно-приблизительно разберись с PDO и XPDO запросами в Revo. Вот честно, по-другому ничего не поймешь

Дмитрий Куликов
31.03.2014 05:57

Спасибо, буду осваиваться! Пока решил вот так

Наумов Алексей
05.04.2014 03:38

Василий, добрый день!

Вчера обновился до свежей версии тикетс, что-бы воспользоваться всеми новыми плюшками. Но сразу же выплыло неудобство: создается только 1 превью для загруженного файла. Причем мне нужно превью большого размера, 400 точек в ширину, а высоту любое, но с ограничением до 1000 допустим. Ок, пропишу в источниках файлов, но тогда сломается предпросмотр превьюшек при создании поста. В чем сложность сделать возможность создания нескольких превью? Пусть они бы были записаны в виде

[
{"thumb": "w=120&h=90&..."},
{"anotherthumb": "w=400&h=1000&..."},
]

и в разных случаях мы бы просто использовали разный ключ. Или оставить текущую настройку thumbnail и добавить к ней дополнительно еще настройку thumbnails с массивом, как в gallery. В этом случае, изображения вставлять не полным кодом в текст, а так:

<img src="1" />
  • где 1 - порядковый номер изображения у данного тикета. А про отображении уже заменять на то, что хочется. На превью, превью со ссылкой, ну в общем как пожелает пользователь.

Если это возможно сделать, готов проспонсировать.

bezumkinВасилий Наумкин
05.04.2014 04:10

Ты даже не представляешь, насколько я устал от всех этих "в чем сложность сделать возможность...". Бери - да делай, исходники открыты.

Если нет желания - используй phpthumbof или phpthumbon.

Наумов Алексей
05.04.2014 04:38

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

Борис И
20.04.2014 07:45

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

{"w":720,"h":400,"q":90,"zc":"1","bg":"000000","fltr":"wmt|site.ru|20|BR|DDEDF7|7fonts.ru_GAU_root_N.TTF|90|20|5||0|"}

и все в порядке. Для того, чтобы сделать водяные знаки на увеличенном изображении пытаюсь использовать phpthumbon (саму картину оригинал не трогаю). Для этого в чанке tpl.Tickets.form.image вместо [[+url]] (ссылки на оригинал) прописываю

[[phpthumbon? &phpthumbon.cache_dir=`images` &options=`fltr[]=wmt|site.ru|40|BR|DDEDF7|/core/model/phpthumb/fonts/7fonts.ru_GAU_root_N.TTF|90|20|5|0|0|` &input=`[[+url]]` ]]

до очистки кэша все в порядке, а после и превью исчезает. Посмотрел, у картинок (превью и увеличенной) в созданном тикете остаются пути на /assets/images/tickets/0/... не происходит замены на id ресурса. Причем, увеличенная картинка открывается, даже после очистки кэша и с путем /assets/images/tickets/0/... Прошу прошения если объяснил непонятно, осваиваю modx. Подскажите, куда копать.

bezumkinВасилий Наумкин
20.04.2014 13:50

Посмотрел, у картинок (превью и увеличенной) в созданном тикете остаются пути на /assets/images/tickets/0/… не происходит замены на id ресурса. Причем, увеличенная картинка открывается, даже после очистки кэша и с путем /assets/images/tickets/0/

А версия точно последняя? Я вроде это уже починил.

Борис И
20.04.2014 15:18

Василий, спасибо. Пришлось обновить вручную, автоматом почему то показывало, что последняя версия. Превью стали открываться нормально, id присваивается. Потестил немного phpthumbon, для создания увеличенной картинки, чувствую, в дальнейшем, с ним могут возникнуть проблемы, естественно он не меняет /assets/images/tickets/0/ на id (а значит может перезаписать картинки). Чтобы не затирались картинки дополнил его параметром

&phpthumbon.cache_dir=`images/[[+id]]`

, получилась интересная штука. Пример: к превью картинки путь /assets/images/tickets/103/ и id ресурса соответственно 103. А у phpthumbon путь получился /assets/images/110/tickets/0/ (откуда взялось 110, вместо 103, загадка). При создании следующего ресурса будет 104 и 111. В общем криво получается. Как бы боком не вышла защита увеличенных картинок ватермаркой.

Николай Загумённов
03.05.2014 13:57

Никак не могу найти где менять миниатюры изображений. Как вот тут показано: В настройках системы нет. Не подскажете где эти настройки?

kondakovДмитрий Кондаков
04.05.2014 05:52

Инструменты > Источники файлов

Николай Загумённов
04.05.2014 05:59

спасибо!

agronomТимофей
30.11.2014 21:12

Подскажите, после нажатия кнопки

<input type="button" class="btn btn-primary publish" name="publish" value="Опубликовать" title="" />

- куда передаются параметры? Внутрь сниппета TicketForm или куда-нибудь в другое место?

bezumkin
Василий Наумкин
04.07.2022 23:34
Что-то странное у тебя произошло: миграция есть, и вроде как выполнена, но таблицы при этом отсутств...
inetlover
Александр Наумов
03.07.2022 20:36
Василий, спасибо! Все понятно!
bezumkin
Василий Наумкин
02.07.2022 20:28
Спасибо, поправил!
bezumkin
Василий Наумкин
30.06.2022 03:58
Есть ли возможность формировать &quot;friendly URL aliases&quot;, используя аналог translit MODx? ...
bezumkin
Василий Наумкин
27.06.2022 03:32
Спасибо за исправления, очень выручаешь =) Но учитывая количество не описаных в заметке дополнительн...
bezumkin
Василий Наумкин
27.06.2022 03:10
что будет использоваться для вывода многоуровневого меню Посмотри как работают комментарии на этом ...
bezumkin
Василий Наумкин
25.06.2022 11:56
Поправил, спасибо!
bezumkin
Василий Наумкин
21.06.2022 01:58
onLoad(data) { this.total = data.total }, и onLoad({total}) { this.total = total }, В нашем случ...
bezumkin
Василий Наумкин
20.06.2022 14:01
Прекрасно тебя понимаю, я когда сам в этом разбирался - голова дымилась. Но зато теперь прямо-таки п...
bezumkin
Василий Наумкин
20.06.2022 09:30
Не надо, оно по умолчанию так - я просто чуть более подробно написал.