Загрузка картинок с преобразованием размера в Yii через форму. Продолжение.
В предыдушей статье про загрузку файлов изображений в Yii к материалу мы немножно слукавили, то есть умолчали о некоторых недостатках. Тогда целью было сделать удобную возможность загрузки картинок с автоматическим переименовыванием файла картинки, а также удаление картинки (из поля базы и с сервера). И эта цель успешно была достигнута. Но мы не ресайзили картинку, в то время как отображается она только как превьюшка шириной 150px. А вдруг сама картинка - 1000 или 2000 px? Мы поставили в правилах только ограничение на загрузку картинки по весу - до 5 Mb.
Сегодня дорабатываем наш алгоритм загрузки картинкок в Yii:
- Научим картинку сохраняться в 3 вариантах - маленькая (50px по длинной стороне), превьюшка (шириной 200px), большая (800px по длинной стороне);
- Оставляем нерешённой на следующий раз ошибку с отсутствием папки для сохранения (нужно просто дописать проверку существует ли такая папка и если не существует, то создать её);
- Перепишем функцию показа картинки - будет картинкой-превью ссылкой на подробную новость, либо большой картинкой в новости (не ссылка!!)
- Добавим колонку картинок (маленьких, тех что уменьшатся до 50px) в интерфейсе администратора, то есть в списке, выводимом с помощью CGridView в экшне admin контроллера Post (Post.admin)
public function actionCreate() { $model=new Post; // Uncomment the following line if AJAX validation is needed // $this->performAjaxValidation($model); if(isset($_POST['Post'])) //Если пользователь отослал данные { $model->attributes=$_POST['Post']; //Заполнить модель данными присланными пользователем $model->icon=CUploadedFile::getInstance($model,'icon'); //Атрибуту icon присвоить указатель на загружаемый файл if ($model->icon){ $sourcePath = pathinfo($model->icon->getName()); $fileName = substr($model->time_start, 5, 5).'-'.$model->alias.'.'.$sourcePath['extension']; $model->image = $fileName; } if($model->save()){ //Если поле загрузки файла не было пустым, то if ($model->icon){ //сохранить файл на сервере в каталог images/2011 под именем //month-day-alias.jpg $file = $_SERVER['DOCUMENT_ROOT'].Yii::app()->urlManager->baseUrl.'/images/'.substr($model->time_start, 0, 4).'/'.$fileName; //Переменной $file присвоить путь, куда сохранится картинка без изменений $model->icon->saveAs($file); //Используем функции расширения CImageHandler; $ih = new CImageHandler(); //Инициализация Yii::app()->ih ->load($file) //Загрузка оригинала картинки ->thumb('200', false) //Создание превьюшки шириной 200px ->save($_SERVER['DOCUMENT_ROOT'].Yii::app()->urlManager->baseUrl.'/images/'.substr($model->time_start, 0, 4).'/thumbs/'.$fileName) //Сохранение превьюшки в папку thumbs ->reload() //Снова загрузка оригинала картинки ->thumb('50', '50') //Создание превьюшки размером 50px ->save($_SERVER['DOCUMENT_ROOT'].Yii::app()->urlManager->baseUrl.'/images/'.substr($model->time_start, 0, 4).'/thumbs_small/'.$fileName) //Сохранение превьюшки в папку thumbs_small ->reload()//Снова загрузка оригинала картинки ->thumb('800', '800') //Создание превьюшки размером 800px ->save($_SERVER['DOCUMENT_ROOT'].Yii::app()->urlManager->baseUrl.'/images/'.substr($model->time_start, 0, 4).'/'.$fileName) //Сохранение большой картинки в папку ; } $this->redirect(array('view','id'=>$model->id)); } } $this->render('create',array( 'model'=>$model, )); }
public function actionUpdate() { $model=$this->loadModel(); if(isset($_POST['Post'])) { $model->attributes=$_POST['Post']; $model->icon=CUploadedFile::getInstance($model,'icon'); if ($model->icon){ $sourcePath = pathinfo($model->icon->getName()); $fileName = substr($model->time_start, 5, 5).'-'.$model->alias.'.'.$sourcePath['extension']; $model->image = $fileName; } if($model->save()){ if($model->del_img) //Если отмечен чекбокс «удалить файл» { if(file_exists($_SERVER['DOCUMENT_ROOT'].Yii::app()->urlManager->baseUrl.'/images/'.substr($model->time_start, 0, 4).'/'.$model->image)) { //удаляем картинку и все её thumbs @unlink('./images/'.substr($model->time_start, 0, 4).'/'.$model->image); @unlink('./images/'.substr($model->time_start, 0, 4).'/thumbs/'.$model->image); @unlink('./images/'.substr($model->time_start, 0, 4).'/thumbs_small/'.$model->image); $model->image = ''; } } //Если поле загрузки файла не было пустым, то if ($model->icon){ $file = './images/'.mb_substr($model->time_start, 0, 4, 'UTF-8').'/'.$fileName; $model->icon->saveAs($file); //сохранить файл на сервере под именем 12-03-alias.jpg Если файл с таким именем существует, он будет заменен. //Как в actionCreate - используем функции расширения CImageHandler; $ih = new CImageHandler(); //Инициализация Yii::app()->ih ->load($file) //Загрузка оригинала картинки ->thumb('200', false) //Создание превьюшки шириной 200px ->save($_SERVER['DOCUMENT_ROOT'].Yii::app()->urlManager->baseUrl.'/images/'.substr($model->time_start, 0, 4).'/thumbs/'.$fileName) //Сохранение превьюшки в папку thumbs ->reload() //Снова загрузка оригинала картинки ->thumb('50', '50') //Создание превьюшки размером 50px ->save($_SERVER['DOCUMENT_ROOT'].Yii::app()->urlManager->baseUrl.'/images/'.substr($model->time_start, 0, 4).'/thumbs_small/'.$fileName) //Сохранение превьюшки в папку thumbs_small ->reload()//Снова загрузка оригинала картинки ->thumb('800', '800') //Создание превьюшки размером 800px ->save($_SERVER['DOCUMENT_ROOT'].Yii::app()->urlManager->baseUrl.'/images/'.substr($model->time_start, 0, 4).'/'.$fileName) //Сохранение большой картинки в папку ; } $this->redirect(array('view','id'=>$model->id)); } } $this->render('update',array( 'model'=>$model, )); }
// application components 'components'=>array( 'ih'=>array('class'=>'CImageHandler'), 'user'=>array(...
<?php $this->breadcrumbs=array( 'Manage Posts', ); ?> <h1>Manage Posts</h1> <?php $this->widget('zii.widgets.grid.CGridView', array( 'id'=>'posts-grid', 'dataProvider'=>$model->search(), 'filter'=>$model, 'columns'=>array( array( 'name'=>'id', 'headerHtmlOptions'=>array('width'=>'50px') ), array( 'name'=>'title', 'type'=>'raw', 'value'=>'CHtml::link(CHtml::encode($data->title), $data->url)' ), array( 'name'=>'image', 'type'=>'image', //если файла картинки нет, // то отображается файл noeventimage.png // Значение value обрабатывается функцией eval() поэтому // одинарные ковычки. 'value'=> 'file_exists($_SERVER["DOCUMENT_ROOT"].Yii::app()->urlManager->baseUrl."/images/".substr($data->time_start, 0, 4)."/thumbs_small/".$data->image) ? Yii::app()->urlManager->baseUrl."/images/".substr($data->time_start, 0, 4)."/thumbs_small/".$data->image : Yii::app()->urlManager->baseUrl."/css/noeventimage.png"', 'filter'=>'', 'headerHtmlOptions'=>array('width'=>'54px'), ), ... array( 'name'=>'status', 'value'=>'Lookup::item("PostStatus",$data->status)', 'filter'=>Lookup::items('PostStatus'), ), array( 'name'=>'create_time', //'type'=>'datetime', 'filter'=>false, ), array( 'class'=>'CButtonColumn', ), ), )); ?>
public function event_image($id, $create_year, $alias, $title, $image, $class='material_img',$link=null,$target='_self') { if(isset($image) && file_exists($_SERVER['DOCUMENT_ROOT'].Yii::app()->urlManager->baseUrl.'/images/'.$create_year.'/'.$image)) { if ($link) return CHTML::link( CHtml::image(Yii::app()->getBaseUrl(true).'/images/'.$create_year.'/thumbs/'.$image, $title, array( 'class'=>$class, ) ), $link, array('target'=>$target,) ); else return CHtml::image(Yii::app()->getBaseUrl(true).'/images/'.$create_year.'/'.$image, $title, array( 'class'=>$class, )); } else return CHtml::image(Yii::app()->urlManager->baseUrl.'/css/noeventimage.png','Нет картинки', array( 'class'=>$class )); }
Используется эта функция в отображении /protected/views/post/_view.php (выводит картинку-ссылку)
<div><p><?php echo $this->event_image($data->id, substr($data->time_start, 0, 4), $data->alias, $data->title, $data->image, 'small_img left', $data->url);?></p></div>
<div><?php echo $this->event_image($data->id, mb_substr($data->time_start, 0, 4, 'UTF-8'), $data->alias, $data->title, $data->image);?></div>
almix
Разработчик Loco, автор статей по веб-разработке на Yii, CodeIgniter, MODx и прочих инструментах. Создатель Team Sense.
Вы можете почитать все статьи от almix'а.
- 14 Разработка приложения на Yii. Урок 14: Выводим список категорий как новый виджет на сайте (29.04.2015)
- 13 Разработка приложения на Yii. Урок 13: Внедряем категории для статей. (29.04.2015)
- 12 Разработка приложения на Yii. Урок 12: Профилирование приложения, включаем кеширование. (20.01.2015)
- 11 Yiico. Видеокурс по разработке сайта на Yii. Урок 11: Отладка приложения, включаем журналирование. (20.01.2015)
- 10 Yiico. Видеокурс по разработке сайта на Yii. Урок 10: Если ваше приложение находится не в корневой папке, а во вложенной. (19.10.2014)
- 9 Разработка сайта на Yii с нуля. Урок 9. Выборка статей определённого автора. (13.08.2014)
- 8 Разработка сайта на Yii с нуля. Урок 8. Вызов в моделях функции, общей для них. Как избегать дублирования кода? (25.07.2014)
- 7 Разработка сайта на Yii с нуля. Урок 7. Изменение количества выводимых записей на странице в CGridView. Включаем сессии Yii. (04.09.2013)
- 6 Разработка сайта на Yii с нуля. Урок 6. Автоматич. отправка оповещений об одобренных комментариях на email автора комментария (11.08.2013)
- 5 Разработка сайта на Yii с нуля. Урок 5. Переименовываем blog в yiico. Изменяем "Home" в breadcrumbs. Включаем Gzip-сжатие. (09.08.2013)
- 4 Курс по Yii с нуля. Урок 4. Дорабатываем простую работу с пользователями: хранение пароля при редактировании пользователя. (13.04.2013)
- 3 Курс по Yii с нуля. Урок 3. Создаём новых пользователей. Организуем простую систему авторизации. Аутентификация, пароли, соли. (20.07.2014)
- 2 Yii + Git (github) на Mac. (24.03.2013)
- 2 Курс по Yii с нуля. Урок 2. Переносим и настраиваем Yii и проект нашего сайта на рабочем сервере. Избавляемся от index.php в url (09.07.2014)
- 1 Курс по Yii с нуля. Урок 1. Устанавливаем Yii на локальном компьютере. Заводим проект будущего сайта. (10.03.2013)
- 0 Composer – пакетный менеджер PHP. Что и как? (22.07.2014)
- 0 MySQL: проверить содержится ли значение в поле столбца (в столбце хранится строка значений через запятую) (22.05.2014)
- 0 Yii: Статичные страницы (создание, редактирование, удаление) (28.04.2014)
- 0 Yii: Расширение ECKEditor = Связка ckeditor + kcfinder (визуальный редактор с бесплатным файловым менеджером) (28.04.2014)
- 0 Yii: Bootstrap tabs, делаем активной вкладку на которую выполняется переход по ссылке (20.03.2014)
- 0 Yii: Доступ к атрибуту модели из файла шаблона (Вызов в шаблоне какого-либо атрибута модели). (17.02.2014)
- 0 Yii: Множественный автокомплит с помощью CJuiAutoComplete (автокомплит нескольких значений в одно поле) (07.02.2014)
- 0 Yii: Фотогалерея через поведение (доработка расширения imagesgallerymanager) (08.03.2016)
- 0 Yii: Установка и настройка Yii-app заготовки приложения от Crisu83 (09.03.2014)
- 0 Twitter Bootstrap Carousel Crossfade (09.09.2013)
5 комментариев
@unlink('./images/'.substr($model->time_start, 0, 4).'/'.$model->image); тоесть удаляем только что сохраненную в базу картинку, еще до ее загрузки, а старое изображение остается прежним. и честно говоря не увидел где мы проверяем на существование каталога для сохранения файлов.
Вместо:
$_SERVER["DOCUMENT_ROOT"].Yii::app()->urlManager->baseUrl."/images/"
правильнее использовать:
Yii::getPathOfAlias('images.uploads');