Какая же нам нужна система для скачивания файлов с нашего сайта:
1. Загрузка файлов на сайт нас не интересует особо - позволять делать это посетителям мы не собираемся.
2. Для скачиваемых файлов должна быть возможность русского названия, какой-то аннотации, указания размеров файла.
3. Должна быть скрыта прямая ссылка на файл - иначе мы бы просто давали линк в любом месте.
4. Конечно нужен счетчик закачек.
5. Требуется ограничение доступа к скачиванию всяких праздношатающихся.
Что же мы имеем на эту тему в репозитории MODx? А не особенно чего имеем. Есть ранее знакомые нам FileDownload сниппет с плагином и более свежий сниппет FileDownloadPE. Вот с него и начнем.
Сниппет FileDownloadPE
Это не простой FileDownload, это PE - то есть Pirate Edition! Круто! Наверное. "Будем посмотреть".
В общем, всё работает, файл скачивается, счетчик добавляется. Только такая маленькая деталь - скачанный архив не открывается, испорчен. Это, видимо связано с MIME-types.В параметре TV указано правильно - application/zip, а в момент скачивания определяется неправильно - application/octet-stream.
Кроме того, к файлу прицепляется расширение .html. Автор рекомендует отключить для сайта суффиксы URL. Это нам просто никак не подходит.
В общем, от FileDownloadPE мы решили отказаться. "Такой хоккей нам не нужен!".
Сниппет-плагин FileDownload
Эта "сладкая парочка" работает по другому принципу.
FileDownloadPlugin скрывает настоящие имена файлов, загружаемых с сайта. Он использует TV-параметр FileDownloadFolder, в котором указыватся папка с файлами.
Ссылка на файл получается в виде http://cadx2009/ru_files.html/ru_source_explorer_2.0.zip
Вообще-то это неправильно - такого файла действительно нет, но по этой ссылке можно загрузить файл.
А нам это надо?
Но нужно получше разобраться с настройками. Скорее всего это учтено.
Сниппет FileDownload автоматически отображает файлы в заданной папке
FileDownloadPlugin поддерживает:
- Скачивание файлов из каталога, заданного TV-параметром FileDownloadFolder.
- Привилегий для работы с документами - файл нельзя скачать, если WEB- пользователь не имеет к нему доступа.
- Скачивание больших файлов без тайтм-аутов при малом использовании памяти.
- Частичную загрузку по HTTP/206
- Докачку после разрывов соединений.
- Интеграцию со сниппетом FileDownload.
Установка
1) Создать новый TV FileDownloadFolder с типом ввода text.
2) Создать плагин FileDownloadPlugin.
3) Вставить код плагина.
3) Отметить событие OnWebPagePrerender.
4) Сохранить плагин.
Нужно ещё настроить в .htaccess правило:
RewriteRule ^([^/]*)/?(.*)$ index.php?q=$1&d=$2 [L,QSA]
А то, что было предусмотрено в MODx, закомментировать:
#RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
Еще можно поэкспериментировать с настройками блока памяти (мы этого делать не стали) в коде плагина:
define('FILE_DOWNLOAD_BLOCK_SIZE', 256 * 1024);
define('FILE_DOWNLOAD_VARIABLE', 'FileDownloadFolder');
Дальше надо браться за сниппет.
Сниппет FileDownload
Установка сниппета
- Создать папку assets/shippets/filedownload.
- Скопировать файлы filedownload.class.inc.php, data.db.class.inc.php, и filecount.txt в эту папку.
- Создать новый сниппет FileDownload.
- Скопировать код из FileDownloadSnippet2.5.php в код сниппета.
- При использовании FileDownloadPlugin (а мы его уже установили) записать в конфигурацию плагина (этого мы ещё не делали):
&countDownloads=Count Downloads;list;yes,no;yes &useDbCount=Store Count Where;list;db,file;db
Теперь мы можем вставлять сниппет в разные страницы. Для каждого документа, в котором вызывается сниппет FileDownload, нужно уcтановить значение TV FileDownloadFolder. Это будет указанием плагину - какую папку обрабатывать. В FileDownloadFolder вписывается путь от корня сайта, например assets/files/rucad.
Вот теперь можно вызывать сниппет. Разумеется, он имеет множество параметров, настройкой которых можно добиться нужного эффекта.
Простейший вызов
При самом простом вызове:
[ !FileDownload? &getFolder=`assets/snippets/filedownload`! ]
мы получим примерно такой результат:
Здесь мы видим простой список файлов. Форма отображения достаточно корявая (английские заголовки, формат даты, отсутствие комментариев, счетчика загрузок). Теперь придётся заняться настройкой с помощью параметров.
Параметры сниппета FileDownload
Что отображать
Главный параметр - это &getFolder. Он задает каталог, показываемый сниппетом. Может быть и список каталогов, разделенных запятыми. В этом параметре не надо задавать концевые слэши! Но если мы используем сниппет совместно с плагином, то &getFolder задавать не надо - папка будет взята из TV FileDownloadFolder. Так мы и будем делать в дальнейшем.
Если задать в &getFolder список каталогов, да еще &groupByDirectory=`1`, то на одной странице будут показаны файлы, сгруппированные по каталогам. Вот так:
Но при этом должен быть пустым параметр TV FileDownloadFolder, а это означает потерю защиты файла от скачивания. Оно нам надо - такая группировка?
Если задать параметр &browseDirectories=`1` при заданном TV FileDownloadFolder, то будут отображаться подкаталоги:
В подкаталоги можно заходить и просматривать их содержимое:
Такой вариант вполне может применяться. Недостатком является то, что отображаются настоящие имена каталогов и им нельзя присвоить понятное русскоязычное описание. Иногда это может быть существенным препятствием, а иногда его можно обойти если, например, для какого-то архива задать имена подкаталогов в виде лет - 2008, 2007.
Если не задавать параметр &browseDirectories=`1`, то будет отображаться только каталог, заданный в TV FileDownloadFolder:
Параметр &browseDirectories=`1` должен именно отсутствовать, а не быть установленным &browseDirectories=`0` - в этом случае всё равно выводятся папки.
Для того, чтобы отображались файлы только с некоторыми расширениями, используется параметр &showExt. Можно задать список допустимых расширений, например &showExt=`zip,exe,pdf`. А можно использовать альтернативный вариант - &hideExt.
Внешний вид
Как именно отображать файлы - задается кучей шаблонов. Показанные примеры значительно отличаются от первоначального. Достигнуто это использованием нескольких параметров.
Параметр &tplList=`dnl_list` задаёт имя чанка, в котором описан шаблон вывода (иначе принимается по умолчанию зашитый в код). Пример используемог нами чанка:
<table border="0" cellpadding="5" style="width:95%"> <tr ><td colspan="5"><strong>Дорожка: </strong></td></tr> <tr> <th colspan="2">Файл</th> <th width="10%">Скачан</th> <th width="15%">Размер</th> <th width="10%">Дата</th></tr> <!-- Fd:Splitter --> <!-- This is the parent template --> <tr > <td colspan="5"> <a href="" alt="Выше" title="На уровень выше"><img src=""/></a> </td> </tr> <!-- Fd:Splitter --> <!-- This is the folder template --> <tr > <td><img src=""/></td> <td colspan="4"><a href=""></a></td> </tr> <!-- Fd:Splitter --> <!-- This is the file template --> <tr > <td><img src=""/></td> <td> <a href="" title="Скачать файл"><br /></a> </td> <td align="right"></td> <td align="right"></td> <td align="right"></td> </tr> <!-- Fd:Splitter --> <!-- This is the delete link template --> <a href="">Удалить</a> <!-- Fd:Splitter --> <!-- This is the template used when &groupByDirectory=`1` --> <tr > <td colspan="5"><strong></strong></td> </tr> <!-- Fd:Splitter --> <!-- This is the footer template --> </table>
В этот шаблон мы ввели дополнительную колонку Скачан, задали размеры колонок. В шаблоне используются плейсхолдеры наподобие [ +fd.class+ ]. Во время работы сниппета на их места подставляются текущие значения. Пытливые люди могут сравнить код шаблона с кодом, выдаваемым браузеру. В приведенном шаблоне вроде бы одна таблица, но она состоит из нескольких секций. Не все секции показываются одновременно и обязательно! Это зависит от сочетания аргументов. Используются такие шаблоны:
- Header - Показывается вверху. Когда используется &browseDirectories=`1`, показывает текущий путь, используя плейсхолдеры: [ +fd.path+ ], [ +fd.class+ ]
- Parent - Используется для ссылки на родительскую папку. Использует плейсхолдеры как в шаблоне File, исключая fd.delete и fd.filenumber.
- Folder - Используется для отображения папок. Использует плейсхолдеры как в шаблоне File, исключая fd.delete.
- File - Используется для отображения файлов с помощью плейсхолдеров : [ +fd.filename+ ], [ +fd.extension+ ], [ +fd.path+ ], [ +fd.size+ ], [ +fd.sizetext+ ], [ +fd.type+ ], [ +fd.date+ ], [ +fd.description+ ], [ +fd.image+ ], [ +fd.delete+ ], [ +fd.count+ ], [ +fd.link+ ], [ +fd.class+ ], [ +fd.filenumber+ ]
- Delete - Это шаблон ссылки на удаление файла, вставляемый в [ +fd.delete+ ] если пользователь имеет соответствующие права. Использует плейсходер: [ +fd.deletelink+ ]. Мы его убрали от греха подальше.
- Group By - Шаблон, используемый для нескольких дорожек при действии &groupByDirectory=`1`. Использует плейсхолдеры : [ +fd.directory+ ],[ +fd.class+ ]
- Footer - Показывается в конце.
Описания файлов
На рисунках видны длинные русские описания файлов. Они создаются в чанке, имя которого задано параметром &chkDesc=`dnl_rucad`. В чанке dnl_rucad записаны, в определенном формате, имена и описания файлов:
assets/files/rucad/doc|Документация||
assets/files/rucad/doc/ru_install.pdf|Руководство по установке||
assets/files/rucad/ruSourceExplorerR4.zip|Обозреватель исходных текстов. Версия 4||
assets/files/rucad/ru_air_heater.zip|Поверочный расчет воздухонагревателей||
assets/files/rucad/rudwgpreview_vcl.zip|Компонент Delphi для предварительного просмотра DWG-файлов||
assets/files/rucad/wlx_rudwgpreview_1_1.zip|Плагин к Total Commander для предварительного просмотра DWG-файлов ||
assets/files/rucad/dnl|Старые версии||
assets/files/rucad/dnl/ru_source_explorer_2.0.zip|Обозреватель исходных текстов. Версия 2 ||
Такой чанк надо делать для каждого каталога, указанного в TV. Обратите внимание - имена файлов задаются от корня сайта. К сожалению, на имена каталогов комментарии не распространяются (мы их оставили специально для примера).
Иконки файлов
В наших примерах слева у папок и файлов отображаются свои иконки, причем для каждого типа файла - своя. Достигается это использованием параметров &imgLocat=`assets/templates/yaml/images` и
&imgTypes=`download_img`. Параметр &imgLocat задает каталог, в котором хранятся файлы иконок, а &imgTypes - чанк, в котором описаны типы файлов и соответсвующие им иконки. Место вывода иконок задано в шаблоне местом расположения плейсхолдера fd.image. Пример чанка download_img:
jpg=jpg.gif,
gif=gif.gif,
pdf=pdf.gif,
doc=doc.gif,
dll=dll.gif,
exe=exe.gif,
txt=txt.gif,
lsp=lsp.gif,
zip=zip.gif,
xml=xml.gif,
folder=folderopened.gif,
parent=folderup.gif,
default=default.gif
Сортировка файлов
Задается параметрами &userSort=`date` и &sortOrder=`asc`. В &useSort можно задать
filename | extension | path | size | sizetext | type | date | description | count
а в &sortOrder - asc или desc.
Замечания.
1. При заданном &browseDirectories=`1`сортировка не выполняется как надо.
2. Для сортировки можно задать список полей, например &userSort=`date,extension`. Однако при этом будут рядом выводиться файлы с одинаковыми расширениями, отсортированными по дате, а потом с другими расширениями. Добиться, например, чтобы вверху были самые последние файлы с любыми расширениями, будет сложно - если не применять искусственной нумерации.
Стили
Для изменения внешнего вида списка файлов могут использоваться стили CSS. При желании можно задать стиль для какого-то элемента списка (из числа доступных) или определить стиль с именем по умолчанию. Задать стиль, с именем, отличающимся от имени стиля по умолчанию можно с помощью параметров.
&altCSS (по умолчанию fd-alt) - класс нечетных строк.
&firstFolderCss - класс для первой папки
&lastFolderCss - класс для последней папки папки
&firstFieCss - класс для первого файла
&lastFileCss - класс для последнего файла
&folderCSS (по умолчанию fd-folder) - класс для папок
&fileCSS (по умолчанию fd-file) - класс для файлов
&parentCSS (по умолчанию fd-parent) - класс для родительской папки
&directoryCSS (по умолчанию fd-directory) - класс для каталога при выводе из нескольких папок
&pathCSS (по умолчанию fd-path) - класс для строки с дорожкой при обзоре каталогов
&extCSS (по умолчанию 0) - при установке в 1 позволяет использовать собственные классы для каждого расширения файлов. Например, для exe-файлов будет использоваться класс fd-exe, а для pdf-файлов класс fd-pdf.
Таким образом, разумно манипулируя аргументами, можно добиться любого отображения файлов:
Настройки языка
Сообщения, выдаваемые сниппетом, можно задать в виде аргументов &delSuccess, &delError, &dirOpenError, ¬aDir, &noDownload. Это неплохо для многоязычных файлов, но мы один язык используем. Зачем нам передавать столько аргументов при каждом вызове? Мы просто переведём эти жалкие строчки в коде сниппета в файле filedownload.class.inc.php (не забывая, что его надо сохранить в кодировке UTF-8 без BOM).
Однако иногда мы можем и переопределить в параметре текст сообщения, например:
&noDownload=`Скачивать этот файл имеют право только зарегистрированные пользователи системы ruCAD`
для конкретного случая может быть более подходящим. Такое сообщение имеет смысл, если задан аргумент
&downloadGroups=`Admins,SiteAdmins,ruCAD`
Здесь задан перечень групп WEB-пользователей, имеющих право скачивать файлы.
Не забываем, что менеджеры сайта не относятся в WEB-пользователям. Даже если самый главный администратор зашел в панель управления, но не зашел как WEB-пользователь, он не сможет скачать файл. И совсем не обязательно, чтобы менеджер был одновременно и WEB-пользователем. Не забываем также, что имеются штатные средства MODx для защиты страниц. Если мы хотим сделать скачивание доступным только определенным группам WEB-пользователей, можно защитить сами страницы, и они вообще не будут видны посторонним. Если же страница с файлами видна, но скачать их не позволяется, это вызывает обиду.
К сожалению, полная защита от скачивания не обеспечивается. Если сохранена ссылка на файл в виде, например,
http://cadx2009/ru_files.html/wlx_rudwgpreview_1_1.zip
то по этой ссылке можно будет скачать файл, не заходя на страницу. Сниппет сработает и выдаст файл. Впрочем, ещё надо разобраться - нет ли каких-то настроек на эту тему.
Написать комментарий
Реплика №4: 11.03.2011, 21:05:15
Реплика №3: 24.10.2009, 08:07:27
Реплика №2: 23.10.2009, 21:26:00
Реплика №1: 13.05.2009, 17:10:23