Задать вопрос
@lilwings

Как правильно сохранить данные в бд после загрузки файла в Yii2?

Модель:

class Info extends ActiveRecord
{
    public $img_preview;
    public $img_full;

    public static function tableName()
    {
        return '{{info}}';
    }

    public function rules() {
        return [
            [['title', 'preview', 'description_seo'], 'string', 'length' => [0, 255]],
            [['title', 'preview', 'description_seo'], 'filter', 'filter' => 'strip_tags'],
            [['title', 'preview', 'description_seo'], 'trim'],
            [['title', 'preview', 'description_seo'], 'required'],
            [['img_preview', 'img_full'], 'file', 'skipOnEmpty' => false, 'extensions' => 'jpg, jpeg'],
            ['description', 'safe'],
        ];
    }

    public function upload() {
        if ( $this->validate() ) {
            // Создание директории
            $folderName = $this->generateUniqFileName("web/info");
            FileHelper::createDirectory( Yii::getAlias("@frontend/web/img/info/$folderName") );

            // Создание файла
            $imgPreviewName = $folderName . '/' . $this->generateUniqFileName("web/info/$folderName") . '.' . $this->img_preview->extension;
            $this->img_preview->saveAs( Yii::getAlias("@frontend/web/img/info/$imgPreviewName") );

            // Создание Файла
            $imgFullName = $folderName . '/' . $this->generateUniqFileName("web/info/$folderName") . '.' . $this->img_full->extension;
            $this->img_full->saveAs( Yii::getAlias("@frontend/web/img/info/$imgFullName") );

            // Перезаписать файлы их директорией
            $this->img_preview = $imgPreviewName;
            $this->img_full = $imgFullName;

            return true;
        }

        return false;
    }

    public function generateUniqFileName($path) {
        $name = bin2hex(random_bytes(8));

        if ( file_exists( Yii::getAlias("@frontend/$path/$name") ) ) return $this->generateUniqFileName();
        else return $name;
    }

    public function attributeLabels()
    {
        return [
            'title' => 'Заголовок',
            'preview' => 'Превью',
            'description' => 'Описание новости',
            'img_preview' => 'Фотография (Превью)',
            'img_full' => 'Фотография (Основная)',
            'description_seo' => 'Description (SEO)',
        ];
    }

    public function behaviors()
    {
        return [
            'purify' => array(
                'class' => PurifyBehavior::className(),
                'attributes' => array('description'),
                'config' => function ($config) {
                    $def = $config->getHTMLDefinition(true);

                    $config->set('HTML.AllowedElements', array('p', 'span', 'h1', 'h2', 'h3', 'h4', 'a', 'br', 'strong', 'em', 'del', 'u', 'pre', 'code', 'blockquote'));

                    $def->addAttribute('a', 'url', 'Text');
                    $def->addAttribute('a', 'title', 'Text');
                    $def->addAttribute('a', 'target', 'Text');

                    $def->addAttribute('p', 'style', 'Text');
                    $def->addAttribute('span', 'style', 'Text');
                    $def->addAttribute('del', 'style', 'Text');
                    $def->addAttribute('u', 'style', 'Text');
                    $def->addAttribute('em', 'style', 'Text');

                    $def->addAttribute('img', 'src', 'Text');
                    $def->addAttribute('img', 'alt', 'Text');

                    $config->set('HTML.SafeIframe', true);
                    $config->set('URI.SafeIframeRegexp', '%^(http:|https:)?//(www.youtube(?:-nocookie)?.com/embed/|player.vimeo.com/video/)%');

                    $config->set('AutoFormat.RemoveEmpty', true);
                    $config->set('AutoFormat.RemoveEmpty.RemoveNbsp', true);
                    $config->set('AutoFormat.AutoParagraph', true);
                }
            )
        ];
    }
}


Контроллер:

public function actionAdd()
{
    $model = new Info();

    if ( $model->load(Yii::$app->request->post()) ) {
        $model->img_preview = UploadedFile::getInstance($model, 'img_preview');
        $model->img_full = UploadedFile::getInstance($model, 'img_full');

        $model->upload();

        if ( $model->save() ) {
            Yii::$app->session->setFlash('message', 'Информация добавлена!');

            return $this->refresh();
        }

        Yii::$app->session->setFlash('message', 'Не правильные данные!');
    }

    return $this->render('add', compact('model'));
}


MySql:

5e4284caeba1f977299744.png

После вызова $model->upload(); при сохранении не проходит валидация, так как там файлы перезаписываются:

$this->img_preview = $imgPreviewName;
$this->img_full = $imgFullName;


Если удалить строки с перезаписью файла, то ошибка появляется:
finfo_file(C:\projects\yuk\tmp\php8015.tmp): failed to open stream: No such file or directory


Вообщем мне бы хотелось не создавать отдельных переменных для файла и для его имени, а обработать файлы, в данные переменные поместить их путь, и сохранить в бд. Чтобы при $model->save()
$img_preview, $img_full сохранялись в бд.
  • Вопрос задан
  • 208 просмотров
Подписаться 1 Простой 3 комментария
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы