ashleydawson / doctrine-gaufrette-storable-bundle
Symfony2 扩展包,为 doctrine 实体添加存储行为,以便于抽象化文件存储
Requires
- php: >=5.4.0
- doctrine/orm: ~2.3
- knplabs/knp-gaufrette-bundle: 0.1.*
- symfony/symfony: ~2.3
Requires (Dev)
- phpunit/phpunit: 4.2.6
This package is auto-updated.
Last update: 2024-09-14 03:58:40 UTC
README
需求
>= PHP 5.4
>= Symfony Framework 2.3
Doctrine 支持
- 对 Doctrine ORM 的支持 - 完整
- 对 Doctrine ODM 的支持 - 不完整
简介
我构建了这个扩展包来扩展优秀的文件系统抽象层,Knp Lab 的 Gaufrette。实际上,这个库扩展了 KnpGaufretteBundle。
这个扩展包在 Doctrine 实体上实现了一个“上传文件”处理器,允许 Gaufrette 将文件作为 Doctrine 实体生命周期的一部分进行存储。
这个扩展包的主要类是应用于任何 Doctrine 实体的一个 特质,使得 Gaufrette 处理器能够与实体一起持久化文件详情。
安装
您可以通过 Composer 安装 Doctrine Gaufrette Storable Bundle。为此,只需在您的 composer.json 文件中像这样要求包
{ "require": { "ashleydawson/doctrine-gaufrette-storable-bundle": "0.8.*" } }
运行 composer update 以安装包。然后您需要将包注册到您的 app/AppKernel.php 中
$bundles = array( // ... new Knp\Bundle\GaufretteBundle\KnpGaufretteBundle(), // KnpGaufretteBundle is a dependency of this bundle new AshleyDawson\DoctrineGaufretteStorableBundle\AshleyDawsonDoctrineGaufretteStorableBundle(), );
配置
接下来,您需要配置至少一个文件系统来存储文件。下面我将提供一个示例,然而,更好的示例可以在 Gaufrette Bundle 文档 中找到。
# app/config/config.yml knp_gaufrette: adapters: local_adapter: local: directory: /tmp/sandbox filesystems: test_local_filesystem: adapter: local_adapter
用法
为了使用此扩展包,您必须将给定的特质应用于希望携带上传文件的实体。
<?php namespace Acme\DemoBundle\Entity; use Doctrine\ORM\Mapping as ORM; use AshleyDawson\DoctrineGaufretteStorableBundle\Model\UploadedFileTrait; /** * Post * * @ORM\Table() * @ORM\Entity */ class Post { /** * Use the uploaded file trait */ use UploadedFileTrait; /** * @var integer * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @var string * * @ORM\Column(name="title", type="string", length=255) */ private $title; /** * Get id * * @return integer */ public function getId() { return $this->id; } /** * Set title * * @param string $title * @return Post */ public function setTitle($title) { $this->title = $title; return $this; } /** * Get title * * @return string */ public function getTitle() { return $this->title; } /** * Get the Gaufrette filesystem map id as * configured in https://github.com/KnpLabs/KnpGaufretteBundle#configuring-the-filesystems * * @return string */ public function getFilesystemMapId() { return 'test_local_filesystem'; } }
特质将为实体添加四个字段
- file_name : 字符串
- 客户端上传的文件的原始名称
- 例如:foobar.gif
- file_storage_path : 字符串
- 文件的存储路径。默认为文件名(如上所述)
- 例如:/path/to/foobar.gif
- file_mime_type : 字符串
- 客户端上传的文件的解析 MIME 类型
- 例如:image/gif
- file_size : 整数
- 以字节为单位的文件大小
- 例如:2324
在使用此实体之前,您需要更新您的模式。
app/console doctrine:schema:update [--force | --dump-sql]
抽象方法 getFilesystemMapId()
定义了 Gaufrette 文件系统 ID,其中您希望与该实体关联的文件被存储(在 knp_gaufrette 配置中定义)。
表单类型
使用实体与表单类型的示例
<?php namespace Acme\DemoBundle\Form; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolverInterface; /** * Class PostType * @package Acme\DemoBundle\Form */ class PostType extends AbstractType { /** * {@inheritdoc} */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('title', 'text') ->add('uploaded_file', 'file', [ 'required' => false, ]) ; } /** * {@inheritdoc} */ public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver ->setDefaults([ 'data_class' => 'Acme\DemoBundle\Entity\Post', ]) ; } /** * {@inheritdoc} */ public function getName() { return 'post'; } }
注意:名为 "uploaded_file" 的字段映射到 AshleyDawson\DoctrineGaufretteStorableBundle\Model\UploadedFileTrait
中的参数。如果您想更改此,只需添加一个访问器到您的实体作为代理即可
<?php namespace Acme\DemoBundle\Entity; use Doctrine\ORM\Mapping as ORM; use AshleyDawson\DoctrineGaufretteStorableBundle\Model\UploadedFileTrait; use Symfony\Component\HttpFoundation\File\UploadedFile; /** * Post * * @ORM\Table() * @ORM\Entity */ class Post { /** * Use the uploaded file trait */ use UploadedFileTrait; // ... /** * Set my file * * @param \Symfony\Component\HttpFoundation\File\UploadedFile $file * @return $this */ public function setMyFile(UploadedFile $file = null) { $this->setUploadedFile($file); return $this; } }
然后您可以像这样向表单类型添加新名称
// ... /** * {@inheritdoc} */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('title', 'text') ->add('my_file', 'file', [ 'required' => false, ]) ; } // ...
事件
存储处理器( Doctrine 实体生命周期的一部分)在文件存储活动的边缘触发几个事件。这些事件包括
- ad_doctrine_gaufrette_storable.pre_write
- 在文件写入文件系统之前触发
- ad_doctrine_gaufrette_storable.post_write
- 在文件写入文件系统之后触发
- ad_doctrine_gaufrette_storable.pre_delete
- 在文件从文件系统中删除之前触发
- ad_doctrine_gaufrette_storable.post_delete
- 在文件从文件系统中删除之后触发
这些事件可以在 AshleyDawson\DoctrineGaufretteStorableBundle\Event\StorageEvents
命名空间中找到。
这些事件的一个良好用例是在表单写入之前更改其任何细节,例如(在Symfony控制器内部):
// Replace the file storage path with a random md5 hash directory structure, name and file extension $this->get('event_dispatcher')->addListener(StorageEvents::PRE_WRITE, function (WriteUploadedFileEvent $event) { // Build a directory structure like "af/9e" $fileStoragePath = implode('/', str_split(substr(md5(mt_rand()), 0, 4), 2)); $event->setFileStoragePath(sprintf('/%s/%s.%s', $fileStoragePath, md5(mt_rand()), $event->getFileExtension())); });
当然,这是一个粗略的例子 - 但它确实展示了如何更改文件(或关于文件的元信息)。在上面的例子中,我正在构建一个存储路径的哈希目录结构。类似于这样:
/af/9e/2997f54d953111d222c00a0b6ed94a50.gif
注意:请不要将上述示例用作生产解决方案,因为存在文件名冲突的风险。
也可能是一个好主意,使用订阅者而不是像我上面那样使用基于闭包的实现。你应该始终致力于创建一个促进单一责任原则的系统!