czim/laravel-paperclip

此包最新版本(5.0.6)没有可用的许可证信息。

Laravel Eloquent 文件附件解决方案

5.0.6 2024-09-16 11:52 UTC

README

Latest Version on Packagist Software License Build Status Coverage Status

Laravel Paperclip:文件附件解决方案

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

这是对CodeSleeve's 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);
    }
}

注意:如果您在调用 parent::__construct() 之后执行 hasAttachedFile() 调用(s),则一切都将按预期工作,但您不能在创建模型时直接分配图像。在这种情况下,ModelClass::create(['attachment' => ...]) 将不会工作。

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.<您的存储磁盘>,以便返回存储内容的有效URL。

处理前后的钩子

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

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

事件

以下事件可用

  • AttachmentSavedEvent:在将文件与任何附件一起保存时发出

刷新模型

当更改模型的变体配置时,可以使用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 trait使用自己的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)。有关更多信息,请参阅许可证文件