用于上传图像文件的Symfony自定义文件名 [英] Symfony custom filename for uploaded image files
问题描述
我知道VichUpload和命名器,但是我必须面对两种不同的文件上传,并且我需要使用当前的VichUpload文档无法获得的特殊命名约定.
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.
首次上传文件的对象是一个名为学校"的实体,该实体管理着每所学校及其徽标.因此,以Web根目录'../web/files/schools/'为例,我将选择school_id,然后选择带有上载文件名的'logo'文件夹,因此它可能是'../web/files/school/000001/logo.png".
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'.
然后,第二个实体是存储照片的学生",并带有来自School实体的school_id外键.因此,生成的文件名将取决于学校ID和学生ID,即学生'../web/files/schools/< school_id>/students/< student_id>的根.[jpg | png] ",在左侧有student_id的六个零填充.
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.
这是config.yml
中与此相关的部分(更新的信息):
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();
}
同时使用"namer"和"directory_namer"进行此设置似乎忽略了directory_namer中的路径,并使用路径< namer>/< namer> .ext"而不是< directory_namer>/< namer>" .ext".如果我更改getUserImage()函数并在getUserDirectory()的结果前面添加(即,数据库存储< directory_namer>/< namer> .ext",而不只是< namer> .ext"),则"< directory_namer>"路径将被忽略,仅创建< namer> .ext".
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.
由于upload_prefix和uri_destination似乎无法处理可变数据,因此在两种情况下如何设置命名器或获取该路径的任何方法?
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?
顺便说一句,根据vendor
文件夹中捆绑的composer.json的说法,我正在使用Symfony 3.1,并且composer不允许更新"1.7.x-dev"以外的版本. 如果您发现它可以使用此设置,并且可能的解决方案是升级,那么感谢您指出解决该问题的特定文件,以便我可以手动粘贴任何错误的内容.
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.
解决方案:
问题在于,由于版本旧",缺少了一个目录名类PropertyDirectoryNamer,它的服务名是vich_uploader.namer_directory_property
而不是vich_uploader.directory_namer_subdir
,这在此用途上是一个错误的类.我复制了此类并将其注册在namer.xml文件中,然后得到了预期的结果.现在,我将尝试将其标记为已解决.
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.
推荐答案
您需要创建实现的自定义目录命名器类
You need to create custom directory namer class that implements
Vich\UploaderBundle\Naming\DirectoryNamerInterface
例如:
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;
}
}
然后,将其作为服务.
services:
# ...
app.directory_namer.school:
class: App\Services\SchoolDirectoryNamer
最后一步是配置vich_uploader
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-如何创建自定义目录命名器
这篇关于用于上传图像文件的Symfony自定义文件名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!