D
D
Dmitry Kim2016-07-14 13:29:22
Yii
Dmitry Kim, 2016-07-14 13:29:22

afterSave carousel in YII2 or how to attach image to entity?

In general, the situation is as follows: you need to upload PDF files to the database (PS: upload not the files themselves to the database, but records with information about their location on the site), so that people can then download / watch them in the browser.
Model attributes:

return [
                'id'             => 'ID',
                'issue_date'     => 'Дата выпуска',
                'issue_num'      => 'Номер газеты',
                'year_num'       => 'Номер в году',
                'path'           => 'Ссылка на файл',
                'size'           => 'Размер файла',
                'created_by'     => 'Создано',
                'updated_by'     => 'Обновлено',
                'created_at'     => 'Дата создания',
                'updated_at'     => 'Дата обновления',
                'view_count'     => 'Количество просмотров',
                'download_count' => 'Количество скачиваний',
                'is_active'      => 'Активность',
            ];

I must say right away that everything works flawlessly with the exception of one problem area. Files are uploaded to the form via dropzone and stored in the /tmp temporary folder. The form is filled with the rest of the data, and when saving the record, the file must be moved to a subfolder by the record ID: /userdata/pdfs/XXXX (well, you know how it happens).
For editing - everything is clear, everything works like clockwork. But what about when adding a new record? After all, the ID is still unknown, and therefore we cannot create such a folder!
"Good" - I thought, and decided to move the temporary file in the afterSave method. But then, after moving, I need to change the address of the file in the database, then afterSave twitches again, and again, and again?!
Loading images into a separate database table is not a problem. But what if the file needs to be kept along with the record?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
M
Maxim Fedorov, 2016-07-14
@kimono

"Good" - I thought, and decided to move the temporary file in the afterSave method. But then, after moving, I need to change the address of the file in the database, then afterSave twitches again, and again, and again?!

what address are you talking about? You have a place to store the file /userdata/pdfs/XXXX You just need to store the name of the file - you don't need to store the entire path to it. Those. you can safely save the record with the name, and then move it to afterSave
Let's say there is a path to the file /userdata/pdfs/module/id/filename.pdf.
Each file, respectively, refers to some module, as far as I understand, the ownership of the module is determined before saving the model data. What's stopping you from doing the following?
1. Move the path to the /userdata/pdfs/ files into some alias or, in extreme cases, into a constant
2. Add the $module attribute to the model - in which to write information about the module at the loading stage.
3. Add the $filename attribute to the model - in which, at the loading stage, write the file name
4. On afterSave, make the file move
5. Get the full path to the file as a combination of all these data
Ie . do something like this:
/**
 * @property $id ID
 * @property $issue_date Дата выпуска
 * @property $issue_num Номер газеты
 * @property $year_num Номер в году
 * @property $size Размер файла
 * @property $created_by Создано
 * @property $updated_by Обновлено
 * @property $created_at Дата создания
 * @property $updated_at Дата обновления
 * @property $view_count Количество просмотров
 * @property $download_count Количество скачиваний
 * @property $is_active Активность
 *
 * @property $module Модуль к которому относится файл
 * @property $filename Название файла (вместе с расширением)
 */
class PdfFile extends \yii\db\ActiveRecord 
{
    /**
     * @var string Путь к папке загрузок, но вообще лучше его вынести в алиас
     */
    const PATH = '/userdata/pdfs/'
    
    /**
     * Функция получения полного пути к файлу
     *
     * @return string
     */
    public function getFilepath() {
        return $this::PATH . $this->module . '/' . $this->id . '/' . $this->filename;
    }

    /**
     * @inheritdoc
     */
    public function afterSave( $insert, $changedAttributes ){
        // тут перемещаем файл с временной папки в папку $model->getFilepath
    }
}

K
Kirill Arutyunov, 2016-07-14
@arutyunov

$insert and $changedAttributes are passed to afterSave - you only need to pull at $insert, as far as I understand.
Do a check if ($insert) and update the record, specifying the path to the file, save. After this save, $insert will already be false, because the model will already have an ID.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question