strokoff

Форма загрузки файлов Joomla 3.2+ для компонентов и модулей

Форма загрузки файлов Joomla 3.2

При разработке компонента для joomla 2.3.2 появилась необходимость в создании формы загрузки изображений. Причем загружать хотелось бы несколько изображений. Просмотр документации на эту тему ничего не выдал, да и гугл решений тоже не выдал, решено писать свой велосипед для мульти загрузки файлов в joomla 3.2. Для загрузки одного файла в joomla у нас не возникнет каких-то особых проблем.
Вот пример кода загрузки одного файла.

HTML шаблон

 


<form method="post" enctype="multipart/form-data"  action="index.php" >
<input type="file" id="image"name="image">
</form>

В php пишем уже загрузку


jimport('joomla.filesystem.file');

$fileInput = new JInput($_FILES);
$file = $fileInput->get('image', null, 'array');

if(isset($file) && !empty($file['name'])) {
$filename = JFile::makeSafe($file['name']);
$src = $file['tmp_name'];
$data['image']=$filename;
$path = JPATH_SITE . '/modules/mod_helloworld/images/'
$dest = $path . $filename;

JFile::upload($src, $dest);
}

Но что делать, если мы хотим загружать несоклько файлов ? Мы не можем передать массив файлов  в класс JInput т.к. он строится по принципу $_FILES[‘name’][$i] . Решением стало создание формы с динамическим добавлением дополнительных инпутов для файлов. Я приведу пример из своего кода, все основано на twittert bootstrap и jquery.

Фрагмент с полем для изображений:


<div class="control-group">
<label class="control-label" for="photo">Фотографии
<button type="button" class="btn btn-mini" id="add_photo"><i class=" icon-plus"></i></button>
</label>
<div class="controls controls-photo">
<input type="file" id="photo" name="photo1">
<input type="hidden" name="files_count" id="files_count" value="1">

</div>
</div>

Я создал кнопку button#add_photo на которую мы повесим простенький скрипт добавления еще одного поля. Также добавил скрытое поле с счетчиком количества input#files_count, мы будем менять его через jQuery.


jQuery(document).ready(function($){

$('#add_photo').on('click', function(){

//Текущее количество инпутов
var filesCount = Number($('#files_count').val());

//Прибавляем количество
var newCount = filesCount+1;

//Добавляем инпут
$('.controls-photo').prepend('<input type="file" id="photo'+newCount+'" name="photo'+newCount+'" ><br>');

//Меняем скрытый инпут
$('#files_count').val(newCount);
});
});

Теперь немного переработаем предыдущий метод загрузки файлов и напишем свой велосипед. Код прокомментировал.


//Функция загрузки некой записи в бд
function addNewObject() {

//Путь загрузки
$filesPath = JPATH_ROOT.'/components/com_velesrealty/images/';
//Количество файлов
$filesCount = JRequest::getVar('files_count', 1, 'post');

//Создаем новый экземпляр JInput

$input = JFactory::getApplication()->input;

//Проходимся по инпутам с файлами
for($i = 1; $i <= $filesCount; $i++){

$fileformname = 'photo'.$i;

//Получаем файл из формы с name="photo"
$file = $input->files->get($fileformname);

//Новое имя
$newfilename = uniqid().'-'.$file['name'];

//Делаем имя файла безопастным для использования
$newfilename = JFile::makeSafe($newfilename);

//Проверка разрешения файла
if($file["type"] == "image/jpeg" || $file["type"] == "image/png") {
//Если файл и имя не пустое
if(isset($file) && !empty($file['name'])) {

//Создаем полный путь с имененем
$fullpath = $filesPath.$newfilename;

//Загружаем файл
JFile::upload($file['tmp_name'], $fullpath);

//Добавляем имя в массив
$photos[] = $newfilename;
}
} else {
JFactory::getApplication()->enqueueMessage('Неверный формат файла', 'error');
return false;
}
}

//Запаковываем имена в json удобного хранения в бд.
$photos = json_encode($photos);

// Ну и дальше уже в бд добавляем...

Хочу отметить, что код все-таки придется причесать под себя. Вывод ошибок сделан с помощью вывода сообщений JFactory::getApplication()->enqueueMessage, я вызываю этот метод из модели компонента. Для модуля и других областей применения стоит переписать вывод ошибок. На этом все. Если будут вопросы, пишите, дополню статью.


Последняя редакция 17 февраля, 2023 в 08:02