вторник, 27 августа 2013 г.

Предобработка картинок в административной панели (фреймворк Yii).

Сразу же оговорюсь, что ниженаписанное тестировалось только для Yii версии 1.1.2, поскольку сайт я делаю в процессе изучения этой книги (на момент ее публикации эта версия была последней).

Задача: реализовать возможность в административной панели приложения при редактировании страницы новости загружать фотографии и позволить их обрезать под нужный размер перед сохранением на сервере. Вот что должно получиться:



Решение.

1. Подключение необходимых библиотек
Нам помогут три библиотеки: imgAreaSelectWideImagejquery.form. Первая библиотека требует более нового jQuery, который поставляется с Yii, поэтому также пришлось отключать "старый" jQuery и  подключать "новый". Для этого в /protected/config/main.php под 'components' напишем следующее:
Далее, в /protected/views/layouts/main.php напишем следующее:
Вот мы и подключили нужную версию jQuery и заодно imgAreaSelect. WideImage будем подключать "на лету" прямо в контроллере. 
2. Изменение модели
Объявляем переменные (photo - ссылка на файл-картинку, остальные переменные - координаты обрезания картинки). У меня модель находится в файле /protected/models/News.php):
В этом же файле изменяем функцию rules (в ней прописываются правила, которым должны удовлетворять данные, вносимые в форму):
3. Изменение формы
В форме редактирования страницы (у меня это файл /protected/views/news/_form.php)  убираем текстовое поле Picture, где хранится путь к файлу и добавляем кнопку выбора файла:
Также добавляем место, куда будем подгружать картинку для предпросмотра и переменные, где будем хранить сведения о координатах для обрезки картинки и о пути к загруженному файлу:
В самый верх файла добавляем скрипты. Они делают следующее.
После выбора пользователем файла, он отправляется на сервер, где файл сохраняется в папке tmp, обратно приходит ссылка на него. Далее в область предпросмотра подгружается картинка из присланной ссылки. Подключается к работе плагин imgAreaSelect. При изменении параметров обрезки картинки  в скрытых данных формы сохраняются координаты обрезки. Эти скрытые данные будут также переданы при нажатии на кнопку "Отправить". Кстати, за возможность отправки файла без перезагрузки страницы стоит поблагодарить плагин jquery.form, у него есть полезнейший метод ajaxSubmit. Оказалось, что просто так без перезагрузки страницы файл на сервер не отправить (из соображений безопасности). Вот этот плагин и выручил.
4. Изменение контроллера
В контроллере (у меня это файл /protected/controllers/NewsController.php) изменяем функцию accessRules - для того, чтобы разрешить пользователям сайта запускать функцию preview (функция preview сохраняет выбранный файл в папку tmp и передает на клиент ссылку на него):
А вот и сама функция preview:
Она такая большая, потому что выполняет кучу проверок - на формат файла, на размер, и т.д. Генерирует уникальное имя файла, зависящее от времени загрузки, ужимает до макс. 600 px по ширине и высоте, сохраняет файл в папку tmp и сообщает клиенту его адрес.

А вот функция создания новости (вызывается, когда на клиенте нажимается кнопка "Отправить"). Как видим, перед сохранением новости производится обрезка изображения по координатам, выбранным пользователем. Кстати, функция обновления новости видоизменяется аналогично.

1 комментарий: