В этой статье я опишу как базово интегрировать плагин jQuery File Upload для работы в Joomla CMS

Для начала нам надо пройти по ссылке и скачать последнюю версию этой библиотеки.
В полученном архиве, для базовой работы, нам нужно взять три файла из папки /js/: jquery.ui.widget.js, jquery.iframe-transport.js и jquery.fileupload.js

Далее с помощью генератора каркаса компонентов я создал пустой компонент c именем ajaxupload и одним пустым видом load, и с таблицей images

Поскольку таблица имеет лишние поля можно открыть скачанный архив компонента и изменить запрос создающий таблицу, для этого проследуем в admin/sql/install.mysql.utf8.sql и изменим содержимое файла на следующее:

CREATE TABLE IF NOT EXISTS `wss_images` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `created` datetime NOT NULL,
  `image` varchar(255) NOT NULL,
  UNIQUE KEY `id` (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

Так же можно сначала установить компонент, а потом удалить ненужные поля через phpMyAdmin

После установки компонента нам нужно пройти в папку administrator/components/com_ajaxupload/tables/images.php И в методе bind удалить все кроме установки текущей даты (если вы оставили это поле, в это поле будет записано время загрузки изображения)

В итоге метод bind() должен выглядеть так:

public function bind( $array, $ignore = '' )
	{
		if ( empty( $array['created'] ) ) $array['created'] = JFactory::getDate()->toSql();
		return parent::bind( $array, $ignore );
	}

 

Теперь приступим к реализации пользовательской части:

Для начала скопируем файлы: jquery.ui.widget.js, jquery.iframe-transport.js и jquery.fileupload.js в components/com_ajaxupload/assets/scripts/

Далее открываем дефолтный контроллер components/com_ajaxupload/controller.php и в класс AjaxUploadController добавляем следующий метод:

public function getAjax(){
	$input = JFactory::getApplication()->input;
	$model = $this->getModel( 'load' );
	$action = $input->getCmd( 'action' );
	$reflection = new ReflectionClass( $model );
	$methods = $reflection->getMethods( ReflectionMethod::IS_PUBLIC );
	$methodList = array();
	foreach ( $methods as $method ) {
		$methodList[] = $method->name;
	}
	if ( in_array( $action, $methodList ) ) {
		$model->$action();
	}
	exit;
}

Этот метод нам нужен для перехвата AJAX задач для компонента, и вызова нужных методов из модели load

Далее мы идем в модель load которая лежит у нас по пути components/com_ajaxupload/models/load.php и вставляем в неё следующий код:

<?php

// No direct access
defined( '_JEXEC' ) or die;

/**
 * @author Alexand Denezh
 */
class AjaxuploadModelLoad extends JModelLegacy
{

	/**
	 * Вывод JSON данных
	 * @param $message
	 * @param bool $result
	 * @param array $custom
	 */
	private function printJson( $message, $result = false, $custom = array() )
	{
		$jsonData = array( 'result' => $result, 'message' => $message );
		foreach ( $custom as $key => $value ) {
			$jsonData[$key] = $value;
		}
		echo json_encode( $jsonData );
		exit;
	}

	/**
	 * Загрузка изображений
	 * @throws Exception
	 */
	public function upload()
	{
		$baseUrl = JUri::root();
		$input = JFactory::getApplication()->input;
		$files = $input->files->get( 'files', array(), 'array' ); //Список файлов для загрузки
		if ( isset( $files[0]['error'] ) && (int)$files[0]['error'] == 0 ) { //проверка или файл загружен
			try {
				jimport( 'joomla.filesystem.folder' );//библиотека для работы с папками
				$galleryPath = JPATH_SITE . '/images/gallery/'; //путь по которому будем загружать изображения
				//проверяем или папка для изображений существует, если нет то создаем
				if ( !JFolder::exists( $galleryPath ) ) {
					JFolder::create( $galleryPath );
				}
				//Генерируем имя картинки
				$name = md5( $files[0]['tmp_name'] . mt_rand( 0, 9999 ) . mktime() ) . '.jpg';
				$image = new JImage( $files[0]['tmp_name'] );
				$image->resize( 800, 600, false );//уменьшаем картинку до 800*600 пикселей
				$image->toFile( $galleryPath . $name );//сохраняем картинку на диске
				$storedId = $this->pushImage( $name ); //Сохраняем запись о картинке в БД
				//сообщение о том что картинка загружена
				echo json_encode(
					array(
						'loaded' => 'true',
						'file' => array(
							'path' => $baseUrl . '/images/gallery/' . $name, //путь к загруженной картинки
							'id' => $storedId // id загруженной картинки в БД
						)
					)
				);
			} catch ( Exception $ex ) {
				//Если не удалось сохранить картинку то выводим сообщение об ошибке загрузки
				echo json_encode( array( 'loaded' => 'false' ) );
			}

		}
		exit;
	}


	/**
	 * Сохранение изображения в базе
	 * @param $image
	 * @return mixed
	 * @throws Exception
	 */
	private function pushImage( $image )
	{
		$table = $this->getTable( 'images' ); //таблица с картинками
		$table->bind(
			array( 'image' => $image )
		);
		$table->store(); //вставляем изображение
		return $table->id;//возврат id изображения
	}

	/**
	 * Удаление изображения из базы
	 * @throws Exception
	 */
	public function deleteImage()
	{
		$input = JFactory::getApplication()->input;
		$id = $input->getInt( 'id', 0 );
		$table = $this->getTable( 'images' ); //таблица с картинками
		if ( $table->load( $id ) ) { //Загружаем запись
			jimport( 'joomla.filesystem.file' );
			//Удаляем картинку из папки
			JFile::delete( JPATH_SITE . '/images/gallery/' . $table->image );
			if ( $table->delete( $id ) ) {//Если запись удалена то выводим сообщение о удалении
				$this->printJson( 'Изображение удалено!', true );
			}
		}
		$this->printJson( 'Ошибка удаления!' );
	}

	/**
	 * Список загруженных изображений
	 * @return mixed
	 */
	public function getImages()
	{
		$query = $this->getDbo()->getQuery( true )->select( '*' )
			->from( '#__images' );
		return $this->getDbo()->setQuery( $query )->loadObjectList();
	}
}

 

В нашей модели 5-ть методов:

  1. printJson - служит для вывода каких либо JSON данных
  2. upload - служит для загрузки сохранения изображения на диске и в базе!
  3. pushImage - служит для сохранения изображения в базу данных
  4. deleteImage - служит для удаления загруженного изображения с диска и с базы данных
  5. getImages - служит для получения списка ранее загруженных изображений в базу данных

Далее заходим в наш вид components/com_ajaxupload/views/load/view.html.php и в методе display добавим строку $this->images = $this->get( 'images' );

И последний шаг пишем в шаблон вида подключение скриптов и скрипт обработчик загрузки файлов!

Для этого вставляем следующий код в файл: components/com_ajaxupload/views/load/tmpl/default.php

<?php
/** @var $this AjaxuploadViewLoad */
defined( '_JEXEC' ) or die; // No direct access

$baseUrl = JUri::base();
$imagesPath = JUri::root() . 'images/gallery/';
//Подключение jQuery
JHtml::_( 'jquery.framework', false, null, false );
//Подключение скриптов
JFactory::getDocument()
	->addScript( $baseUrl . 'components/com_ajaxupload/assets/scripts/jquery.ui.widget.js' )
	->addScript( $baseUrl . 'components/com_ajaxupload/assets/scripts/jquery.iframe-transport.js' )
	->addScript( $baseUrl . 'components/com_ajaxupload/assets/scripts/jquery.fileupload.js' );
?>
<script>
	jQuery(document).ready(function ($) {
		$('#fileupload').fileupload({//инициализация плагина загрузки файлов
			dataType: 'json',//тип данных
			url: '<?php echo $baseUrl; ?>index.php',//скрипт обработчик
			formData: {//данные формы (компонент, задача, действие)
				option: 'com_ajaxupload',
				task: 'getAjax',
				action: 'upload'
			},
			add: function (e, data) {//Метод который вызывается перед загрузкой файлов
				$('#progress .bar').css('width', '0px');
				data.submit();//Сабмит формы
			},
			done: function (e, data) {//метод который вызывается при завершение загрузки изображений
				if (data.result.loaded) {//если изображение успешно загружено то добавляем в таблицу загруженную картинку
					$('.table-files-upload tbody').append('<tr>' +
					'<td style="text-align: center;"><a href="' + data.result.file.full + '"><img  src="' + data.result.file.path + '" style="height: 50px;"  /></a></td>' +
					'<td><input type="button" class="btn btn-danger btn-delete-gallery-image" data-id="' + data.result.file.id + '" value="Удалить изображение"></td>' +
					'</tr>');
				}
			},
			progressall: function (e, data) {//метод для визуализации общего прогресса загрузки
				$('.progress-info').show();//показываем прогресс бар
				var progress = parseInt(data.loaded / data.total * 100, 10);//вычисляем процент длины прогресс бара
				$('#progress .bar').css('width', progress + '%');//отображаем длину прогресс бара
			}
		});
		//Слушатель на кнопку для удаления уже загруженной картинки:
		$(document).on('click', '.btn-delete-gallery-image', function () {
			if (confirm('Удалить изображение?')) {
				var button = $(this);
				button.hide();
				$.getJSON('index.php?option=com_ajaxupload&task=getAjax&action=deleteImage&id=' + button.data('id'), function (response) {
					if (!response.result) {
						alert(response.message);
					} else {
						button.closest('tr').remove();
					}
				});
			}
		});
	});
</script>

<div class="item-page">
	<h1>Загрузка файлов</h1>
	<!-- поле для загрузки файлов -->
	<div class="upload-block-hidden btn btn-primary" style="position:relative;">+ Загрузить изображения в галерею
		<input id="fileupload" type="file" name="files[]" multiple style="position: absolute;opacity: 0; width: 100%; height: 100%; top: 0; left: 0;">
	</div>
	<br /><br />
	<!-- прогресс бар -->
	<div class="progress progress-info progress progress-striped active" id="progress">
		<div class="bar" style="width: 0%"></div>
	</div>
	<!-- Таблица в которой будут отображены загруженные изображения -->
	<table class="table table-files-upload table-bordered table-striped table-hover table-condensed" style="width: 500px;">
		<thead>
		<tr>
			<th style="width: 50px">Изображение</th>
			<th>Действие</th>
		</tr>
		</thead>
		<tbody>
		<?php foreach ( $this->images as $image ): ?>
			<tr>
				<td style="text-align: center;">
					<a href="/<?php echo $imagesPath . $image->image; ?>" class="zoom-image">
						<img src="/<?php echo $imagesPath . $image->image; ?>" alt="" style="height: 50px;" class="block" />
					</a>
				</td>
				<td>
					<input type="button" class="btn btn-danger btn-delete-gallery-image" data-id="<?php echo $image->id; ?>" value="Удалить изображение">
				</td>
			</tr>
		<?php endforeach; ?>
		</tbody>
	</table>
</div>

Самое важное в этом файле это инициализация плагина fileupload в котором мы передаем данные и обрабатываем полученные данные

Так же в начале этого файла мы подключаем jQuery и файлы скриптов плагина jQuery File Upload

Готовый компонент можно скачать тут, после установки вызывать http://sitename/?option=com_ajaxupload

Результат работы скрипта: Результат проделанной работы!