Symfony custom filename for uploaded image files

邮差的信 提交于 2019-12-12 06:46:40

问题


I'm aware of VichUpload and namers, but I have to face two different file uploads, and I need special naming conventions that I'm unable to get with the current VichUpload documentation.

First file upload is for an entity called "School", which manages every single school, and its logo. So, taking as web root '../web/files/schools/', then I'd take the school_id and then the 'logo' folder with the uploaded file name, so it could be '../web/files/schools/000001/logo.png'.

Then, the second entity is 'students' to store the photo, with a school_id foreign key from School entity. So, the resulting file name would depend on the school id, and the student id, being the root for student '../web/files/schools/<school_id>/students/<student_id>.[jpg|png]', having student_id a six zero padding on the left.

This is the section in config.yml about this (updated info):

    school_image:
        upload_destination: "../web/files/images/schools"
        uri_prefix: "/files/images/schools"
        directory_namer:
            service: vich_uploader.directory_namer_subdir
            options: { property: 'schoolDirectory', chars_per_dir: 6, dirs: 1 }
        namer:
            service: vich_uploader.namer_property
            options: { property: 'idSlug' }
        inject_on_load:     true
        delete_on_update:   true
        delete_on_remove:   true
    student_image:
        upload_destination: "../web/files/images/schools"
        uri_prefix: "/files/images/schools"
        directory_namer:
            service: vich_uploader.directory_namer_subdir
            options: { property: 'userDirectory', chars_per_dir: 6, dirs: 1 }
        namer:
            service: vich_uploader.namer_property
            options: { property: 'userImage'}
        inject_on_load:     true
        delete_on_update:   true
        delete_on_remove:   true

in school entity (might work with a dirty workaround):

/**
 * NOTE: This is not a mapped field of entity metadata, just a simple property.
 *
 * @Vich\UploadableField(mapping="school_image", fileNameProperty="imageName")
 *
 * @Assert\Image()
 *
 * @var File
 */
private $imageFile;

public function getIdSlug()
{
    $slug = sprintf("%06d", $this->getId());
    return $slug;
}

public function getSchoolDirectory()
{
    $slug = sprintf("%06d", $this->getId());
    return $slug;
}

in student entity (not working, as explained below):

/**
 * NOTE: This is not a mapped field of entity metadata, just a simple property.
 *
 * @Vich\UploadableField(mapping="student_image", fileNameProperty="imageName")
 *
 * @Assert\Image()
 *
 * @var File
 */
private $imageFile;

public function getUserDirectory()
{
    $schoolDir = $this->getSchool()->getSchoolDirectory();
    $dir = $schoolDir.'/students/'.sprintf("%06d", $this->getId());
    return $dir;
}

public function getUserImage()
{
    return $this->getUsername() . $this->getImageFile()->getExtension();
}

This setup with both "namer" and "directory_namer" seems to ignore the paths in directory_namer and use a path "<namer>/<namer>.ext" instead of "<directory_namer>/<namer>.ext". If I change the getUserImage() function and prepend the result of getUserDirectory() (i.e., the db stores "<directory_namer>/<namer>.ext" instead of just "<namer>.ext"), the "<directory_namer>" path is ignored and just "<namer>.ext" is created.

Since upload_prefix and uri_destination don't seem to handle variable data, how can I setup a namer or whatever to get this path for both cases?

BTW, I'm using Symfony 3.1 and composer hasn't allowed to update vich beyond "1.7.x-dev", according to bundled composer.json in vendor folder. If you find that it should work with this setup and the possible solution is to upgrade, I would thank to be pointed to the specific files which fix the problem, so I can manually paste whatever is wrong.

SOLUTION:

The problem was that, due to the "old" version, there was a missing directory_namer class, PropertyDirectoryNamer, with vich_uploader.namer_directory_property servicename, instead of vich_uploader.directory_namer_subdir, which was a wrong class for this purpose. I copied this class and registered it in the namer.xml file, and then I got the expected results. Now I'm going to try to mark this as solved.


回答1:


You need to create custom directory namer class that implements

Vich\UploaderBundle\Naming\DirectoryNamerInterface

For example:

namespace App\Services;

use Vich\UploaderBundle\Mapping\PropertyMapping;

class SchoolDirectoryNamer implements DirectoryNamerInterface
{
    public function directoryName($object, PropertyMapping $mapping): string
    {
        // do what you want with $object and $mapping 
        $dir = '';

        return $dir;
    }
}

Then, make it as a service.

services:
    # ...
    app.directory_namer.school:
        class: App\Services\SchoolDirectoryNamer

Last step is config vich_uploader

vich_uploader:
    # ...
    mappings:
        school:
            upload_destination: school_image
            directory_namer:    app.directory_namer.school
        student:
            upload_destination: student_image
            directory_namer:    app.directory_namer.student

source : VichUploaderBundle - How To Create a Custom Directory Namer



来源:https://stackoverflow.com/questions/48917246/symfony-custom-filename-for-uploaded-image-files

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!