В этой статье я опишу как базово интегрировать плагин 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-ть методов:
- printJson - служит для вывода каких либо JSON данных
- upload - служит для загрузки сохранения изображения на диске и в базе!
- pushImage - служит для сохранения изображения в базу данных
- deleteImage - служит для удаления загруженного изображения с диска и с базы данных
- 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
Результат работы скрипта: