Мы тут вроде вступили недавно в 21 век. А файлы закачиваем всё также - инпутом с типом файл. Долго, не круто и вообще... 21 век же! Всякие гуглы и мейлы уже давно сделали асинхронную закачку файлов. И пока вы заполняете остальную форму - файлы спокойненько себе подкачиваются.
В интернетах гуляет множество решений, некоторые из которых мне совсем не по душе. Например с флеш-компонентами. Такое сразу отсекаем.
После некоторого времени, потраченного на поиски, выбираю решение fine-uploader. Проект более чем живой, обновляется и развивается. Хранится весь на ГитХабе, хотя и свой сайтец у проекта существует. Все ссылки в конце статьи.
UPD: Статья маленько устарела, если честно. Обращайте внимание на версию =)
Сегодня обсуждаем асинхронную подкачку файлов, решение fine-uploader и традиционно - применение к системе Битрикс: прикрепление нескольких асинхронно закаченных файлов к элементу ИБ. Разговор будет долгий и мозгодробительный, так что готовьтесь.
1. Есть клиент-форма, в которую включается jquery плагин, добавляющий свой инпут типа файл с обработчиками событий. Плагин очень гибко настраивается и имеет кучу настроек.
2. Пользователь нажимает Добавить и выбирает файл для закачки. Если файл по каким-то параметрам не подходит, то плагин об этом сообщает (первый уровень проверки).
3. По событию выбора файл асинхронно уходит к серверной части, к обработчику со стороны сервера (второй уровень проверки). На клиентской части в это время работает прогресс-бар. По завершении закачки этот самый серверный обработчик возвращает json-результат для клиентской части.
4. На клиентской форме отображается результат. На этом этапе я приписывала к форме скрытые инпуты с названием файла, чтобы потом по самбиту их обрабатывать.
5. По сабмиту обрабатываем стандартные инпуты и обрабатываем массив с именами файлов, которые нам пришли из формы.
У аплоадера есть две части - клиентская и серверная. Клиентская предоставляет функционал морды и первый уровень проверки закачиваемых файлов. Серверная часть соответственно принимает файл, обеспечивая более приближенный к реальности уровень проверки закачиваемого контента.
Рассмотрим клиентскую часть. После включения файлов jquery и самого плагина, переходим к подключению функционала аплоадера.
Версия, на которой писалась статья - 3.4.1
ГитХаб: Серверная часть
Сайт с примерами и всяким таким
В интернетах гуляет множество решений, некоторые из которых мне совсем не по душе. Например с флеш-компонентами. Такое сразу отсекаем.
После некоторого времени, потраченного на поиски, выбираю решение fine-uploader. Проект более чем живой, обновляется и развивается. Хранится весь на ГитХабе, хотя и свой сайтец у проекта существует. Все ссылки в конце статьи.
UPD: Статья маленько устарела, если честно. Обращайте внимание на версию =)
Сегодня обсуждаем асинхронную подкачку файлов, решение fine-uploader и традиционно - применение к системе Битрикс: прикрепление нескольких асинхронно закаченных файлов к элементу ИБ. Разговор будет долгий и мозгодробительный, так что готовьтесь.
0. Общая логика
1. Есть клиент-форма, в которую включается jquery плагин, добавляющий свой инпут типа файл с обработчиками событий. Плагин очень гибко настраивается и имеет кучу настроек.
2. Пользователь нажимает Добавить и выбирает файл для закачки. Если файл по каким-то параметрам не подходит, то плагин об этом сообщает (первый уровень проверки).
3. По событию выбора файл асинхронно уходит к серверной части, к обработчику со стороны сервера (второй уровень проверки). На клиентской части в это время работает прогресс-бар. По завершении закачки этот самый серверный обработчик возвращает json-результат для клиентской части.
4. На клиентской форме отображается результат. На этом этапе я приписывала к форме скрытые инпуты с названием файла, чтобы потом по самбиту их обрабатывать.
5. По сабмиту обрабатываем стандартные инпуты и обрабатываем массив с именами файлов, которые нам пришли из формы.
1. Работа с jquery-плагином fine-uploader
Вообще сам плагин имеет дикое количество настроек и запутанную распределённую многоступенчатую документацию. Углубляться не буду, пройдусь по верхам и по использованным параметрам. Да и вообще внутрь не полезем, будем смотреть на части нашего сегодняшнего урока как на Чёрные Ящики.У аплоадера есть две части - клиентская и серверная. Клиентская предоставляет функционал морды и первый уровень проверки закачиваемых файлов. Серверная часть соответственно принимает файл, обеспечивая более приближенный к реальности уровень проверки закачиваемого контента.
Рассмотрим клиентскую часть. После включения файлов jquery и самого плагина, переходим к подключению функционала аплоадера.
var uploader = $('#fine-uploader-files').fineUploader({ //ну, во-первых, надо завести div с таким id. это вы и без меня справитесь. request: { endpoint: '/new_order/jsonUploaderHandler.php', //путь к серверной части forceMultipart: false, inputName: 'qqfiles', //имя инпут поля типа file params: { action: 'files' //здесь можно указать доп. параметры, которые надо передать серверной части } }, debug: true, //включаем дебаг в консоль браузера. validation: { allowedExtensions: ['jpg', 'png', 'xls', 'doc', 'docx', 'odt', 'pdf'], //разрешённые типы для первого уровня проверки sizeLimit: 31457280, //максимальный размер файла для первого уровня проверки itemLimit: 5 //максимальное количество файлов для текущего подключения плагина }, dragAndDrop: { disableDefaultDropzone: true //отключаем дроп-зону }, messages: { //русифицируем некоторые сообщения и кнопки typeError: "{file}: неверный тип файла. Принимаются только файлы форматов: {extensions}.", sizeError: "{file}: файл слишком большой. Максимальный размер: {sizeLimit}.", tooManyItemsError: "Вы пытаетесь закачать {netItems}-й файл. Максимальное количество: {itemLimit}." }, text: { uploadButton: 'Прикрепить файлы', failUpload: 'Не закачан!' } })//обработка события .on('complete', function(event, id, fileName, responseJSON) { if (responseJSON.success) //если серверная часть вернула статус успешное завершение $('#form_order').append(''); });Для удобства я добавляю скрытое поле с именем только что добавленного файла. Кстати, можно не бояться, плагин следит за уникальностью имён.
2. Морда плагина
Собственно, вместо указанного элемента, получаем кнопочку, которая по нажатию вызывает диалоговое окно выбора файла. А там уже и оформляем по вкусу.3. Серверная часть
Собственно серверная часть представлена на нескольких языках, смотрите на хитхабе. Меня интересует php, смотрим дальше. Пример на гитхабе более чем исчерпывающий, надо только подставить свои данные =)//защитимся-ка мы от самых умных if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') { // Include the uploader class require_once 'uploads/qqFileUploader.php'; $uploader = new qqFileUploader(); //в зависимости от типа выставляем ограничение на закачки $uploader->allowedExtensions = array("jpg", "png", 'xls', 'doc', 'docx', 'odt', 'pdf'); $uploader->sizeLimit = 31457280; // 30 Mb = 30 * 1024 * 1024 $uploader->inputName = 'qqfiles'; // Call handleUpload() with the name of the folder, relative to PHP's getcwd() $result = $uploader->handleUpload('../upload/problems_images'); // To return a name used for uploaded file you can use the following line. $result['uploadName'] = $uploader->getUploadName(); header("Content-Type: text/plain"); echo json_encode($result); }Обратить внимание следует разве что на адрес, который передаётся для handleUpload. В комментарии там ясно написано, каким он должен быть. Файлы у меня сохранялись во временную папочку, все в одну кучу. При обработке сабмита формы эти файлы распределяются по нужным каталогам и из этой временной папочки удаляются.
4. Добавление элемента в ИБ
Все добавленные к форме "на лету" файлы были записаны в скрытые поля с именем files[], так что после самбита мы получаем массив с именами добавленных файлов. Прроверям пришедшие из формы данные, формируем массив файлов и делаем Add$arDeleteFiles = array(); $el = new CIBlockElement; //свойства по умолчанию $arAdd['NAME'] = 'НОВОЕ ЗАДАНИЕ'; //имя элемента $arAdd['IBLOCK_ID'] = 3; //айдишка ИБ, куда добавляем элемент $arAdd['IBLOCK_SECTION_ID'] = false; // айдишка секции ИБ, куда добавляем элемент //дополнительные файлы if (isset($_REQUEST['files']) && count($_REQUEST['files'])) //в переменной files лежат имена добавленных к этой форме файлов { $counter = 0; //счётчик для множественного добавления файлов в свойство (см. код далее) foreach($_REQUEST['files'] as $file_name) { $file_filepath = $_SERVER["DOCUMENT_ROOT"].'/upload/problems_images/'.$file_name; //временная папка плюс имя файла if (file_exists($file_filepath)) { $arAdd['PROPERTY_VALUES']['FILES']['n'.$counter] = CFile::MakeFileArray($file_filepath); //формируем массив, который поймёт функция добавления array_push($arDeleteFiles, $file_filepath); //формируем массив для удаления использованных файлов из временной директории $counter++; } } } //добавляем элемент или выводим ошибку if($PRODUCT_ID = $el->Add($arAdd)) echo "New ID: ".$PRODUCT_ID; else echo "Error: ".$el->LAST_ERROR; //удаляем файлы из "временной" директории foreach($arDeleteFiles as $sFilePath) unlink($sFilePath); //@unlink($sFilePath);ГитХаб: Клиентская часть
Версия, на которой писалась статья - 3.4.1
ГитХаб: Серверная часть
Сайт с примерами и всяким таким
Спасибо за статью!
ОтветитьУдалитьЯ вот так и не понял, плагин платный? При попытке скачать на сайте, мне говорят что это триал на 45 дней?
У вас какая версия? Можете разместить плагин для скачивания?
угу, а исходников то уже и нет... только демки...
Удалитьдобавлена ссылочка на скачивание внизу статьи
УдалитьПочему же исходников нет?
УдалитьСкачал с сайта fineuploader.com, там версия 3.5.0 с такими же кодами как и в вашей 3.4.1.
Вот только не понятно чего ожидать от этой триальной версии? Она что, перестанет работать через 45 дней? :)
Ссылка на 3.5.0: http://bit.ly/10uJhGq
а чёрт их знает, надо в код смотреть, что там через 45 дней будет =)
Удалитьони и сайт успели поменять, с тех пор как я статью начала писать (заготовка-то давно валялась...
Сравнил исходные коды этих двух версий. Новые изменения по поводу триала или 45 дней не обнаружил :)
Удалитьhttps://github.com/Widen/fine-uploader/releases - здесь легко скачиваются версии клиента вплоть до 4.1.0, а здесь - https://github.com/Widen/fine-uploader-server/releases - версии сервера вплоть до 4.0.0.
УдалитьЛицензия GNU GPL v3 вроде не коммерческая. Или я что-то упускаю?
статья мною писалась когда ребятки там закрыли вообще доступ к исходникам, оставив только триал.
Удалитьсейчас они повесили гну и покупку лицензию на освобождение от гну. ну чего могу сказать. круто.
спасибо за последнюю бесплатную версию)
ОтветитьУдалитьпожалуйста; хорошо, что кому-то пригодилось.
УдалитьДа я уверен пригодилось многим, просто не пишет никто.
УдалитьСветлана, пожалуйста, заэскейпите $file_name перед использованием, а то сейчас можно просмотреть и удалить почти любой файл, доступный пользователю, от имени которого запущен php-скрипт.
ОтветитьУдалитьк счастью, мы уже некоторое время назад избавились от этого модуля =)
УдалитьА что вместо?
УдалитьКстати, с помощью текущего примера серверной части FileUploader'a [url]https://github.com/Widen/fine-uploader-server/blob/master/php/traditional/handler.php[/url], тоже можно на сервере файлы поудалять или папок насоздавать в неожиданных местах - проследите за $_REQUEST['qqfilename'] и $_REQUEST['qquuid']:
ОтветитьУдалить[code]
public function getName(){
if (isset($_REQUEST['qqfilename']))
return $_REQUEST['qqfilename'];
...
}
...
public function handleUpload($uploadDirectory, $name = null){
...
if ($name === null){
$name = $this->getName();
}
...
$uuid = $_REQUEST['qquuid'];
if (!file_exists($targetFolder)){
mkdir($targetFolder);
}
...
$targetFolder = $this->chunksFolder.DIRECTORY_SEPARATOR.$uuid;
$target = join(DIRECTORY_SEPARATOR, array($uploadDirectory, $uuid, $name));
...
$target = fopen($target, 'wb');
...
}
[/code]