oddvalue/laravel-drafts

为 Laravel 模型提供的简单、即插即用的草稿/修订系统

v2.0.0 2024-06-06 11:31 UTC

README

为 Laravel 模型提供的简单、即插即用的草稿/修订系统

Latest Version on Packagist PHP Support Laravel Support GitHub Tests Action Status GitHub Code Style Action Status Total Downloads Coverage

版本兼容性

安装

您可以通过 composer 安装此包

composer require oddvalue/laravel-drafts

您可以使用以下命令发布配置文件

php artisan vendor:publish --tag="drafts-config"

这是已发布配置文件的内容

return [
    'revisions' => [
        'keep' => 10,
    ],

    'column_names' => [
        /*
         * Boolean column that marks a row as the current version of the data for editing.
         */
        'is_current' => 'is_current',

        /*
         * Boolean column that marks a row as live and displayable to the public.
         */
        'is_published' => 'is_published',

        /*
         * Timestamp column that stores the date and time when the row was published.
         */
        'published_at' => 'published_at',

        /*
         * UUID column that stores the unique identifier of the model drafts.
         */
        'uuid' => 'uuid',

        /*
         * Name of the morph relationship to the publishing user.
         */
        'publisher_morph_name' => 'publisher',
    ],

    'auth' => [
        /*
         * The guard to fetch the logged-in user from for the publisher relation.
         */
        'guard' => 'web',
    ],
];

使用

准备你的模型

添加特质

HasDrafts 特质添加到您的模型中

<?php

use Illuminate\Database\Eloquent\Model;
use Oddvalue\LaravelDrafts\Concerns\HasDrafts;

class Post extends Model
{
    use HasDrafts;
    
    ...
}

关系

该包可以处理与其他模型的基本关系。当草稿发布时,HasOneHasMany 关系将被复制到已发布的模型中,而 BelongsToManyMorphToMany 关系将被同步到已发布的模型中。为了实现这一点,您首先需要在模型上设置 $draftableRelations 属性。

protected array $draftableRelations = [
    'posts',
    'tags',
];

或者您也可以重写 getDraftableRelations 方法。

public function getDraftableRelations()
{
    return ['posts', 'tags'];
}

数据库

以下数据库列对于模型存储草稿和修订是必需的

  • is_current
  • is_published
  • published_at
  • uuid
  • publisher_type
  • publisher_id

这些列的名称可以在配置文件中或使用常量按模型更改

例如,要更改 is_current 列的名称,则您需要添加一个名为 IS_CURRENT 的类常量

<?php

use Illuminate\Database\Eloquent\Model;
use Oddvalue\LaravelDrafts\Concerns\HasDrafts;

class Post extends Model
{
    use HasDrafts;
    
    public const IS_CURRENT = 'admin_editing';
    
    ...
}

为迁移中使用的 schema 构建器添加了两个辅助方法,可为您添加/删除所有这些列

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
 
Schema::table('posts', function (Blueprint $table) {
    $table->drafts();
});
 
Schema::table('posts', function (Blueprint $table) {
    $table->dropDrafts();
});

API

HasDrafts 特质将添加一个默认范围,该范围将仅返回已发布/活动记录。

以下查询构建器方法可用于更改此行为

  • withoutDrafts()/published(bool $withoutDrafts = true) 仅选择已发布的记录(默认)
  • withDrafts(bool $withDrafts = false) 包含草稿记录
  • onlyDrafts() 仅选择草稿,排除已发布

创建新记录

默认情况下,新记录将作为已发布创建。您可以通过在模型属性中包含 'is_published' => false 或使用 createDraftsaveAsDraft 方法来更改此行为。

Post::create([
    'title' => 'Foo',
    'is_published' => false,
]);

# OR

Post::createDraft(['title' => 'Foo']);

# OR

Post::make(['title' => 'Foo'])->saveAsDraft();

在保存/更新记录时,将保持已发布状态。如果您想保存已发布记录的草稿,则可以使用 saveAsDraftupdateAsDraft 方法。

# Create published post
$post = Post::create(['title' => 'Foo']);

# Create drafted copy

$post->updateAsDraft(['title' => 'Bar']);

# OR

$post->title = 'Bar';
$post->saveAsDraft(); 

这将创建一个草稿记录,而原始记录将保持不变。

与记录交互

已发布修订

已发布修订是记录的实时版本,将是向公众显示的内容。默认行为是仅显示已发布修订。

# Get all published posts
$posts = Post::all();

当前修订

每条记录都有一个当前修订。这是最新的修订,您想在管理员中显示的内容。

要获取当前修订,您可以调用 current 范围。

$posts = Post::current()->get();

修订

每次更新记录时,都会插入一个新的行/修订。默认保留的修订数是 10,这可以在已发布的配置文件中更新。

您可以通过调用 revisions 方法来获取记录的修订版本。

$post = Post::find(1);
$revisions = $post->revisions();

删除记录也会删除其所有修订版本。软删除记录将软删除修订版本,恢复记录将恢复修订版本。

如果您需要在没有创建修订版本的情况下更新记录

$post->withoutRevision()->update($options);

预览模式

启用预览模式将禁用仅获取已发布记录的全局作用域,并将改用获取当前修订版本,而不考虑发布状态。

# Enable preview mode
\Oddvalue\LaravelDrafts\Facades\LaravelDrafts::previewMode();
\Oddvalue\LaravelDrafts\Facades\LaravelDrafts::previewMode(true);

# Disable preview mode
\Oddvalue\LaravelDrafts\Facades\LaravelDrafts::disablePreviewMode();
\Oddvalue\LaravelDrafts\Facades\LaravelDrafts::previewMode(false);

中间件

WithDraftsMiddleware

如果您需要特定路由能够访问草稿,则可以使用 WithDraftsMiddleware 中间件。

Route::get('/posts/publish/{post}', [PostController::class, 'publish'])->middleware(\Oddvalue\LaravelDrafts\Http\Middleware\WithDraftsMiddleware::class);

路由器上还有一个辅助方法,允许您创建应用了该中间件的组。

Route::withDrafts(function (): void {
    Route::get('/posts/publish/{post}', [PostController::class, 'publish']);
});

测试

composer test

变更日志

请参阅 变更日志 了解最近的变化信息。

贡献

请参阅 贡献指南 了解详细信息。

安全漏洞

请查看 我们的安全策略 了解如何报告安全漏洞。

鸣谢

许可协议

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