tiloweb/uploaded-file-type-bundle

一个处理表单文件类型上传并为您存储URL的Symfony扩展包

v1.0.2 2023-06-12 08:35 UTC

This package is auto-updated.

Last update: 2024-09-05 13:38:29 UTC


README

不要处理实体图像的上传、存储和访问逻辑!只需指定您想要上传文件的位置,并仅存储其URL。

安装

请确保已全局安装Composer,如Composer文档中的安装章节所述。

使用Symfony Flex的应用程序

打开命令行控制台,进入您的项目目录并执行

$ composer require tiloweb/uploaded-filetype-bundle

不使用Symfony Flex的应用程序

步骤 1:下载Bundle

打开命令行控制台,进入您的项目目录并执行以下命令以下载此扩展包的最新稳定版本

$ composer require tiloweb/uploaded-filetype-bundle

步骤 2:启用Bundle

然后,通过将其添加到项目config/bundles.php文件中注册的Bundle列表中,启用该Bundle

// config/bundles.php

return [
    // ...
    Tiloweb\UploadedFileTypeBundle\UploadedFileTypeBundle::class => ['all' => true],
];

配置

步骤 1:配置您的文件系统

使用OneUp FlySystem Bundle来配置您想要与之一起工作的文件系统。

步骤 2:创建默认配置

# config/package/uploaded_file_type.yml
uploaded_file_type:
  configurations:
    default:
      filesystem: 'oneup_flysystem.your_filesystem'
      base_uri: 'https://www.exemple.com/upload'
      path: '/image'

您可以创建多个配置,这里,您将使用default配置。

  • filesystem:您想要使用的OneUp FlySystem的别名。
  • base_uri:访问您文件系统根部的URL。
  • path:您想要上传文件的文件夹。

使用方法

非常简单!🦆

只需创建一个带有FileType字段的表单,并带有选项upload

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('image', FileType::class, [
            'upload' => 'default'
        ])
    ;
}

当表单提交时,文件将由default配置的文件系统上传,文件的URL将被构造并存储在您的$image字段中。

您可以在文件存储在文件系统后更改文件命名策略。为此,您可以将一个filename选项添加到您的FileType,指向一个接受2个参数的包装器

  1. UploadedFile $file将包含通过表单上传的文件
  2. UploadedFile $item将包含您的表单的数据对象

默认命名策略为

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('image', FileType::class, [
            'upload' => 'default',
            'filename' => function(UploadedFile $file, $item) {
                $filename = $file->getClientOriginalName();
    
                $filename = str_replace(
                    '.' . $file->guessClientExtension(),
                    '.' . md5(microtime().rand(0, 1000)) . '.' . $file->guessClientExtension(),
                    $filename
                );
    
                return $filename;
            }
        ])
    ;
}

示例

在这里,您将创建一个表单以创建一个包含要在服务器上存储的标志的Retail实体。

<?php
# src/Form/RetailType.php

namespace App\Form;

use App\Entity\Retail;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class RetailType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('label', TextType::class)
            ->add('logo', FileType::class, [
                'upload' => 'default'
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Retail::class,
        ]);
    }
}
<?php
# src/Entity/Retail.php
namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class Retail
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     * @ORM\Column(type="integer")
     */
    private int $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private string $label = '';

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private ?string $logo = null;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getLabel(): ?string
    {
        return $this->label;
    }

    public function setLabel(string $label): self
    {
        $this->label = $label;

        return $this;
    }

    public function getLogo(): ?string
    {
        return $this->logo;
    }

    public function setLogo(?string $logo): self
    {
        $this->logo = $logo;

        return $this;
    }
}
<?php
# src/Entity/Retail.php
namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity
 */
class Retail
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     * @ORM\Column(type="integer")
     */
    private int $id;

    /**
     * @Assert\NotBlank
     * @ORM\Column(type="string", length=255)
     */
    private string $label = '';

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private ?string $logo = null;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getLabel(): ?string
    {
        return $this->label;
    }

    public function setLabel(string $label): self
    {
        $this->label = $label;

        return $this;
    }

    public function getLogo(): ?string
    {
        return $this->logo;
    }

    public function setLogo(?string $logo): self
    {
        $this->logo = $logo;

        return $this;
    }
}
<?php

namespace App\Controller;

use App\Entity\Retail;
use App\Form\RetailType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

class DefaultController extends AbstractController
{
    /**
     * @Route("/{retail}", name="app_edit")
     */
    public function form(Retail $retail, Request $request)
    {
        $form = $this->createForm(RetailType::class, $retail);
        $form->handleRequest($this->request);

        if($form->isSubmitted() && $form->isValid()) {
            // ...
        }

        // ...
    }
}
# config/packages/oneup_flysystem.yaml
# Read the documentation: https://github.com/1up-lab/OneupFlysystemBundle
oneup_flysystem:
  adapters:
    default_adapter:
      local:
        location: '%kernel.project_dir%/public/upload'
        
  filesystems:
    default_filesystem:
      adapter: default_adapter
      alias: League\Flysystem\Filesystem
# config/packages/uploaded_file_type.yaml
uploaded_file_type:
  configurations:
    retail:
      filesystem: 'oneup_flysystem.default_filesystem'
      base_uri: 'https://www.example.com/upload'
      path: '/retail'

如果您在计算机上选择了图像logo.png后提交表单,文件将存储在public/upload/retail/logo.ee2a6cd0ed54b0f9e625698ae909d7ff.png中,而Retail::$logo将存储URL https://www.example.com/upload/retail/logo.ee2a6cd0ed54b0f9e625698ae909d7ff.png

报告问题或功能请求

问题和功能请求在Github问题跟踪器中跟踪。

报告错误时,在symfony/website-skeleton上重现它可能是个好主意,以便扩展包的开发者可以通过简单地克隆它并遵循一些步骤来重现问题。