Как загрузить/обновить" изображение к тикету?
Приветствую!
Стояла задача: при создании тикета из фронтенда загружать главное изображение, которое будет использоваться в превью и отображаться на странице самого тикета в начале.
В качестве решения можно было бы использовать, например, первое изображение из встроенной загрузки файлов для тикета, но желание экспериментировать перебороло.
Кратко:
1. В форму создания тикета добавляем поле input type=«file»
2. Создаем плагин на событие сохранения формы с загрузкой и изменением размеров изображения.
Итак:
1. На всякий случай создаем копию чанка tpl.Tickets.form.create и редактируем его.
2. Форме создания тикета добавляем аттрибут enctype=«multipart/form-data», т.к. будем загружать файлы:
4. Создаем текстовое ТВ-поле для хранения имени изображения. Назовем его srcImg. Не забываем указать доступы для шаблонов страниц создания и вывода тикета.
5. Создаем в корне сайта папку imgTickets, а в ней папки user_uploads и tmp.
6. Создаем новый плагин, назовем его ImgTicketsNew, который будет загружать изображение в папку imgTickets/tmp/, создавать копию изображения с новыми размерами в папке imgTickets/user_uploads/ и удалять оригинал изображения.
8. В шаблоне вывода тикета добавляем:
Все работает, но есть небольшие проблемы:
{решено} 1. При загрузке изображения с расширением .png, прозрачный фон заменяется на черный.
2. При создании тикета и добавлении фото с телефона, фото получается перевернутым из-за вертикальной съемки, нужно ориентацию картинки как то отслеживать, либо организовывать редактирование фото перед загрузкой.
Стояла задача: при создании тикета из фронтенда загружать главное изображение, которое будет использоваться в превью и отображаться на странице самого тикета в начале.
В качестве решения можно было бы использовать, например, первое изображение из встроенной загрузки файлов для тикета, но желание экспериментировать перебороло.
Кратко:
1. В форму создания тикета добавляем поле input type=«file»
2. Создаем плагин на событие сохранения формы с загрузкой и изменением размеров изображения.
Итак:
1. На всякий случай создаем копию чанка tpl.Tickets.form.create и редактируем его.
2. Форме создания тикета добавляем аттрибут enctype=«multipart/form-data», т.к. будем загружать файлы:
<form class="well create" method="post" action="" id="ticketForm" enctype="multipart/form-data">
3. Внутри самой формы добавляем поле для загрузки изображения. Я сделал так: <div class="form-group">
<label for="ticket-photo">Изображение</label>
<input type="file" class="form-control" name="photo"/>
<span class="error" id="error_ticketphoto"></span>
</div>
Сохраняем. Все, с редактированием чанка tpl.Tickets.form.create закончили.4. Создаем текстовое ТВ-поле для хранения имени изображения. Назовем его srcImg. Не забываем указать доступы для шаблонов страниц создания и вывода тикета.
5. Создаем в корне сайта папку imgTickets, а в ней папки user_uploads и tmp.
6. Создаем новый плагин, назовем его ImgTicketsNew, который будет загружать изображение в папку imgTickets/tmp/, создавать копию изображения с новыми размерами в папке imgTickets/user_uploads/ и удалять оригинал изображения.
if ($modx->event->name == 'OnDocFormSave') {
if($mode == 'new'){
if (!empty($_FILES)) {
$id = $resource->get('id');
$folder = 'imgTickets/user_uploads/'; //Папка с загруженными изображениями
$path = MODX_BASE_PATH.$folder; // Путь от корня до нужного места
$tmp_path = MODX_BASE_PATH.'imgTickets/tmp/';
$tv_name = 'srcImg'; // имя текстовой тв для изображения
// все значения файла
$nameFile = $_FILES['photo']['name'];
$typeFile = $_FILES['photo']['type'];
$tmpNameFile = $_FILES['photo']['tmp_name'];
$sizeFile = $_FILES['photo']['size'];
$limit_size = 5*1024*1024; // 5 Mb - максимальный размер загружаемого файла
$max_width = 800;
$extensionFile = substr(strrchr($nameFile, '.'), 1); // получаем расширение файла
// новое имя файла
$NewNameFile = 'id_'.$id.'_'.date("m_d_y").'.'.$extensionFile;
$filename = $tmp_path.$NewNameFile;
// проверяем зашёл ли файл и подходит ли его размер
if(is_uploaded_file($tmpNameFile) and $sizeFile <= $limit_size) {
// тип содержимого
header('Content-Type: '.$typeFile);
// загружаем файл
move_uploaded_file($tmpNameFile, $filename);
if ($typeFile == 'image/jpeg')
$image = imagecreatefromjpeg($filename);
elseif ($typeFile == 'image/png')
$image = imagecreatefrompng($filename);
elseif ($typeFile == 'image/gif')
$image = imagecreatefromgif($filename);
else
return false;
list($width, $height) = getimagesize($filename);
if ($width > $max_width) {
// получение новых размеров
$ratio = $width/$max_width;
$new_width = round($width/$ratio);
$new_height = round($height/$ratio);
// ресэмплирование
$image_p = imagecreatetruecolor($new_width, $new_height);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
// сохраняем изображение в папку
imagejpeg($image_p, $path.$NewNameFile, 100);
// записываем в наш тв
$resource->setTVValue($tv_name, $folder.$NewNameFile);
}
// если картинку уменьшать не нужно
else {
// копируем изображение в папку
copy($tmp_path.$NewNameFile, $path.$NewNameFile);
// записываем в наш тв
$resource->setTVValue($tv_name, $folder.$NewNameFile);
}
// Очищаем память
imagedestroy($image);
// Удаляем временный файл (закомментируйте строку, если не хотите удалять оригиналы изображений)
unlink($tmp_path.$NewNameFile);
}
}
}
}
7. Не забываем в настройках плагина поставить галочку во вкладке Системные событияна OnDocFormSave. Сохраняем.8. В шаблоне вывода тикета добавляем:
[[*srcImg:notempty=<img style="padding:15px; margin: 0 auto; max-width:100%" class="media-object" src="[[*srcImg]]" alt="[[*pagetitle]]" title="[[*pagetitle]]">`]]
Все работает, но есть небольшие проблемы:
{решено} 1. При загрузке изображения с расширением .png, прозрачный фон заменяется на черный.
2. При создании тикета и добавлении фото с телефона, фото получается перевернутым из-за вертикальной съемки, нужно ориентацию картинки как то отслеживать, либо организовывать редактирование фото перед загрузкой.
Поблагодарить автора
Отправить деньги
Комментарии: 4
Проблема № 1 При загрузке изображения с расширением .png, прозрачный фон заменяется на черный. решена!
При ресемплировании выключаем режим сопряжения цветов и включаем сохранение альфаканала:
При ресемплировании выключаем режим сопряжения цветов и включаем сохранение альфаканала:
//Отключаем режим сопряжения цветов
imagealphablending($image_p, false);
//Включаем сохранение альфа канала
imagesavealpha($image_p, true);
И в зависимости от расширения исходного файла сохраняем изображение:// сохраняем изображение в папку
if ($typeFile == 'image/jpeg')
imagejpeg($image_p, $path.$NewNameFile, 100);
elseif ($typeFile == 'image/png')
imagepng($image_p, $path.$NewNameFile);
else
return false;
Чтобы ввесь код сюда не копировать, замените условие if ($width > $max_width) {...} на следующее:if ($width > $max_width) {
// получение новых размеров
$ratio = $width/$max_width;
$new_width = round($width/$ratio);
$new_height = round($height/$ratio);
// ресэмплирование
$image_p = imagecreatetruecolor($new_width, $new_height);
//Отключаем режим сопряжения цветов
imagealphablending($image_p, false);
//Включаем сохранение альфа канала
imagesavealpha($image_p, true);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
// сохраняем изображение в папку
if ($typeFile == 'image/jpeg')
imagejpeg($image_p, $path.$NewNameFile, 100);
elseif ($typeFile == 'image/png')
imagepng($image_p, $path.$NewNameFile);
else
return false;
// записываем в поле photo
$profile->set('photo', $folder.$NewNameFile);
$profile->save();
}
Нашел ошибку! Нужно
// записываем в поле photo
$profile->set('photo', $folder.$NewNameFile);
$profile->save();
Заменить на // записываем в наш тв
$resource->setTVValue($tv_name, $folder.$NewNameFile);
А как плагин ведет себя при обновлении тикета?
Просто я заменил в Вашем плагине строку
Но в моем случае затирается ранее загруженное изображение…
Не подскажете?
if($mode == 'new'){...
на
if($mode == 'new' || $mode == 'upd' && $resource->class_key == "Ticket"){...
По идее, при обновлении тикета, если не изменяется изображение, то ни чего с ним и не должно происходить?Но в моем случае затирается ранее загруженное изображение…
Не подскажете?
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.