Форум русской поддержки Joomla!® CMS
21.07.2017, 02:29:28 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
   
   Начало   Поиск Joomla 3.0 FAQ Joomla 2.5 FAQ Joomla 1.5 FAQ Правила форума Новости Joomla Реклама Войти Регистрация Помощь  
Страниц: [1]   Вниз
  Добавить закладку  |  Печать  
Автор

Мультизагрузка файлов [решение]

 (Прочитано 98 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Liss
Давно я тут
****

Репутация: +9/-0
Offline Offline

Сообщений: 219


« : 08.06.2017, 14:11:39 »

Joomla 3.7.2
RSForm 1.52.12

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

Грузить будем красиво, нам поможет проект https://www.fyneworks.com/jquery/multifile/
Скачиваем jquery.MultiFile.js и кидаем его в /media/com_rsform/js

Править исходный код нужно будет всего в двух файлах:
/administrator/components/com_rsform/helpers/rsform.php
/administrator/components/com_rsform/helpers/fields/fileupload.php

Немного теории. У нас на форме может быть любое кол-во полей типа type="file". Это означает, что в обработчике мы принимаем двухуровневый массив из данных: первый уровень - это массив полей, второй уровень - это массив с информацией о файле ($file['name'], $file['error'] и т.д., погуглите общую теорию о передачи файлов через post). Если мы хотим мульзагрузку, то обработчик принимает уже трехуровневый массив:
 
Код:
поле 1
   - файл 1
     - имя файла
     - код ошибки
     - временная папка
     - размер
  - файл 2
    - имя
    - и т.д
 поле 2
   - файл 1
     - и т.д
   - файл 2

и т.д.
 
Записан
Liss
Давно я тут
****

Репутация: +9/-0
Offline Offline

Сообщений: 219


« Ответ #1 : 08.06.2017, 14:31:16 »

строки пишу примерно, из-за доработок нумерация у меня скорее всего "поехала"

итак файл fileupload.php, допилим функцию function getFormInput()
строка 48
это
Код:
$html .= ' name="'.$this->escape($name).'"'.
меняем на это
Код:
$html .= ' name="'.$this->escape($name).'[]"'.
Таким образом мы определяем массив (а не одну переменную, как изначально)

в районе строки 58 перед return $html; вставляем
Код:
RSFormProAssets::addScript(JHtml::script('com_rsform/jquery.MultiFile.js', false, true, true));
Таким образом подключаем нашу "красоту"

теперь допилим function processBeforeStore($submissionId, &$post, &$files)
ее содержание должно быть таково:
Код
foreach ($files[$this->name] as $file) {
 if ($file) {
 
     if (!empty($file['name']) && $file['error'] == 0) {
 
       $prefixProperty = $this->getProperty('PREFIX', '');
$destination    = $this->getProperty('DESTINATION', '');
// Prefix
$prefix = uniqid(''). '-';
if (strlen(trim($prefixProperty)) > 0) {
 $prefix = RSFormProHelper::isCode($prefixProperty);
}
 
// Path
$realpath = realpath($destination . DIRECTORY_SEPARATOR);
 if (substr($realpath, -1)!= DIRECTORY_SEPARATOR) {
   $realpath .= DIRECTORY_SEPARATOR;
 }
 
       // Filename
$fi = $realpath . $prefix . $file['name'];
       if (JFile::upload($file['tmp_name'], $fi, false, (bool) RSFormProHelper::getConfig('allow_unsafe'))){
 
         // Tut kod zapisi v BD. Originalniy kod tut ne rabotaet
 
       }
     }
 
 }
}
 

Про запись в БД: изначально компонент может грузить только один файл, и в БД он пишется вот так:
---
SubmissionValueId            | FormId    | SubmissionId   | FieldName | FieldValue
уникальный номер записи | ID формы | ID заполнения | имя поля   | значение поля (вот тут будет имя файла)
---
но у нас теперь не имя файла, а целый массив из имен. Хотите, пишите туда массив (сериализовать не забудьте). Хотите, пишите сюда некий ID, а сами файлы в отдельную таблицу, и группа файлов от туда будет цепляться по этому некому ID. В любом случае далее необходимо уже переписывать код вывода результатов
« Последнее редактирование: 08.06.2017, 14:36:57 от Liss » Записан
Liss
Давно я тут
****

Репутация: +9/-0
Offline Offline

Сообщений: 219


« Ответ #2 : 08.06.2017, 15:02:28 »

файл RSForm.php
строка в районе 2460, нас интересует секция, которая в оригинале прокомменитирована вот так
// Upload field
В этой секции происходит валидация формы (проверка расширения, размера - это все настраивается в админке при создании поля). Концепция правки кода тут аналогична по смыслу и объясняется тем же: у нас массив теперь трехуровневый. Выглядит код теперь так (это НЕ сразу после // Upload field, а ниже, смотрите и сравнивайте с оригинальным кодом) :
Код
 
 if ($files = JFactory::getApplication()->input->files->get('form', null, 'raw')) {
   foreach ($files as $file) {
     foreach ($file as $fil) {  
       $name = $fil['name'];
       $tmp_name = $fil['tmp_name'];
       $error = $fil['error'];
       $size        = $fil['size'];
 
       // File has not been sent but it's required
if ($error == UPLOAD_ERR_NO_FILE && $required && !$originalUpload) {
 $invalid[] = $data['componentId'];
 continue;
}
 
       // File has been uploaded correctly to the server
if ($error == UPLOAD_ERR_OK) {
 // Let's check if the extension is allowed
 $extParts = explode('.', $name);
 $ext = strtolower(end($extParts));
 $acceptedExts        = !empty($data['ACCEPTEDFILES'])? self::explode($data['ACCEPTEDFILES']) : false;
 
 // Let's check only if accepted extensions are set
 if ($acceptedExts) {
   $accepted = false;
   $extListForMsg ='';
           foreach ($acceptedExts as $acceptedExt) {
     $acceptedExt = trim(strtolower($acceptedExt));
     $extListForMsg .= $acceptedExt.', ';
     if (strlen($acceptedExt) && $acceptedExt == $ext) {
       $accepted = true;
break;
     }
   }
   if (!$accepted) {
     $invalid[] = $data['componentId'];
     $extListForMsg = substr($extListForMsg, 0, -2);
     $msg = $name.' – '.JText::_('RSFP_UPLOAD_ERR_EXT').' '.$extListForMsg;
   }
 }
 
 // Let's check if it's the correct size
 if ($size > 0 && $data['FILESIZE'] > 0 && $size > $data['FILESIZE']*1024) {
   $invalid[] = $data['componentId'];
   $msg = $name.' – '.JText::_('RSFP_UPLOAD_ERR_FORM_SIZE');
   continue;
 }
 if (isset($msg)) {
   JFactory::getApplication()->enqueueMessage($msg, 'warning');
 }
       }
       elseif ($error != UPLOAD_ERR_NO_FILE) {
// tut kod ostavlyaem kak est', nichego ne menyaem
       }
     }
   }
 }
 
тут я также ввел языковую переменную RSFP_UPLOAD_ERR_EXT, которую необходимо прописать в языковой файл /language/ru-RU/ru-RU.com_rsform.ini
RSFP_UPLOAD_ERR_EXT="формат файла не разрешён в настройках этой формы. Допустимы следующие форматы файлов: "
Записан
Liss
Давно я тут
****

Репутация: +9/-0
Offline Offline

Сообщений: 219


« Ответ #3 : 08.06.2017, 15:11:01 »

чтобы подключенный jquery.MultiFile.js отрабатывал наше поле, в админке в настройках поля во вкладке "атрибуты" в поле "доп. атрибуты" пишем
Код:
class="multi"
если хотите, чтоб показывались превьюшки загружаемых файлов пишем так
Код:
class="multi with-preview"


если хотите, чтоб файлы цеплялись не по одному, а сразу группой (т.е. через "обзор" можно выделить несколько файлов разом), пишем так
Код:
class="multi with-preview" multiple

Вообще посмотрите сайт проекта этого плагина, там много настроек и примеров

PS не забывайте, что помимо ограничения на размер загружаемого файла (каждого), есть ограничение на размер всей формы целиком. По умолчанию, это 20 Mb (изменяется в php.ini)
PPS и еще про запись в БД: специфика моей задачи скорее подразумевает запись информации о загружаемых файлах в отдельную таблицу. Если интересно продолжение, напишу (ну как доделаю)

Всем добра
Записан
Страниц: [1]   Вверх
  Добавить закладку  |  Печать  
 
Перейти в:  

Powered by SMF 1.1.21 | SMF © 2006, Simple Machines

Joomlaforum.ru is not affiliated with or endorsed by the Joomla! Project or Open Source Matters.
The Joomla! name and logo is used under a limited license granted by Open Source Matters
the trademark holder in the United States and other countries.

LiveInternet