Пример использования расширения по загрузке фото - vorst.ru

Загрузка фото


делаем демо

Работа с изображениями является важной составляющей любого разрабатываемого сайта. Скорость разработки сайта, дальнейшее сопровождение сайта во многом зависят от функциональности выбранного расширения.

Загрузка фото

делаем демо

Чтобы показать, как работает загрузка изображений, нужно разрешить загружать изображения на свой сайт. Но, в этом случае, дисковое пространство может быть быстро исчерпано и нужно как-то удалять оставленный посетителями "мусор".

Например, можно устроить, что-то вроде надписи в столовой - "Уберите, пожалуйста, за собой посуду" (демо).


Если ограничить количество загружаемых файлов небольшой цифрой, то очень скоро каждый следующий посетитель будет вынужден удалять файлы предшественников, прежде, чем сам сможет загрузить файлы.

Так и сделаем. Для загрузки будем использовать расширение yii2-byone-uploader. Это расширение, которое хранит информацию обо всех загруженных в приложении файлах, в одной модели - OneFile.

Модель

В модели, которой нужна загрузка файлов, не создается поле с типом file, а "подмешивается" поведение, которое сохраняет информацию о загруженных файлах.

Создадим модель sample\models\Photo.php категорий фотографий. В каждую категорию можно грузить несколько, например 5 фотографий.

namespace sample\models;
use yii\base\Model;
use sergmoro1\uploader\FilePath;
use sergmoro1\uploader\models\OneFile;
class Photo extends Model
{
  public $id;
  public $category;

Модель не связана с таблицей базы данных. Она будет существовать только в памяти. Этого достаточно, ведь информация о загруженных файлах будет хранится в "реальной" модели. Подмешаем эту модель.

  public $sizes = [
    'original' => ['width' => 600, 'height' => 450, 'catalog' => 'original'],
    'main' => ['width' => 400, 'height' => 300, 'catalog' => ''],
    'thumb' => ['width' => 120, 'height' => 90, 'catalog' => 'thumb'],
  ];
  public function behaviors()
  {
    return [
      'FilePath' => [
        'class' => FilePath::className(),
        'file_path' => '/files/photo/',
      ]
    ];
  }

Массив $sizes задает подкаталоги и размеры в которых будет сохраняться загруженное изображение. В поведении определяется основной каталог для хранения файлов модели.

Теперь нужно определить, какие именно файлы относятся к модели.

  public function getFiles()
  {
    return OneFile::find()
      ->where('parent_id=:parent_id AND model=:model', [
        ':parent_id' => $this->id,
        ':model' => 'sample\models\Photo',
      ])
      ->all();
  }

Контроллер

Будем считать, что категории фотографий неизменны и их количество фиксировано. Пусть их всего будет 4. Проще всего задавать их в виде массива sample\controllers\PhotoController.php.

<?php
namespace sample\controllers;
use Yii;
use yii\web\Controller;
use yii\data\ArrayDataProvider;
use sample\models\Photo;
class PhotoController extends Controller
{
  public $models = [
    ['id' => 1, 'category' => 'Street'],
    ['id' => 2, 'category' => 'Office'],
    ['id' => 3, 'category' => 'Factory'],
    ['id' => 4, 'category' => 'Nature'],
  ];
  public $_model;

Теперь легко вывести список категорий.

  public function actionIndex()
  {
    $dataProvider = new ArrayDataProvider([
      'models' => $this->models,
    ]);
    return $this->render('index', [
      'dataProvider' => $dataProvider,
    ]);
  }

Представление

Список в демо немного сложнее, но полное описание только утомит читателя, поэтому приведем только часть, а именно вывод миниатюры sample\views\photo\index.php.

<?= GridView::widget([
  'dataProvider' => $dataProvider,
  'layout' => "{items}\n{summary}\n{pager}",
  'columns' => [
    'id',
    [
      'header' => \Yii::t('app', 'Image'),
      'format' => 'html',
      'options' => ['style' => 'width:120px'],
      'value' => function($data) {
        $model = new Photo(['id' => $data['id'], 'category' => $data['category']]);
        $count = count($model->files);
        return $count == 0 
          ? '<i class="fa fa-3x fa-photo"></i>'
          : Html::img($model->getImage('thumb', $count - 1));
      }
    ],

Выводится последняя загруженная миниатюра. Теперь можно посмотреть, как это работает.

Да и главное!

Как будут загружаться изображения?

В представлении sample/views/photo/update.php вызовем виджет ByOne.

<?php
use sergmoro1\uploader\widgets\Byone;
?>
<?= Byone::widget([
  'model' => $model,
  'secure' => false,
  'maxFiles' => 5,
  'appendixView' => '/photo/appendix',
  'cropAllowed' => true,
]) ?>

А в контроллере sample/controller/PhotoController.php добавим соответствующее действие.

  public function actionUpdate($id)
  {
    return $this->render('update', [
      'model' => $this->getModel($id),
    ]);
  }
  public function getModel($id)
  {
    if($this->_model === null)
    {
      $model = $this->models[$id - 1];
      $this->_model = new Photo(['id' => $model['id'], 'category' => $model['category']]);
    }
    return $this->_model;
  }

Заключение

При подключении расширения yii2-byone-uploader нет необходимости определять поле file в модели, обрабатывать submit и даже определять form. Полная документация, демо.

комментарии

  • Василий 25 Янв 2017

    Sergey Morozov 18 Июн 2018

  • Jenibelle 26 Июл 2016

    Sergey Morozov 18 Июн 2018

Оставьте комментарий

Только авторизованные посетители могут оставлять комментарии. Пожалуйста, войдите или пройдите регистрацию.