Создаем папку для загрузки. Разместим ее в корне www/photos.
Создаем таблицы в БД
DROP TABLE IF EXISTS `cm_photos`;
CREATE TABLE `cm_photos` (
`id` INT(10) NOT NULL DEFAULT '0',
`title` VARCHAR(255) DEFAULT NULL,
`description` text,
`cat` INT(10) DEFAULT NULL,
`link` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `cm_photo_cat`;
CREATE TABLE `cm_photo_cat` (
`id` INT(10) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Для каждой таблицы в БД создадим файл модели (mdl_photo_cat и mdl_photos). Эти файлы можно посмотреть, скачав результат в конце урока. В них просто описаны правила валидации при добавлении и редактировании.
Теперь нам надо подробней рассмотреть процесс загузки фотографии, чтобы мы смогли реализовать его в программе.
Я использовал такую схему:
Приводить весь листинг модулей здесь я не буду. Опишу основные моменты:
Загрузка файлов фотографий реализована через jQuery Multiple File Upload Plugin. Для его использования подключаем в шапке скрипты
<script type="text/javascript" src="<?=base_url();?>js/jquery-1.3.1.min.js"></script>
<script type="text/javascript" src="<?=base_url();?>js/upload/jquery.MultiFile.js"></script>
<script type="text/javascript" src="<?=base_url();?>js/upload/jquery.form.js"></script>
<script type="text/javascript" src="<?=base_url();?>js/upload/jquery.blockUI.js"></script>
Вот так выглядит файл вида upload.php
<script type="text/javascript">
$(document).ready(function(){
$('.MultiFile').MultiFile({
accept:'jpg|gif|bmp|png|rar', max:15, STRING: {
remove:'удалить',
file:'$file',
selected:'Выбраны: $file',
denied:'Неверный тип файла: $ext!',
duplicate:'Этот файл уже выбран:\n$file!',
maxlength:1
}
});
$("#loading").ajaxStart(function(){
$(this).show();
})
.ajaxComplete(function(){
$(this).hide();
});
$('#uploadForm').ajaxForm({
beforeSubmit: function(a,f,o) {
o.dataType = "html";
$('#uploadOutput').html('Submitting...');
},
success: function(data) {
var $out = $('#uploadOutput');
//$out.html('Form success handler received: <strong>' + typeof data + '</strong>');
if (typeof data == 'object' && data.nodeType)
data = elementToString(data.documentElement, true);
else if (typeof data == 'object')
data = objToString(data);
$out.append('<div>'+ data +'</div>');
document.getElementById('wind').style.display='none';
}
});
});
</script>
<div id="wind">
<h2>Загрузка фотографий</h2>
<form id="uploadForm" action="<?=base_url();?>admin/photos/doajaxfileupload" method="post" enctype="multipart/form-data"> <input name="MAX_FILE_SIZE" value="1000000" type="hidden"/>
File: <input name="fileToUpload[]" id="fileToUpload" class="multi" maxlength="1" type="file" />
<input value="Загрузить" type="submit"/>
</form>
<img id="loading" src="<?=base_url();?>loading.gif" style="display:none;"/>
</div>
<div id="uploadOutput"></div>
В нем мы имеем:
Скрипт для отправки и обработки AJAX запроса на сервер
Форму id=»uploadForm» Для выбора загружаемых файлов.
Див куда будет загружен вид photo для последующего добавления к фотографии описания, названия, категории. После этого отправка на валидацию и добавление в базу.
Приведу здесь функцию которая обрабатывает AJAX запрос с именем файла, загружает файл и возвращает ответ в DIV uploadOutput.
function doajaxfileupload()
{
$error = "";
$msg = "";
$fileElementName = 'fileToUpload';
$i = 0;
$files_count = sizeof($_FILES[$fileElementName]["name"]);
for ($i = 0; $i < $files_count - 1; $i++) {
if (!empty($_FILES[$fileElementName]['error'][$i])) {
switch ($_FILES[$fileElementName]['error'][$i]) {
case '1':
$error = 'размер загруженного файла превышает размер установленный параметром upload_max_filesize в php.ini ';
break;
case '2':
$error = 'размер загруженного файла превышает размер установленный параметром MAX_FILE_SIZE в HTML форме. ';
break;
case '3':
$error = 'загружена только часть файла ';
break;
case '4':
$error = 'файл не был загружен (Пользователь в форме указал неверный путь к файлу). ';
break;
case '6':
$error = 'неверная временная дирректория';
break;
case '7':
$error = 'ошибка записи файла на диск';
break;
case '8':
$error = 'загрузка файла прервана';
break;
case '999':
default:
$error = 'No error code avaiable';
}
} elseif (empty($_FILES[$fileElementName]['tmp_name'][$i]) || $_FILES[$fileElementName]['tmp_name'][$i] ==
'none') {
$error = 'No file was uploaded..';
} else {
if (file_exists("photos/" . $_FILES[$fileElementName]['name'][$i])) {
$error = $_FILES[$fileElementName]['name'][$i] . " уже существует. ";
} else {
$msg .= " File Name: " . $_FILES[$fileElementName]['name'][$i] . "<br/>";
$msg .= " File Type: " . $_FILES[$fileElementName]['type'][$i] . "<br/>";
$msg .= " File Size: " . (@filesize($_FILES[$fileElementName]['tmp_name'][$i]) /
1024) . "Kb";
move_uploaded_file($_FILES[$fileElementName]['tmp_name'][$i], "photos/" . $_FILES[$fileElementName]['name'][$i]);
$this->resize("photos/" . $_FILES[$fileElementName]['name'][$i], 150,
"photos/sm_" . $_FILES[$fileElementName]['name'][$i]);
$this->resize("photos/" . $_FILES[$fileElementName]['name'][$i], 640, "photos/" .
$_FILES[$fileElementName]['name'][$i]);
}
//for security reason, we force to remove all uploaded file
@unlink($_FILES[$fileElementName][$i]);
}
//Подготовка ответа
$CI = &get_instance();
$data = array();
$data['validation_errors'] = validation_errors();
$data['type'] = 'add';
$CI->load->model('mdl_photo_cat');
$data['list_cat'] = $CI->mdl_photo_cat->getlist();
$data['error'] = $error;
$data['upload'] = 'ok';
$data['one']['link'] = $_FILES[$fileElementName]['name'][$i];
//отправка AJAX ответа
$this->load->view('admin/photo', $data);
}
Также здесь видно что после загрузки используется функция $this->resize. Этафункция позволяет изменить размер файла картинки средствами PHP. Как нетрудно заметить во время загрузки мы делаем ресайз основной фотографии и создаем миниатюру с шириной 150 pх.
Стоит обратить внимание на файл вида photo. Этот файл вида может быть вызвани из трех мест: функции обработки AJAX запроса, функции добавления (если не прошла валидация) и функции редактирования. В зависимости от того откуда он вызван будет меняться вывод. Для этого в файле вида есть две переменные: $type со значениями add (добавление) и edit (редактирование) и переменная $upload принимающая значение ‘ok’, если вид вызван из функции обработки загрузки файла doajaxfileupload.
В контроллере photos кроме вышеописанных функций и стандартных функции получения списка, добавления, редактирования и удаления, имеется функция clear_photos(). Эта функция удаляет все загруженные фотографии которых нет в базе. Т.к. может получиться ситуация, когда пользователь начнет загружать фотографию (физически она загрузиться и будет показана в форме добавления), но не добавит ее в базу.