Yii2 File Uploading And Cyrillic Names

Hello, I’ve read the non-complete official article and I get the problems…

The first problem is: how to transliterate cyrillic file names (like привет.jpg) before saving (for example in the model under beforeSave() method)?

The original code saves files like привет.jpg as .jpg (only extension).

The code beyond from the article, but with one additional line that solves the problem.




$model = new UploadForm();

        if (Yii::$app->request->isPost) {

            $model->file = UploadedFile::getInstance($model, 'file');


            if ($model->validate()) {

                $model->file->name = Translit::to($model->file->name, 'rus'); //temp solution

                $model->file->saveAs('uploads/'. $model->file->baseName . '.' . $model->file->extension);

            }

        }

        return $this->render('create', ['model' => $model]);



Here Translit::to(string, language) - it is super simple method which transliterate cyrillic letters (eg. ш -> sh, я -> ya etc) via strtr php function.

The second issue is: I can’t understand the meaning of UploadForm model in the example (it is almost empty!). It feels like UploadedFile class holds responsibility to all the work. Maybe UploadForm model should be more massive?

And the third one is: I can’t find comprehensive example working with file uploading :unsure: . The most articles are devoted to working with Kartik widgets…

:rolleyes: Anybody help me?

Not sure if it helps and how your design is. One way, is to hash the filename before saving it to the database.




$model->file_name = hash('crc32', $cyrillicFile);

$model->save();



When you want to retrieve and compare filenames later you can compare the hashed versions;




use yii\helpers\Html;

if ($model->file_name == hash('crc32', $cyrillicFile)) {

   // do stuff

}



You can also use Html::encode and Html::decode methods or combine the above with this to achieve your needs.

You offer me hashing the file name? I don’t understand your solution.

For me more interesting where in the UploadForm model I can make this:




$model->file->name = intolatin($model->file->name);



As I said, it depends on your design need (I do not have detailed info on that):

[list=1]

[*]Hashing the file name using crc32 as I said will generate 8 english roman characters to save, which will be db friendly and based on the filename you input.

[*]If maintaining exact file name is important for you, you can use htmlentities or yii\helpers\Html::encode as I mentioned, before you save. You can retrieve it later with decode. You may need some replacing of special characters like & before saving and retrieving.

[*]If you are indicating, you need to translate the string to another language before saving, then I am not sure there is a ready made function, you may need to write your own converter or rely on third party translation apis.

[/list]

Files are usually renamed when using $file->saveAs with random hash or anything else(date and time and so on). Hash is used as filename so that if you have many files in one dir you will not get any collisions(hopefully).

Example:

user uploads привет.jpg

you save it as al23s45k3245d2345jfh234askdjfh.jpg