L
L
lilwings2020-02-11 13:51:44
Yii
lilwings, 2020-02-11 13:51:44

How to correctly save data to db after uploading a file in Yii2?

Model:

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);
                }
            )
        ];
    }
}


Controller:

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

After the $model->upload();save call, validation fails because the files are overwritten there:

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


If you delete the lines with overwriting the file, then the error appears:
finfo_file(C:\projects\yuk\tmp\php8015.tmp): failed to open stream: No such file or directory


In general, I would like not to create separate variables for the file and for its name, but to process the files, put their path into these variables, and save them to the database. So that when $model->save()
$img_preview, $img_fullare saved in the database.

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question