Codeigniter и SWFUpload
Не так давно я открыл для себя достаточно интересный фреймворк, но уже для php — Codeigniter. В принципе, достаточно простой, удобный, мощный и, что очень важно, быстрый фреймворк. Я планирую ещё написание цикла статей по работе с Codeigniter, от самого начала до создание каких-то более-менее вразумительных задач. Лично я создаю на нём свою собственную CMS — noneCMS, да вот такой я скромный (-: Это исключительно для себя будет детище (-:
Так вот… понадобился мне загрузчик файлов на сервер из моей CMS. Ну там фотки всякие, картинки, мало ли что может понадобиться. Смысл был в том, что загрузив изображения, они должны быть потом доступны при создании статей, т.е. в TinyMCE. К слову, в качестве редактора у себя я использую именно TinyMCE. Надо будет тоже написать несколько статей по его установке и настройке — уж больно вкусная шняжка (-: Но сейчас не об этом. Думал что-то найти, замутить, чтоб связать jQuery и CI, чтоб асинхронно передавать файлики на сервер. Однако не нашлось никакого тривиального решения, особенно для мультизагрузки файлов. Перелопатив пол-интернета в поисках приемлемого решения, сначала остановил свой взор на Uploadify. Однако мне так и не удалось его подружить с CI. Больно заковыристо он использует скрипт на сервере, и правка кода исходников тоже не помогла. А может просто руки у меня не из того места растут (-: После нескольких дней безуспешных попыток скрестить Codeigniter и Uploadify, Евгений Самборский подсказал мне наличие другого замечательного решения — SWFUpload. На сайте разработчиков можно посмотреть несколько демок, чтоб понять, что это и с чем это едят. Я же расскажу, как заставить эту сладкую парочку работать друг с другом. Я наивно предполагаю, что Вы уже умеете работать с Codeigniter (-: Если нет, то ждите в скором времени статей для новичков, как работать с этим продуктом (-:
Для остальных же имеем следующее:
1. Установленный и настроенный для работы CI.
2. Скачиваем SWFUpload. Хотя этого будет мало (-: Ну лично у меня не получилось заставить работать этот плагин только скачав его ядро. Поэтому я взял за основу пример на странице разработчиков SWFUpload. Всё, необходимое для работы плагина, я сохранил в папке swfupload в корне рабочей папки Codeigniter. О! Чуть не забыл: в Firefox 3.0.11 у меня не работали демки с сайта SWFUpload. Пришлось обновить его, огненного лиса, до последней версии 3,5. Так вот, в папке swfupload находится следующее:
- папка Flash
- папка plugins
- default.css
- fileprogress.js
- handlers.js
- jquery-1.3.2.js
- swfupload.js
- swfupload.queue.js
- XPButtonUploadText_61x22.png — это кнопка (-:
3. Дальше создаём view для отображения в CI:
<html>
<head>
<meta http-equiv=»content-type» content=»text/html; charset=UTF-8″>
<script type=»text/javascript» src=»<?php echo base_url(); ?>swfupload/jquery-1.3.2.js»></script>
<script type=»text/javascript» src=»<?php echo base_url(); ?>swfupload/swfupload.js»></script>
<script type=»text/javascript» src=»<?php echo base_url(); ?>swfupload/swfupload.queue.js»></script>
<script type=»text/javascript» src=»<?php echo base_url(); ?>swfupload/fileprogress.js»></script>
<script type=»text/javascript» src=»<?php echo base_url(); ?>swfupload/handlers.js»></script>
<link href=’<?php echo base_url(); ?>swfupload/default.css’ rel=»stylesheet» type=»text/css» />
<script type=»text/javascript»>
$(document).ready(function(){
var upload1;
upload1 = new SWFUpload({
// Backend Settings
upload_url: «<?php echo base_url(); ?>index.php/swfupload/do_upload»,
post_params: {«PHPSESSID» : «r1b26raj2pe1ef637fv1mg3dk7″},
// File Upload Settings
file_size_limit : «1024″, // 100MB
file_types : «*.jpg;*.gif;*.png»,
file_types_description : «All Files»,
file_upload_limit : «10″,
file_queue_limit : «3″,
debug : true,
// Event Handler Settings (all my handlers are in the Handler.js file)
file_dialog_start_handler : fileDialogStart,
file_queued_handler : fileQueued,
file_queue_error_handler : fileQueueError,
file_dialog_complete_handler : fileDialogComplete,
upload_start_handler : uploadStart,
upload_progress_handler : uploadProgress,
upload_error_handler : uploadError,
upload_success_handler : uploadSuccess,
upload_complete_handler : uploadComplete,
// Button Settings
button_image_url : «<?php echo base_url(); ?>swfupload/XPButtonUploadText_61x22.png»,
button_placeholder_id : «spanButtonPlaceholder1″,
button_width: 61,
button_height: 22,
// Flash Settings
flash_url : «<?php echo base_url(); ?>swfupload/flash/swfupload.swf»,
custom_settings : {
progressTarget : «fsUploadProgress1″,
cancelButtonId : «btnCancel1″
},
// Debug Settings
debug: false
});
});
</script>
</head>
<body>
<div>
<div class=»fieldset flash» id=»fsUploadProgress1″>
<span class=»legend»>Large File Upload Site</span>
</div>
<div style=»padding-left: 5px;»>
<span id=»spanButtonPlaceholder1″></span>
<input id=»btnCancel1″ type=»button» value=»Cancel Uploads» onclick=»cancelQueue(upload1);» disabled=»disabled» style=»margin-left: 2px; height: 22px; font-size: 8pt;» />
<br />
</div>
</div>
</body>
</html>
В принципе, ничего сверхъестественного, все настройки можно найти на сайте разработчиков SWFUpload. Хочу обратить ваше внимание на то, что подключены все упомянуты мною файлы *.js, а в качестве обработчика с серверной стороны указан index.php/swfupload/do_upload. Нам этот обработчик ещё предстоит создать. Вот этим и займёмся.
4. Создаём контроллер для нашего мультизагрузчика. Лично я особо ничего не выдумывал и взял для начала стандартный пример для загрузки файлов из помощи по Codeigniter. Собственно, вот сам контроллер:
<?php if ( ! defined(‘BASEPATH’)) exit(‘No direct script access allowed’);
class Swfupload extends Controller {
function Swfupload()
{
parent::Controller();
$this->load->helper(array(‘form’, ‘url’));
}
function index()
{
$this->load->view(‘swfupload’);
}
function do_upload()
{
$config['upload_path'] = ‘./uploads/’; // server directory
$config['allowed_types'] = ‘gif|jpg|png’; // by extension, will check for whether it is an image
$config['max_size'] = ’1000′; // in kb
$config['max_width'] = ’1024′;
$config['max_height'] = ’768′;
$this->load->library(‘upload’, $config);
// $this->load->library(‘Multi_upload’);
$files = $this->upload->do_upload(‘Filedata’);
if ( ! $files )
{
$error = array(‘error’ => $this->upload->display_errors());
$this->load->view(‘upload_form’, $error);
}
else
{
$data = array(‘upload_data’ => $files);
$this->load->view(‘upload_success’, $data);
}
}
}
?>
Все, как видите, предельно просто (-: Единственное, на что обращаю ваше внимание, это вызов нашего метода контроллера, отвечающего, собственно, за загрузку:
$files = $this->upload->do_upload(‘Filedata’);
Здесь ‘Filedata’ — это id поля по умолчанию, по которому и передаётся, собственно, файл. В принципе, оно может быть произвольным, необходимо только при инициализации указать соответствующий параметр: file_post_name. Но и это ещё не всё (-: При настройках по умолчанию CI не станет загружать файлы… Поэтому необходимо ещё произвести некоторые настройки, о чём подробно написано вот тут:
открываем файл system/application/config/mimes.php и для необходимых расширений файлов (в моём случае это jpg, gif и png) меняем на следующее:
‘gif’ => array(‘image/gif’, ‘application/octet-stream’),
‘jpeg’ => array(‘image/jpeg’, ‘image/pjpeg’, ‘application/octet-stream’),
‘jpg’ => array(‘image/jpeg’, ‘image/pjpeg’, ‘application/octet-stream’),
‘jpe’ => array(‘image/jpeg’, ‘image/pjpeg’, ‘application/octet-stream’),
‘png’ => array(‘image/png’, ‘image/x-png’, ‘application/octet-stream’),
Теперь CI чудесным образом будет принимать и складывать все ваши картинки в указанной Вами директории, в моём случае это /uploads/. Вот и всё, что касается того, как подружить Codeigniter и SWFUpload.
Но мой туториал на этом не заканчивается! (-: Если Вы внимательно посмотрите на примеры использования, то увидите, что прогресс-бар загрузки файлов разного цвета когда файл поставлен в очередь загрузки, когда загружается и когда уже загружен. Ну вот мне не подходили данные цвета, указанные по умолчанию, ну не вписываются они в цветовую гамму моего дизайна! (-: поэтому было решено изменить цвета под свой дизайн. Первое, что пришло в голову — это всё сделано в swf-файле и мне срочно нужен декомпилятор, чтоб получить fla-файл и там поменять цвета… но всё оказалось гораздо прозаичнее: все цвета меняются в файле default.css. В частности идёте в раздел «Table Styles», там есть соответствующие разделы:
- /* Error */
.red {
border: solid 1px #B50000;
background-color: #FFEBEB;
} - /* Current */
.green {
border: solid 1px #DDF0DD;
background-color: #FFFFCC;
} - /* Complete */
.blue {
border: solid 1px #CEE2F2;
background-color: #f6de76;
}
Думаю, из названий понятно, где, когда и что используется (-: Правда после моих изменений blue уже как бы и не blue, да и green уже далеко не green… ну да меня это даже как-то совсем и не волнует (((-: Главное, что оно мне по цвету подходит (-:
Вот теперь уже точно всё! Надеюсь, кому-то это поможет (-:
P.S. Если вдруг что-то не получится — свистите, выложу полностью исходники (-:
P.P.S. Всем замечательный плагин SWFUpload, но вот надписи-то в нём на английском! Как бы меня это не сильно расстроило, но решил и это настроить (-: Оказалось всё до ужаса прозаично, даже никаких танцев с бубном (-: Просто открываете файл handlers.js и правите там соответствующие сообщения, лично я пока только исправил «Pending…», «Uploading…» и «Complete» на соответственно «Ожидает…», «Идёт загрузка…» и «Загружено». Так же в этом файле можно настроить и сообщения об ошибках и т.п.
Недавние записи
- Long time no see
- Ошибка при обновлении Meteor до версии 1.4.2
- Patch falcon для ruby-1.9.3-p327
- Ускоряем ruby и Rails
- Gem ‘seo_params’: определение основных параметров
- Отрицательный margin-top и Opera
- Rspec and Devise reset password
- Backbone.js: Views. Часть первая.
- Backbone.js: Models and Collections
- Backbone.js Routers
Август 18th, 2009 at 08:04
Делал по статье нечего не заработало. =( Собрал собственную солянку все заработало, но без jQuery.
У меня два вопроса? =) Не понял для чего используется jQuery в вашем примере? И вопрос номер 2 =) После функции $this->upload->do_upload(‘Filedata’); хотел сделать ресайз фалов примерно так $data=$this->upload->data();
$this->load->library(‘image_lib’);
$filename=rand(1000, 900000).».jpg»;
$config1['image_library']=’gd2′;
$config1['source_image']=»./uploads/$data[file_name]«;
$config1['new_image']=»./uploads/ttt_$filename»;
$config1['create_thumb']=FALSE;
$config1['maintain_ratio']=TRUE;
$config1['width']=128;
$config1['height']=128;
$this->image_lib->initialize($config1);
$this->image_lib->resize();
Но после функции $this->upload->do_upload(‘Filedata’); ничего не работает =(
Использовал вариант http://demo.swfupload.org/v220/speeddemo/index.php
Август 18th, 2009 at 08:22
Обо всё по-порядку (-:
1. Ну явно jQuery не используется, но у меня на страничке ещё куча всего делается. Поэтому я предпочитаю весь исполняемый код писать внутри $(document).ready(function(){…}) Ну такая у меня привычка (-:
2. Я после аплоада тоже делаю превьюшки… конфиг практически такой же, за исключением, $config['create_thumb']=TRUE;
Итого, вот что у меня:
$config['image_library'] = ‘gd2′; // выбираем библиотеку
$config['source_image'] = $return['full_path'];
$config['create_thumb'] = TRUE; // ставим флаг создания эскиза
$config['maintain_ratio'] = TRUE; // сохранять пропорции
$config['width'] = 75; // и задаем размеры
$config['height'] = 50;
$config['new_image'] = $return['file_path'] . «../thumb/»;
$this->load->library(‘image_lib’, $config); // загружаем библиотеку
$this->image_lib->resize(); // и вызываем функцию
Правда у меня ещё по-другому задаётся имя исходного файла, попытайте поиграться с этим…
Август 18th, 2009 at 09:51
Блин, уже все варинты перепробовал. Все работает файлы загружаются на не режутся =( в чем ерор не понятно =(
Вот функция do_upload посмотрите свежим взглядом может где-то что не то
function do_upload(){
$config['upload_path'] = ‘./uploads’;
$config['allowed_types'] = ‘gif|jpg|png’;
$config['max_size'] = ’10000′;
$config['max_width'] = ’1024′;
$config['max_height'] = ’768′;
$this->load->library(‘upload’, $config);
$this->upload->do_upload(‘Filedata’);
$data=$this->upload->data();
$this->load->library(‘image_lib’);
$filename=rand(1000, 900000).».jpg»;
$config1['image_library']=’gd2′;
$config1['source_image']=»./uploads/$data[file_name]«;
$config1['new_image'] = «./uploads/$filename»;
$config1['create_thumb']=FALSE;
$config1['maintain_ratio']=TRUE;
$config1['width']=128;
$config1['height']=128;
$this->image_lib->initialize($config1);
$this->image_lib->resize();
}
Август 18th, 2009 at 09:57
Ха нашел ошибку! =) Все было до банальности просто в форму нужно указывать параметр action на функцию где вызывается вьювер =)
Август 18th, 2009 at 10:13
Мои поздравления (-:
Иногда решение оказывается настолько банальным, что аж даже обидно немного (-:
Август 20th, 2009 at 16:59
я делаю создание класса SWFUpload в отдельном js файле, соответственно передать так путь к картинке не полуится, прописывать жестко не хочется, как быть?
Август 20th, 2009 at 17:18
Хороший вопрос… даже и не знаю, что Вам сразу вот так ответить…
Кроме полного пути ничего не приходит вот так сразу на ум… надо будет обиозговать это…
Сентябрь 15th, 2010 at 10:05
беда беда, при аплоаеде возращает ошибку 302.
SWF DEBUG: Event: uploadError: HTTP ERROR : File ID: SWFUpload_0_0. HTTP Status: 302.
как решить?
p.s. обычным post запросом файлы аплодятся.
Сентябрь 15th, 2010 at 10:08
даже не так, файлы даже загружается, но в лог пишет ошибку 302, и в див со статусом 302 пишет рядом с каждым файлом.
Октябрь 13th, 2010 at 09:02
Андрей! Удалось побороть ошибку 302? Каким образом?