Yii: Фотогалерея через поведение (доработка расширения imagesgallerymanager)
Для Yii2 это расширение описано тут - http://yiico.ru/blog/501-fotogaleryeya-dlya-yii2-rasshirenie-zxbodya-yii2-gallery-manager
Давненько копилось желание организовать фотогалерею на Yii. Сделал это опираясь на существующие на сегодняшний день расширения для Yii. Так как сам проект начал делать на Yii-app от Chris83, то ожидал как-то использовать yii-imagemanager, который входит в yii-app. Но стало понятно, что оно обрабатывает отдельно фотографии и не предлагает галереи фото.
Попалось расширение от Bogdan Savluk - imagesgallerymanager (на bitbucket). Оно позволяет через поведение подвесить менеджер загрузки (+редактирования информации к фотке) прямо к нужной модели. Несколько доработал это расширение, чтобы фотографии сохранялись на сервере по папкам (название папок формируется по псевдониму записи (можно заменить и на значение любого поля в записи модели) - например, у меня это alias у группы). Папки создаются сами в директории gallery, и при удалении последней картинки из папки, сама папка тоже удаляется.
Устанавливаем сначала imagesgallerymanager (для него понадобится расширение yii-image).
config/main.php
'import' => array( ... 'ext.galleryManager.*', 'ext.galleryManager.models.*', 'ext.image.*', ...
// application components 'components' => array( ... 'image' => array( 'class' => 'application.extensions.image.CImageComponent', // GD or ImageMagick 'driver' => 'GD', // ImageMagick setup path 'params' => array('directory' => '/opt/local/bin'), ),
// controllers mappings 'controllerMap' => array( ... 'image' => array('class' => 'vendor.crisu83.yii-imagemanager.controllers.ImageController'), 'gallery' => array('class' => 'ext.galleryManager.GalleryController'), ),
... public function behaviors() { return array( 'galleryBehavior' => array( 'class' => 'GalleryBehavior', 'idAttribute' => 'gallery_id', 'versions' => array( 'small' => array( 'centeredpreview' => array(200, 200), //array(98, 98), ), 'medium' => array( 'resize' => array(800, null), ) ), 'name' => true, 'description' => true, ) ); } ...
... <h2>Product galley</h2> <?php if ($model->galleryBehavior->getGallery() === null) { echo '<p>Before add photos to product gallery, you need to save product</p>'; } else { $this->widget('GalleryManager', array( 'gallery' => $model->galleryBehavior->getGallery(), 'controllerRoute' => '/gallery' )); } ?> ...
Дорабатываю расширение imagesgallerymanager для сохранения фоток по папкам.
... public function behaviors() { return array( 'galleryBehavior' => array( 'class' => 'GalleryBehavior', 'imagePath' => 'gallery/'.$this->alias, 'idAttribute' => 'gallery_id', 'versions' => array( 'small' => array( 'centeredpreview' => array(200, 200), ), 'medium' => array( 'resize' => array(800, null), ) ), 'name' => true, 'description' => true, ) ); } ...
class GalleryBehavior extends CActiveRecordBehavior
{
/** @var string Model attribute name to store created gallery id */
public $imagePath = ''; // вот она
/** @var string Model attribute name to store created gallery id */
public $idAttribute;
...
class GalleryController extends Controller { public $galleryDir = 'gallery'; public function filters() { ...
public function actionDelete($galleryphotospath = null) // !! id передаётся через POST, а galleryphotospath — через GET { $id = $_POST['id']; //$galleryphotospath = $_POST['galleryphotospath']; /** @var $photos GalleryPhoto[] */ $photos = GalleryPhoto::model()->findAllByPk($id); // foreach ($photos as $photo) { // if ($photo !== null) $photo->delete(); foreach ($photos as $photo) { if ($photo !== null) { $photo->galleryDir = $photo->galleryDir."/".$galleryphotospath; $photo->delete(); } ...
public function actionAjaxUpload($gallery_id = null, $galleryphotospath = null) { $model = new GalleryPhoto(); $model->galleryDir = $model->galleryDir."/".$galleryphotospath; $model->gallery_id = $gallery_id; $imageFile = CUploadedFile::getInstanceByName('image'); $model->file_name = $imageFile->getName(); $model->save(); $this->createDirectory($_SERVER['DOCUMENT_ROOT'].Yii::app()->urlManager->baseUrl. '/' .$model->galleryDir); $model->setImage($imageFile->getTempName()); header("Content-Type: application/json"); echo CJSON::encode( ...
... public $gallerypath; ...
... $photos = array(); foreach ($this->gallery->galleryPhotos as $photo) { $photo->galleryDir = $photo->galleryDir."/".$this->gallerypath; $photos[] = array( 'id' => $photo->id, 'rank' => $photo->rank, 'name' => (string)$photo->name, 'description' => (string)$photo->description, 'preview' => $photo->getPreview(), ); } $opts = array( 'hasName' => $this->gallery->name ? true : false, 'hasDesc' => $this->gallery->description ? true : false, 'uploadUrl' => Yii::app()->createUrl($this->controllerRoute . '/ajaxUpload', array('gallery_id' => $this->gallery->id, 'galleryphotospath' => $this->gallerypath)), 'deleteUrl' => Yii::app()->createUrl($this->controllerRoute . '/delete', array('galleryphotospath' => $this->gallerypath)), 'updateUrl' => Yii::app()->createUrl($this->controllerRoute . '/changeData'), 'arrangeUrl' => Yii::app()->createUrl($this->controllerRoute . '/order'), 'nameLabel' => Yii::t('galleryManager.main', 'Name'), 'descriptionLabel' => Yii::t('galleryManager.main', 'Description'), 'photos' => $photos, ); ...
... public function delete() { $this->removeFile(Yii::getPathOfAlias('webroot') . '/' . $this->galleryDir . '/' . $this->getFileName('') . '.' . $this->galleryExt); $this->removeFile(Yii::getPathOfAlias('webroot') . '/' . $this->galleryDir . '/_' . $this->getFileName('') . '.' . $this->galleryExt); $this->removeImages(); @unlink(Yii::getPathOfAlias('webroot') . '/' .$this->galleryDir. '/.DS_Store');//array_map("unlink", glob(Yii::getPathOfAlias('webroot') . '/' .$this->galleryDir. '/.DS_Store'));// MAC OS X создаёт файл .DS_Store, который мешает удалять папку rmdir, так как она должна быть пустой, чтобы сработала функция rmdir // если в папке gallery/alias_группы нет изображений, то удалять нахрен эту папку if($this->regExpFile("/jpg$/", Yii::getPathOfAlias('webroot') . '/' .$this->galleryDir, $regType='P', $case='') === false) { rmdir(Yii::getPathOfAlias('webroot') . '/' .$this->galleryDir); } return parent::delete(); } ...
function regExpFile($regExp, $dir, $regType='P', $case='') { # Two parameters accepted by $regType are E for ereg* functions # and P for preg* functions $func = ( $regType == 'P' ) ? 'preg_match' : 'ereg' . $case; # Note, technically anything other than P will use ereg* functions; # however, you can specify whether to use ereg or eregi by # declaring $case as "i" to use eregi rather than ereg $open = opendir($dir); while( ($file = readdir($open)) !== false ) { if ( $func($regExp, $file) ) { return true; } } // End while return false; } // End function
// <h2>Product galley</h2> <h2>Фотографии коллектива</h2> <?php if ($model->galleryBehavior->getGallery() === null) { echo '<p>Before add photos to product gallery, you need to save product</p>'; } else { $this->widget('GalleryManager', array( 'gallery' => $model->galleryBehavior->getGallery(), 'controllerRoute' => '/gallery', 'gallerypath' => $model->alias, )); } ?>
-- ----------------------------------------------------- -- Table `tbl_gallery` -- ----------------------------------------------------- CREATE TABLE IF NOT EXISTS `tbl_gallery` ( `id` INT NOT NULL AUTO_INCREMENT , `versions_data` TEXT NOT NULL , `name` TINYINT(1) NOT NULL DEFAULT 1 , `description` TINYINT(1) NOT NULL DEFAULT 1 , PRIMARY KEY (`id`) ) ENGINE = InnoDB; -- ----------------------------------------------------- -- Table `tbl_gallery_photo` -- ----------------------------------------------------- CREATE TABLE IF NOT EXISTS `tbl_gallery_photo` ( `id` INT NOT NULL AUTO_INCREMENT , `gallery_id` INT NOT NULL , `rank` INT NOT NULL DEFAULT 0 , `name` VARCHAR(512) NOT NULL DEFAULT '', `description` TEXT NULL, `file_name` VARCHAR(128) NOT NULL DEFAULT '', PRIMARY KEY (`id`) , INDEX `fk_gallery_photo_gallery1` (`gallery_id` ASC) , CONSTRAINT `fk_gallery_photo_gallery1` FOREIGN KEY (`gallery_id` ) REFERENCES `tbl_gallery` (`id` ) ON DELETE NO ACTION ON UPDATE NO ACTION) ENGINE = InnoDB;
А теперь выводим галерею на странице группы (тоже через поведение)
<?php css('css/colorbox.css'); ?> <?//php Yii::app()->clientScript->registerCssFile(Yii::app()->request->baseUrl . "/css/colorbox.css", CClientScript::POS_END); ?> <?php js('js/jquery.colorbox-min.js'); ?>
<script> jQuery(document).ready(function () { jQuery('a.gallery').colorbox({ opacity:0.5 , rel:'group1', loop:false }); jQuery('a.<?php echo $model->alias;?>').colorbox({ opacity:0.5 , rel:'group1', loop:false }); }); </script>
...
<?php if(isset($model->gallery_id) && $model->gallery_id != "0") : ?>
<section id="photo">
<h3>Фото</h3>
<?php
$this->widget('GalleryViewer', array(
'gallery' => $model->galleryBehavior->getGallery(),
'controllerRoute' => '/gallery',
'gallerypath' => $model->alias,
));
?>
</section>
<?php endif; ?>
...
<?php class GalleryViewer extends CWidget { /** @var Gallery Model of gallery to manage */ public $gallery; /** @var string Route to gallery controller */ public $controllerRoute = false; public $assets; public $gallerypath; public $htmlOptions = array(); /** Render widget */ public function run() { /** @var $cs CClientScript */ $photos = array(); foreach ($this->gallery->galleryPhotos as $photo) { $photo->galleryDir = $photo->galleryDir."/".$this->gallerypath; /*$photos[] = array( 'id' => $photo->id, 'rank' => $photo->rank, 'name' => (string)$photo->name, 'description' => (string)$photo->description, 'preview' => $photo->getPreview(), );*/ } $this->render('galleryViewer', array('photos'=>$this->gallery->galleryPhotos, 'groupalias'=>$this->gallerypath)); } }
<ul class="thumbnails"> <?php foreach($photos as $photo): ?> <li class="span3"><a class="<?php echo $groupalias; ?> thumbnail" href="<?php echo $photo->url; ?>"><img src="<?php echo $photo->getUrl("small"); ?>" alt="<?php echo $photo->name; ?>" /></a></li> <?php endforeach; ?> </ul>
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)
2 комментариев
Спасибо Вам, что поделились своим кодом - как раз собирался переделывать галерею под Yii .
Если не сложно, уточните по расширению image
У вас в коде упоминается два (от z_bodya и crisu83 )причем первый объявлен компонентом, а второй указан в controllerMap
Заранее благодарен, Александр.