sibche/laravel-paperclip

该包最新版本(4.1.7)没有提供许可证信息。

Laravel Eloquent 文件附件解决方案

4.1.7 2020-07-07 14:12 UTC

README

Latest Version on Packagist Software License Build Status Coverage Status

Laravel Paperclip:文件附件解决方案

允许您将文件附加到 Eloquent 模型。

这是对 CodeSleeve 的 Stapler 的一次重制。[CodeSleeve's Stapler](https://github.com/CodeSleeve/stapler)。其主要目的是更易于复用和适应不同的 Laravel 版本。尽管名称如此,但这不应被视为与 Ruby 的 Paperclip 钩子相匹配。

它不是直接处理文件存储,而是使用 Laravel 的内部存储驱动和配置。

底层使用 czim/file-handling,可以使用该包及其(和您自定义的)任何变体进行操作。

版本兼容性

变更日志

查看变更日志.

安装

通过 Composer

$ composer require czim/laravel-paperclip

可以使用自动发现来自动注册服务提供程序。否则,您可以在 config/app.php 中手动注册服务提供程序。

<?php
   'providers' => [
        ...
        Czim\Paperclip\Providers\PaperclipServiceProvider::class,
        ...
   ],

发布配置文件

php artisan vendor:publish --provider="Czim\Paperclip\Providers\PaperclipServiceProvider"

设置和配置

模型准备

修改数据库以添加将要获得附件的模型的某些列。使用附件键名作为前缀。

一个示例迁移

<?php
    Schema::create('your_models_table', function (Blueprint $table) {
        $table->string('attachmentname_file_name')->nullable();
        $table->integer('attachmentname_file_size')->nullable();
        $table->string('attachmentname_content_type')->nullable();
        $table->timestamp('attachmentname_updated_at')->nullable();
    });

将这里的 attachmentname 替换为附件的名称。
如果您以前使用过 Stapler,这些属性应该很熟悉。

一个 <key>_variants 文本或 varchar 列是可选的

<?php
    $table->string('attachmentname_variants', 255)->nullable();

在创建大量变体的情况下,建议使用 text() 列。

如果已添加并配置为使用(更多内容请参见配置部分),则将存储有关变体的 JSON 信息。

附件配置

要将附件添加到模型中

  • 使其实现 Czim\Paperclip\Contracts\AttachableInterface
  • 使其使用 Czim\Paperclip\Model\PaperclipTrait
  • 在构造函数中配置附件(与 Stapler 非常相似)
<?php
class Comment extends Model implements \Czim\Paperclip\Contracts\AttachableInterface
{
    use \Czim\Paperclip\Model\PaperclipTrait;
    
    public function __construct(array $attributes = [])
    {
        $this->hasAttachedFile('image', [
            'variants' => [
                'medium' => [
                    'auto-orient' => [],
                    'resize'      => ['dimensions' => '300x300'],
                ],
                'thumb' => '100x100',
            ],
            'attributes' => [
                'variants' => true,
            ],
        ]);

        parent::__construct($attributes);   
    }
}

从版本 2.5.7 开始,也可以使用更易用的流畅对象语法来定义变体步骤

<?php
    use \Czim\Paperclip\Config\Variant;
    use \Czim\Paperclip\Config\Steps\AutoOrientStep;
    use \Czim\Paperclip\Config\Steps\ResizeStep;
    
    // ...

    $this->hasAttachedFile('image', [
        'variants' => [
            Variant::make('medium')->steps([
                AutoOrientStep::make(),
                ResizeStep::make()->width(300)->height(150)->crop(),
            ]),
            Variant::make('medium')->steps(ResizeStep::make()->square(100)),
        ],
    ]);

变体配置

大部分变体配置与 Stapler 几乎相同,因此应很容易进行转换。

从版本 2.6 开始,默认禁用 Stapler 配置支持,但可以通过将 paperclip.config.mode 设置为 'stapler' 启用对此的旧版支持。

有关配置的更多信息,请在此处查看.

自定义变体

文件处理器附带一些常见的变体策略,包括调整图像大小和从视频中截取屏幕截图。但是,可以轻松地添加自己的自定义策略来以任何所需方式操作文件。

变体处理由 文件处理器包 处理。查看其源代码以开始编写自定义变体策略。

存储配置

您可以通过设置 Laravel 存储(在 config/filesystems.php 中)并在 config/paperclip.php 配置文件中注册它来配置上传文件的存储位置。

请确保设置了 paperclip.storage.base-urls.<your storage disk>,以便返回存储内容的有效 URL。

处理前后的钩子

当文件被处理时,可以“挂钩”到纸夹操作。这可以通过使用before和/或after配置键来完成。在文件上传并本地存储后,但在处理变体之前调用“before”钩子;在所有变体都处理完毕时调用“after”钩子。

更多信息和示例请参阅配置部分

刷新模型

当更改模型的变体配置时,您可以使用paperclip:refresh Artisan命令重新处理以前创建的附件的变体。

示例

php artisan paperclip:refresh "App\Models\BlogPost" --attachments header,background

用法

一旦设置了模型的附件配置,只需将附件属性设置为该模型即可创建一个附件。

<?php
public function someControllerAction(Request $request) {
    
    $model = ModelWithAttachment::first();
    
    // You can set any UploadedFile instance from a request on
    // the attribute you configured a Paperclipped model for.
    $model->attachmentname = $request->file('uploaded');
    
    // Saving the model will then process and store the attachment.
    $model->save();
    
    // ...
}

不上传设置附件

通常,您会想将上传的文件设置为附件。如果您想在请求或文件上传的上下文中存储文件,可以使用以下方法

<?php
// You can use the built in SplFileInfo class:
$model->attachmentname = new \SplFileInfo('local/path/to.file');


// Or a file-handler class that allows you to override values:
$file = new \Czim\FileHandling\Storage\File\SplFileInfoStorableFile();
$file->setData(new \SplFileInfo('local/path/to.file'));
// Optional, will be derived from the file normally
$file->setMimeType('image/jpeg');
// Optional, the file's current name will be used normally
$file->setName('original-file-name.jpg');
$model->attachmentname = $file;


// Or even a class representing raw content
$raw = new \Czim\FileHandling\Storage\File\RawStorableFile();
$raw->setData('... string with raw content of file ...');
$raw->setMimeType('image/jpeg');
$raw->setName('original-file-name.jpg');
$model->attachmentname = $raw;

清除附件

为了防止意外删除,将附件设置为null不会销毁先前存储的附件。相反,您必须显式销毁它。

<?php
// You can set a special string value, the deletion hash, like so:
$model->attachmentname = \Czim\Paperclip\Attachment\Attachment::NULL_ATTACHMENT;
// In version 2.5.5 and up, this value is configurable and available in the config:
$model->attachmentname = config('paperclip.delete-hash');

// You can also directly clear the attachment by flagging it for deletion:
$model->attachmentname->setToBeDeleted();


// After any of these approaches, saving the model will make the deletion take effect.
$model->save();

与Stapler的差异

  • Paperclip不内部处理(s3)存储,就像Stapler那样。所有存储都通过Laravel的存储解决方案执行。您仍然可以使用S3(或任何其他存储磁盘),但您必须先在Laravel的存储配置中配置它。
    可以为不同的附件使用不同的存储磁盘。

  • Paperclip在存储附件属性上的string值时可能表现出略微不同的行为。它将尝试将字符串解释为URI(或dataURI),否则将字符串作为原始文本文件内容处理。

如果您想强制存储URL的内容而不让Paperclip解释它,您有一些选择。您可以使用Czim\FileHandling\Storage\File\StorableFileFactory@makeFromUrl方法及其返回值。
或者,您可以自己下载内容并将它们存储在Czim\FileHandling\Storage\File\RawStorableFile中(例如:(new RawStorableFile)->setData(file_get_contents('your-URL-here')))。您还可以将文件下载到本地磁盘,并通过一个\SplFileInfo实例将其存储在模型上(请参阅主readme页面上的示例)。

  • 不再提供convert_options配置设置。转换选项现在在变体策略级别处理。
    您可以为每个附件配置设置它们,或者修改变体策略以使用自定义的全局配置。

  • 刷新命令(php artisan paperclip:refresh)与Stapler的刷新命令非常相似,但它可以可选地接受一个--start #和/或--stop #选项,带有ID号码。这使得只刷新模型的一部分成为可能。
    在底层,刷新命令也不太可能耗尽内存(它使用生成器分块处理模型)。

  • Paperclip特质使用其自己的Eloquent boot方法,而不是全局模型的boot()。这使得Paperclip不太可能与其他特性和模型实现冲突。

Amazon S3缓存控制

如果您将Amazon S3用作附件的存储磁盘,请注意您可以在filesystems.disks.s3配置键的选项中设置Cache-Control头。例如,要将所有上传到S3的文件的max-age头设置为如下编辑config/filesystems.php

's3' => [
    'driver' => env('S3_DRIVER', 's3'),
    'key'    => env('S3_KEY', 'your-key'),
    'secret' => env('S3_SECRET', 'your-secret'),
    'region' => env('S3_REGION', 'your-region'),
    'bucket' => env('S3_BUCKET', 'your-bucket'),
    'visibility' => 'public',
    'options' => [
        'CacheControl' => 'max-age=315360000, no-transform, public',
    ],
],

升级指南

从1.5.*升级到2.5.*

预计升级时间:5-10分钟

更新依赖项

在您的composer.json文件中将czim/laravel-paperclip依赖项更新为^2.5

	"require": {
		...
		"czim/laravel-paperclip": "^2.5",
		...
	}

然后,在终端运行

composer update czim/laravel-paperclip --with-dependencies

此外,如果您直接使用 czim/file-handling 包,应将其升级到 ^1,0 版本,但请务必查看 变更日志

	"require": {
		...
		"czim/file-handling": "^1.0",
		...
	}

更新配置

更新您的 config/paperclip.php 文件,并替换

        // The base path that the interpolator should use
        'base-path' => ':class/:id_partition/:attribute',

        // The path to the original file to be interpolated. This will also\
        // be used for variant paths if the variant key is unset.
        'original' => ':class/:id_partition/:attribute/:variant/:filename',
        
        // If the structure for variant filenames should differ from the
        // original, it may be defined here.
        'variant'  => null,

现在应包含占位符以生成包括文件名的完整文件路径,而不是仅目录。请注意,这使得路径插值逻辑更符合 Stapler 的处理方式。

贡献

有关详细信息,请参阅 贡献指南

鸣谢

许可协议

MIT 许可协议(MIT)。有关更多信息,请参阅 许可文件