mezcalito / sylius-file-upload-plugin
Mezcalito文件上传插件适用于Sylius。
Requires
- php: >=7.2
- sylius/sylius: ^1.4
Requires (Dev)
- behat/behat: ^3.4
- behat/mink: ^1.7@dev
- behat/mink-browserkit-driver: ^1.3
- behat/mink-extension: ^2.2
- behat/mink-selenium2-driver: ^1.3
- friends-of-behat/page-object-extension: ^0.3
- friends-of-behat/suite-settings-extension: ^1.0
- friends-of-behat/symfony-extension: ^2.0
- friends-of-behat/variadic-extension: ^1.1
- lakion/mink-debug-extension: ^1.2.3
- phpspec/phpspec: ^5.0
- phpstan/phpstan-doctrine: ^0.10
- phpstan/phpstan-shim: ^0.10
- phpstan/phpstan-webmozart-assert: ^0.10
- phpunit/phpunit: ^6.5
- sensiolabs/security-checker: ^5.0
- sylius-labs/coding-standard: ^2.0
- symfony/browser-kit: ^3.4|^4.1
- symfony/debug-bundle: ^3.4|^4.1
- symfony/dotenv: ^4.2
- symfony/intl: ^3.4|^4.1
- symfony/web-profiler-bundle: ^3.4|^4.1
- symfony/web-server-bundle: ^3.4|^4.1
Conflicts
- symfony/browser-kit: 4.1.8
- symfony/dependency-injection: 4.1.8
- symfony/dom-crawler: 4.1.8
- symfony/routing: 4.1.8
- symfony/symfony: 4.1.8
This package is auto-updated.
Last update: 2024-09-25 18:49:16 UTC
README
此插件的工作方式几乎与标准Sylius图片上传相同(参见Sylius文档中的如何向实体添加图片?),只不过它接受任何类型的文件。
最初这作为Sylius核心的拉取请求被提出,但由于与Sylius 1.x不向后兼容而被拒绝(这里是初始PR的链接),所以这里作为Sylius插件提供。
安装
首先使用composer要求此包
$ composer require mezcalito/sylius-file-upload-plugin
然后将包添加到您的config/bundles.php
文件中
// bundles.php return [ // ... Mezcalito\SyliusFileUploadPlugin\MezcalitoSyliusFileUploadPlugin::class => ['all' => true], ];
在您的config/packages/_sylius.yaml
文件中,添加以下内容
# config/packages/_sylius.yaml imports: - { resource: "@MezcalitoSyliusFileUploadPlugin/Resources/config/app/config.yml" }
此文件定义了插件使用的gaufrette
filesystem
和adapter
,您可以根据需要覆盖。
用法
本节是官方Sylius文档关于如何向实体添加图片?的改编。
扩展实体以包含
files
字段是一个相当常见的用例。在本指南中,我们将展示如何将文件添加到ShippingMethod
实体中。
1. 使用FilesAwareInterface
扩展ShippingMethod
类
为了覆盖SyliusCoreBundle中的ShippingMethod
,您必须创建自己的ShippingMethod
类,并将其扩展
<?php declare(strict_types=1); namespace App\Entity; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Mezcalito\SyliusFileUploadPlugin\Model\FilesAwareInterface; use Mezcalito\SyliusFileUploadPlugin\Model\FilesAwareTrait; use Sylius\Component\Core\Model\ShippingMethod as BaseShippingMethod; class ShippingMethod extends BaseShippingMethod implements FilesAwareInterface { use FilesAwareTrait { __construct as private initializeFilesCollection; } public function __construct() { $this->initializeFilesCollection(); } }
这里我们使用了提供的
FilesAwareTrait
以方便使用。
2. 注册您扩展的ShippingMethod
作为资源模型类
使用此类配置,您将注册您的ShippingMethod
类以覆盖默认类
# config/packages/sylius_shipping.yaml sylius_shipping: resources: shipping_method: classes: model: App\Entity\ShippingMethod
3. 创建ShippingMethodFile
类
在App\Entity
命名空间中放置ShippingMethodFile
类,其外观如下
<?php declare(strict_types=1); namespace App\Entity; use Mezcalito\SyliusFileUploadPlugin\Model\File; class ShippingMethodFile extends File { }
4. 添加ShippingMethodFile
的映射文件
您的新实体将保存到数据库中,因此它需要一个映射文件,其中您将设置ShippingMethod
为ShippingMethodFile
的owner
。
# App/Resources/config/doctrine/ShippingMethodFile.orm.yml App\Entity\ShippingMethodFile: type: entity table: app_shipping_method_file manyToOne: owner: targetEntity: App\Entity\ShippingMethod inversedBy: files joinColumn: name: owner_id referencedColumnName: id nullable: false onDelete: CASCADE
5. 修改ShippingMethod
的映射文件
新添加的files
字段必须添加到映射中,与ShippingMethodFile
相关联
# App/Resources/config/doctrine/ShippingMethod.orm.yml App\Entity\ShippingMethod: type: entity table: sylius_shipping_method oneToMany: files: targetEntity: App\Entity\ShippingMethodFile mappedBy: owner orphanRemoval: true cascade: - all
6. 将ShippingMethodFile
注册为资源
ShippingMethodFile
类需要注册为Sylius资源
# app/config/config.yml sylius_resource: resources: app.shipping_method_file: classes: model: App\Entity\ShippingMethodFile
7. 创建ShippingMethodFileType
类
这是ShippingMethodFileType
类的样子。将其放在App\Form\Type\
目录中。
.. code-block:: php
<?php declare(strict_types=1); namespace App\Form\Type; use Mezcalito\SyliusFileUploadPlugin\Form\Type\FileType; final class ShippingMethodFileType extends FileType { /** * {@inheritdoc} */ public function getBlockPrefix(): string { return 'app_shipping_method_file'; } }
8. 将ShippingMethodFileType
注册为服务
在创建表单类型类之后,您需要将其注册为如下所示的form.type
服务
# services.yml services: app.form.type.shipping_method_file: class: App\Form\Type\ShippingMethodFileType tags: - { name: form.type } arguments: ['%app.model.shipping_method_file.class%']
9. 将ShippingMethodFileType
添加到资源表单配置中
此外,新的表单类型需要配置为ShippingMethodFile
的资源表单
# app/config/config.yml sylius_resource: resources: app.shipping_method_file: classes: form: App\Form\Type\ShippingMethodFileType
10. 扩展ShippingMethodType
以包含文件字段
创建Sylius\Bundle\ShippingBundle\Form\Type\ShippingMethodType
的表单扩展类
它需要具有作为CollectionType的文件字段。
<?php declare(strict_types=1); namespace App\Form\Extension; use App\Form\Type\ShippingMethodFileType; use Sylius\Bundle\ShippingBundle\Form\Type\ShippingMethodType; use Symfony\Component\Form\AbstractTypeExtension; use Symfony\Component\Form\Extension\Core\Type\CollectionType; use Symfony\Component\Form\FormBuilderInterface; final class ShippingMethodTypeExtension extends AbstractTypeExtension { /** * {@inheritdoc} */ public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->add('files', CollectionType::class, [ 'entry_type' => ShippingMethodFileType::class, 'allow_add' => true, 'allow_delete' => true, 'by_reference' => false, 'label' => 'sylius.form.shipping_method.files', ]); } /** * {@inheritdoc} */ public function getExtendedType(): string { return ShippingMethodType::class; } }
如果您只需要单个文件上传,这可以通过两个非常简单的步骤来完成。
首先,在上面的表单代码中,将 allow_add
和 allow_delete
设置为 false
其次,在您之前定义的 ShippingMethod
实体的 __construct
方法中添加以下内容
public function __construct() { parent::__construct(); $this->files = new ArrayCollection(); $this->addFile(new ShippingMethodFile()); }
# services.yml services: app.form.extension.type.shipping_method: class: App\Form\Extension\ShippingMethodTypeExtension tags: - { name: form.type_extension, extended_type: Sylius\Bundle\ShippingBundle\Form\Type\ShippingMethodType }
11. 声明文件上传监听器服务
为了处理文件上传,您需要将 FilesUploadListener
绑定到 ShippingMethod
实体的事件上
.. code-block:: yaml
# services.yml services: app.listener.files_upload: class: Mezcalito\SyliusFileUploadPlugin\EventListener\FilesUploadListener autowire: true autoconfigure: false public: false tags: - { name: kernel.event_listener, event: sylius.shipping_method.pre_create, method: uploadFiles } - { name: kernel.event_listener, event: sylius.shipping_method.pre_update, method: uploadFiles }
12. 在表单视图中渲染文件字段
为了实现这一点,您需要自定义来自 SyliusAdminBundle/views/ShippingMethod/_form.html.twig
文件的表单视图。
将内容复制并粘贴到您自己的 app/Resources/SyliusAdminBundle/views/ShippingMethod/_form.html.twig
文件中,并渲染 {{ form_row(form.files) }}
字段。
{# app/Resources/SyliusAdminBundle/views/ShippingMethod/_form.html.twig #} {% from '@SyliusAdmin/Macro/translationForm.html.twig' import translationForm %} {# Add the form theme to preview the file with the theme (there is a shortcut for 'fileProductTheme.html.twig' #} {# Check https://symfony.com.cn/doc/current/form/form_themes.html for help #} {% form_theme form with [ '@SyliusAdmin/Form/imagesTheme.html.twig', '@MezcalitoSyliusFileUploadPlugin/Form/theme.html.twig' ] %} <div class="ui two column stackable grid"> <div class="column"> <div class="ui segment"> {{ form_errors(form) }} <div class="three fields"> {{ form_row(form.code) }} {{ form_row(form.zone) }} {{ form_row(form.position) }} </div> {{ form_row(form.enabled) }} <h4 class="ui dividing header">{{ 'sylius.ui.availability'|trans }}</h4> {{ form_row(form.channels) }} <h4 class="ui dividing header">{{ 'sylius.ui.category_requirements'|trans }}</h4> {{ form_row(form.category) }} {% for categoryRequirementChoiceForm in form.categoryRequirement %} {{ form_row(categoryRequirementChoiceForm) }} {% endfor %} <h4 class="ui dividing header">{{ 'sylius.ui.taxes'|trans }}</h4> {{ form_row(form.taxCategory) }} <h4 class="ui dividing header">{{ 'sylius.ui.shipping_charges'|trans }}</h4> {{ form_row(form.calculator) }} {% for name, calculatorConfigurationPrototype in form.vars.prototypes %} <div id="{{ form.calculator.vars.id }}_{{ name }}" data-container=".configuration" data-prototype="{{ form_widget(calculatorConfigurationPrototype)|e }}"> </div> {% endfor %} {# Here you go! #} {{ form_row(form.files) }} <div class="ui segment configuration"> {% if form.configuration is defined %} {% for field in form.configuration %} {{ form_row(field) }} {% endfor %} {% endif %} </div> </div> </div> <div class="column"> {{ translationForm(form.translations) }} </div> </div>
13. 验证
到目前为止,您的表单工作得很好,但不要忘记验证。最简单的方法是在 App/Resources/config/validation
文件夹下的验证配置文件中进行。
例如,对于图像,它可能看起来像这样
# src\Resources\config\validation\ShippingMethodFile.yml App\Entity\ShippingMethodFile: properties: file: - Image: groups: [sylius] maxHeight: 1000 maxSize: 10240000 maxWidth: 1000 mimeTypes: - "image/png" - "image/jpg" - "image/jpeg" - "image/gif" mimeTypesMessage: 'This file format is not allowed. Please use PNG, JPG or GIF files.' minHeight: 200 minWidth: 200
或者对于PDF,它可能看起来像这样
# src\Resources\config\validation\ShippingMethodFile.yml App\Entity\ShippingMethodFile: properties: file: - File: groups: [sylius] maxSize: 10240000 mimeTypes: - "application/pdf" - "application/x-pdf" mimeTypesMessage: 'This file format is not allowed. Only PDF files are allowed.'
这为每个文件实体定义了验证约束。
最后,将 ShippingMethod
的验证连接到每个单独的 File Entity
的验证
# src\Resources\config\validation\ShippingMethod.yml App\Entity\ShippingMethod: properties: ... images: - Valid: ~
14. 迁移
执行数据库迁移
$ bin/console doctrine:migrations:diff $ bin/console doctrine:migrations:migrate