Маленькое резюме- текущая статья устарела в начале 2018 года, когда переписали это расширение. здесь можно взять общую организацию проекта. Я как автор опасаюсь, что вас веду в заблуждение. Если я опять возьмусь за разработку на Yii2- обязательно скорректирую эту статью, но с новым кодом. Если у вас есть конкретные корректировки- присылайте, я буду благодарен и будут благодарны многочисленные читатели этой статьи.
——————
Это настройки в файл web
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
'components' => [ .... // компонет рисунков 'yii2images' => [ 'class' => 'rico\yii2images\Module', //be sure, that permissions ok //if you cant avoid permission errors you have to create "images" folder in web root manually and set 777 permissions 'imagesStorePath' => 'upload/store', //path to origin images 'imagesCachePath' => 'upload/cache', //path to resized copies 'graphicsLibrary' => 'GD', //but really its better to use 'Imagick' 'placeHolderPath' => '@webroot/upload/store/no-image.png', // if you want to get placeholder when image not exists, string will be processed by Yii::getAlias ], ..... ], |
То что надо добавить в модель
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
class Reshenie extends \yii\db\ActiveRecord { public $image; public $gallery; .... public function behaviors() { return [ 'image' => [ 'class' => 'rico\yii2images\behaviors\ImageBehave', ], ..... ]; } public function rules() { return [ ........ [['image'], 'file', 'extensions' => 'png, jpg'], [['gallery'], 'file', 'extensions' => 'png, jpg', 'maxFiles' => 4], ]; } ....... // Две вспомогательные функции для сохранения всего и сразу. Смотри контроллер Create - используются там. public function upload(){ if($this->validate()){ $path = 'upload/store/' . $this->image->baseName . '.' . $this->image->extension; $this->image->saveAs($path); $this->attachImage($path, true); @unlink($path); return true; }else{ return false; } } public function uploadGallery(){ // сохраняет целиком галерею if($this->validate()){ foreach($this->gallery as $file){ $path = 'upload/store/' . $file->baseName . '.' . $file->extension; $file->saveAs($path); $this->attachImage($path); @unlink($path); } return true; }else{ return false; } } |
вывод всех картинок (для fanibox) (во view)
1 2 3 4 5 6 7 8 9 10 11 12 |
<?php use yii\helpers\Html; $img = $model->getImage(); $gallery = $model->getImages(); $img_str=''; foreach($gallery as $img2){ $img_str.='<a class="fancybox img-thumbnail" rel="gallery1" href="'. $img2->getUrl().'">'.Html::img($img2->getUrl('84x85'), ['alt' => '']).'</a>'; } ?> |
вывод всех картинок с последующим удалением через ajax
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<?php $img = $model->getImage(); $gallery = $model->getImages(); // print_r($gallery ); $img_str=''; echo ' <div class="row">'; foreach($gallery as $img_g){ $url_delete=Url::toRoute(['reshenie/deleteimg', 'id_reshenie' => $model->id, 'id_img' => $img_g->id]); //настройка роутера на нужный урл $img_str.=' <div class="col-xs-6 col-md-3"> <div class="thumbnail reshenie_image_form"> <a class="btn delete_reshenie_img" title="Удалить?" href="'.$url_delete.'" data-id="'.$img_g->id.'"><span class="glyphicon glyphicon-remove"></span></a> <a class="fancybox img-rounded" rel="gallery1" href="'. $img_g->getUrl().'">'.Html::img($img_g->getUrl('200x200'), ['alt' => '']).'</a> </div> </div> '; } echo $img_str; echo '</div>'; ?> |
вот сам ajax в Jquery
1 2 3 4 5 6 7 8 9 10 |
//клик на удалении $(document).on("click", '.delete_reshenie_img', function (e) { e.preventDefault(); var isTrue = confirm("Удалить изображение?"); if(isTrue==true){ var href=$(this).attr('href'); $(this).parent('div').parent('div').remove(); $.get( href ); } }); |
вот экшин для удаления 1 фото
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public function actionDeleteimg($id_reshenie, $id_img) { $reshenie = Reshenie::find() ->where(['id' => $id_reshenie]) ->one(); $images = $reshenie->getImages(); foreach($images as $img){ if($img->id==$id_img){ $reshenie->removeImage($img); } } $success=true; return json_encode($success); } |
екшин для создания записи
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
use yii\web\UploadedFile; // это вверх добавить ...... public function actionCreate() { $model = new Reshenie(); if ($model->load(Yii::$app->request->post()) && $model->save()) { $model->image = UploadedFile::getInstance($model, 'image'); if( $model->image ){ $model->upload(); // смотри файл модели } unset($model->image); $model->gallery = UploadedFile::getInstances($model, 'gallery'); $model->uploadGallery(); Yii::$app->session->setFlash('success', "Решение добавлено"); } if( Yii::$app->request->isAjax ){ return $this->renderAjax('create', [ 'model' => $model, ]); }else{ return $this->render('create', [ 'model' => $model, ]); } } } |
a это прописываем в _form.php для загрузки
1 2 |
<?= $form->field($model, 'image')->fileInput() ?> <?= $form->field($model, 'gallery[]')->fileInput(['multiple' => true, 'accept' => 'image/*']) ?> |
Небольшой комментарий по поводу кода Url::toRoute (Добавлено из-за вопроса в комментариях)
Команда
1 |
Url::toRoute([‘reshenie/deleteimg’, ‘id_reshenie’ => $model->id, ‘id_img’ => $img_g->id]) |
Даёт такую строку
/reshenie/deleteimg?id_reshenie=60&id_img=23
По ней мы обращаемся к контроллеру reshenie и к экшину deleteimg (прописал ручками- не GII). Кроме этого в экшин передаётся 2 параметра (смотрите функцию actionDeleteimg ниже) id_reshenie=60 и id_img=23 . id_reshenie — это просто id модели , id_img- это id внутри компонента рисунков.
вот контроллер, более в целом виде :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class ReshenieController extends Controller { ..... // эту фукнцию прописываем ручками public function actionDeleteimg($id_reshenie, $id_img) { ...... } // вот обычный экшин, которые создается в GII public function actionView($id) { .... } } |
Вывод рисунков в DetailView::widget
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?php $img = $model->getImage(); $gallery = $model->getImages(); $img_str=''; foreach($gallery as $img2){ $img_str.='<a class="fancybox img-thumbnail" rel="gallery1" href="'. $img2->getUrl().'">'.Html::img($img2->getUrl('84x85'), ['alt' => '']).'</a>'; } ?> <?= DetailView::widget([ 'model' => $model, 'attributes' => [ 'id', ..... [ 'attribute' => 'image', 'value' => $img_str, 'format' => 'html', ], ], ]) ?> |
Здравствуйте! В пункте, где у вас описан вывод всех картинок с последующим удалением через ajax, есть строка:
$url_delete=Url::toRoute([‘reshenie/deleteimg’, ‘id_reshenie’ => $model->id, ‘id_img’ => $img_g->id]); //настройка роутера на нужный урл
Подскажите что надо написать вместо reshenie/deleteimg — путь к контроллеру, виду или модели?
Сдублировал в низ статьи -Если не помогло, отпишитесь конкретно.
Команда
Url::toRoute([‘reshenie/deleteimg’, ‘id_reshenie’ => $model->id, ‘id_img’ => $img_g->id])
Даёт такую строку
/reshenie/deleteimg?id_reshenie=60&id_img=23
По ней мы обращаемся к конроллеру reshenie и к экшину deleteimg (прописал ручками- не GII). Кроме этого в экшин передаётся 2 параметра (смотрите функцию actionDeleteimg ниже) id_reshenie=60 и id_img=23 . id_reshenie — это просто id модели , id_img- это id внутри компонента рисунков.
вот контроллер, более в целом виде
class ReshenieController extends Controller
{
…..
// эту фукнцию прописываем ручками
public function actionDeleteimg($id_reshenie, $id_img)
{
……
}
// вот обычный экшин, которые создается в GII
public function actionView($id)
{
….
}
}
Здравствуйте! Спасибо за помощь! Все получилось. У меня есть еще один вопрос, может сможете мне помочь, у меня есть файл view созданный через GII, там вывод данных идет через DetailView::widget, так вот я хочу в этом файле вывести массив с фотографиями находящиеся в галерее, как это правильно сделать не совсем понимаю. Я попытался сделать, но у меня выводит только одно фото, а не цикл.
Файл приложу, может так понятнее будет https://yadi.sk/d/_qDhP1lv3Ecsaf
Вы используете при выводе $img = $model->getImage() . Это переменная для вывода главной фотки. Я добавил в урок внизу правильный вывод всех фоток в DetailView::widget. Вот команда для их получения $gallery = $model->getImages(); , и это массив объектов !! А в первом варианте это просто один объект с главной фоткой.
У меня там задано две переменные, одна, как Вы правильно сказали для вывода главной фотографии $img = $model->getImage(), и другая переменная на следующей строке getImages(); ?>, где уже хранятся файлы галереи.
Там в файле я описываю цикл:
getImages(); ?>
$item,
]);
}
?>
Но при всем этом выводится только одно фото, а их там три, но при распечатке массива $images видно что передаются все три фотографии.
Не получилось вставить код, посмотрите пожалуйста в файле строки с 29 по 40, и с 69 по 74 строку.
Вы для начала без виджета попробуйте вывести фотки.
Хотя бы так:
цикл начало
img src=’< ?=$img->getUrl(x300)?>’
цикл конец
Если вывелись в цикле- то надо смотреть что c виджетом.
а вот этот код закомментируйте… он пока не важен
$images = »;
foreach($gallery as $item) {
$images .= DetailView::widget([
‘model’ => $item,
]);
}
debug($images);
Написал такой цикл:
foreach($gallery as $img):
Html::a(Html::img($img->getUrl(‘x100’)));
php endforeach;
Через него все три фотографии выводятся, но как мне этот цикл теперь поместить в DetailView::widget
Для начала засуньте ваш цикл в переменную
$img_str=»;
foreach($gallery as $img2){
$img_str.=Html::a(Html::img($img2->getUrl(‘x100’)));
}
echo $img_str;
Благодаря Вам все получилось, еще раз большое спасибо за оказанную помощь!
Подскажите, пожалуйста, как можно добавить к фото комментарий?
Т.е. когда пользователь загружает документ, нужно что бы он ещё и оставил комментарий к этому документу.
Здравствуйте. Тут мне видится 3 варианта событий. 1) Вам придется прилично переписать данное расширение под себя 2) Создать отдельную таблицу с комментариями и создать для неё модель, Потом сохранять комментарий после сохранения изображения 3) добавить к табличке Image дополнительное поле , создать модель для image через crud . И после отработки расширения costarico дозаписывать 1 поле, стараясь не затереть остальные.
Почему-то удаление не работает: ни один рисунок не удаляет, ни все изображения. Ругается на Url::toRoute([‘reshenie/deleteimg’, ‘id_reshenie’ => $model->id, ‘id_img’ => $img_g->id]) В чём может быть причина?
вы в ручную урл создайте и потестируйте. строка должна быть что то типо этой /вашконтроллер/deleteimg?id_reshenie=60&id_img=23
Простите, я чайничек, как в ручную? Разве не должно у меня работать, если я всё так же прописал?
Без этой строчки появляются картинки с крестиками. А можно эту строчку заменить?
Внимательно перечитал ваш коментарий про Url::toRoute([‘reshenie/deleteimg’, ‘id_reshenie’ => $model->id, ‘id_img’ => $img_g->id])
где class ReshenieController extends Controller самый главный контроллер
+добавил use yii\helpers\Url; вверху — всё заработало. Большое вам спасибо!!!
есть ли правило для urlManager что бы избавиться эт этого страшного урла
site.tu/yii2images/images/image-by-item-and-alias?item=Pedigrees1&dirtyAlias=9c45049ac6-1_300.jpg ?
можно лишь частично зарезать,
‘image’ => ‘yii2images/images/image-by-item-and-alias’,
но как то тоже не очень. особенно после прикручевания RBAC
По идее можно использовать ваш rules . Но чую, что вам поведение придется переписывать под себя. Пользы своим ответом я вам не принесу. Копайте код.
Добрый день. Подскажите, как можно редактировать галерею, то есть, добавлять в уже существующую галерею фото? Есть у меня 3 таблицы. 1) Товары, 2) Цвета ткани 3) Цвет-Товар. К каждому товару в каждом цвете можно создать галерею. Я создал галерею к цвету черный. Потом хочу дабавить 2 фотки к этому цвету. Если я создаю новую — создается новая запись в таблице Цвет-Товар и к этому id привязывается галерея. Мне же нужно задать id (image.itemId), к которому привяжется галерея.
http://joxi.ru/ZrJ4nwBt1NVGk2
http://joxi.ru/LmG4RwgtRpxXp2
Вам нужно дописать этот компонент . В стандартном варианте(в момент написания статьи) галереи не поддерживаются. Уж извините. Посмотрите мой комментарий выше от 31.03.2017 18:13 .
Использую yii2 2.0.15.1
Подключаю как указанно, добавляю по вьюху field($model, ‘image’)->fileInput()
После сохранения статьи в папках и в базе пусто… Куда копать?
Я уже по года как на Yii2 не писал, но в последний раз, когда загружал yii2-images, его кто то испортил . Я запустить не смог. Пришлось заменять тело скриптов на исходники 2-х летней давности. Тогда заработало. Думаю вам лучше написать загрузчик изображений самостоятельно. Это не так долго , но вы съэкономите потом не один день, используя свой код.