plank/快照

快照 Laravel 模型

v0.0.5 2024-08-19 15:54 UTC

This package is auto-updated.

Last update: 2024-08-26 02:51:14 UTC


README

PHP Version Support PHP Version Support GitHub Workflow Status

Laravel 快照

⚠️ 包处于积极开发中。请等待 v1.0.0 版本用于生产使用。⚠️

快照是一个 Laravel 扩展包,允许您通过复制数据库表及其内容来版本化应用程序的内容。每个快照都代表应用程序内容在特定时间点的可浏览版本。通过更改应用程序的激活版本,您可以在先前版本中查看应用程序的内容。

此包的主要目标是实现您内容的强大版本控制,但又不干扰您的操作。您应该能够在不更改现有代码库的情况下使用它。它应该易于安装和配置,并且易于使用。

目录

 

安装

您可以通过 composer 安装此包

composer require plank/snapshots

您可以使用包的安装命令来完成安装

php artisan snapshots:install

快速开始

安装完成后,要开始使用此包

  1. 将所有针对版本化内容的迁移扩展为 Plank\Snapshots\Migrations\SnapshotMigration,而不是框架的 Migration 类。
  2. 在这些迁移中,将 Illuminate\Database\Schema\Builder 的引用替换为 $this->schemaPlank\Snapshots\Facades\SnapshotSchema 以针对版本化内容。
  3. 将所有表示版本化内容的模型实现为 Plank\Snapshots\Contracts\Versioned 并使用 Plank\Snapshots\Concerns\AsVersionedContent 特性。
  4. 将所有不版本化但与版本化内容有关系的模型使用 Plank\Snapshots\Concerns\InteractsWithVersionedContent 特性。
  5. 创建一个中间件,根据请求设置应用程序的激活版本。

中间件示例

<?php

namespace App\Http\Middleware;

use Closure;
use Plank\Snapshots\Contracts\ManagesVersions;

class SetActiveVersion
{
    public function __construct(
        protected ManagesVersions $versions
    ) {
    }

    public function handle($request, Closure $next)
    {
        $version = $request->route('version');

        if ($version = $this->versions->byNumber($version)) {
            $this->versions->setActive($version);
        }

        return $next($request);
    }
}

现在,每次您创建新版本时,SnapshotDatabase 监听器将处理 VersionCreated 事件并运行所有版本化内容的迁移。它还将从表的先前版本复制内容到新版本。

 

配置

包的配置文件位于 config/snapshots.php。如果在安装期间未发布配置文件,您可以使用以下命令发布配置文件

php artisan vendor:publish --provider="Plank\Snapshots\SnapshotsServiceProvider" --tag="config"

版本模型

model 选项是用于存储应用程序版本的应用程序模型的完全限定类名。默认值是 Plank\Snapshots\Models\Version。提供的任何模型都必须实现 Plank\Snapshots\Contracts\Version 接口。

版本工厂

factory 选项是用于生成版本实例以用于测试和填充应用程序的模型工厂的完全限定类名。默认值是 Plank\Snapshots\Factories\VersionFactory

仓库

repository 选项是用于检索应用程序版本的仓库的完全限定类名。默认值是 Plank\Snapshots\Repository\VersionRepository。提供的任何仓库都必须实现 Plank\Snapshots\Contracts\ManagesVersions 接口。

自动迁移

“auto_migrate”选项决定当创建新版本模型时,包是否自动为所有版本化内容创建新表。该包提供了默认实现Plank\Snapshots\Listeners\SnapshotDatabase,但您可以提供自己的实现。

自动复制

“auto_copy”选项决定当创建新版本模型时,包是否自动将内容复制到新版本表中。

该包提供了默认实现Plank\Snapshots\Listeners\CopyTable,数据在数据库级别复制。

该包还附带Plank\Snapshots\Listeners\CopyModels,数据在模型级别复制。如果您在模型中有自定义逻辑需要在数据复制时运行,这很有用。

您也可以通过在配置文件中设置它来提供自己的实现。

 

用法

版本

契约和模型

快照通过Version模型进行标识和访问。该模型由包创建,或可以通过创建实现Plank\Contracts\Version合约的类并指定为配置文件中的model来由用户覆盖。

在使用此包的应用程序中,通常应指定一个“活动”的Version。活动Version将修改数据库表,其中将查询版本化内容。

事件
  • Plank\Events\VersionCreated
    • 在创建新版本模型后触发
    • 该包将其挂钩以运行所有版本化迁移,但可以通过将auto_migrate设置为false来禁用

仓库

ManagesVersions接口是迁移器所需的最小Version存储库接口。该包提供了一个实现此接口的VersionRepository类,但可以通过创建实现Plank\Contracts\ManagesVersions合约的类并在配置文件中指定为repository来由用户覆盖。

存储库负责查询现有版本和管理活动版本。它不用于创建新版本,因为那超出了包的范围。

迁移

快照迁移

此包添加了一个SnapshotMigration类,用于存放所有版本化内容的迁移。它允许SnapshotMigrator知道需要运行所有版本的迁移。

要使用它,只需让迁移类扩展SnapshotMigration而不是框架的Migration类。

<?php

use Plank\Snapshots\Facades\SnapshotSchema;
use Plank\Snapshots\Migrations\SnapshotBlueprint;
use Plank\Snapshots\Migrations\SnapshotMigration;

return new class extends SnapshotMigration
{
    public function up()
    {
        $this->schema->create('blocks', function (SnapshotBlueprint $table) {
            $table->id();
            $table->unsignedBigInteger('page_id');
            $table->string('name');
            $table->morphs('blockable');
            $table->timestamps();

            $table->foreign('page_id')->references('id')->onSnapshot('pages');
        });
    }

    public function down()
    {
        SnapshotSchema::dropIfExists('blocks');
    }
}

您会注意到在SnapshotMigration中,您有可用的$this->schema,它是SnapshotSchemaBuilder实例。它是框架的\Illuminate\Database\Schema\Builder类的包装器。您也可以使用SnapshotSchema外观,但您应仅在SnapshotMigration中使用它。

SnapshotMigrations允许您以熟悉的方式声明迁移,但底层将处理所有版本化。

您还会注意到SnapshotBlueprint类。这种蓝图类型存在是为了允许您使用->onSnapshot()方法定义来自版本化内容到版本化内容的外键。

限制
  1. 来自未版本化内容到版本化内容的关系的外键不能使用。这是因为存在多个表的版本,外键不知道要引用哪个版本。来自版本化内容到未版本化内容以及来自版本化内容到版本化内容的外键仍然可以使用。

  2. 需要注意的是,如果至少有一个相关模型是版本化的,则枢轴表也应进行版本化。这是因为枢轴表需要为相关模型的每个版本进行复制。

  3. 同样需要注意的是,如果您正在使用已版本化的自定义枢轴模型,则无法通过枢轴将未版本化的内容与未版本化的内容相关联。因此,在使用自定义多态枢轴模型时,请特别小心您要关联的内容。

 

快照迁移器

此包将用SnapshotMigrator类替换框架的迁移器。迁移器扩展了框架的迁移器,其唯一目的是确保为您的版本化内容运行迁移,适用于您应用的每个版本。

例如,在运行传统Laravel应用程序的迁移后,您可能会有以下情况

php artisan migrate

INFO  Preparing database.

Creating migration table ............................... 13ms DONE

INFO  Running migrations.

2023_09_25_000000_create_users_table ............................... 10ms DONE
2023_09_25_000001_create_roles_table ............................... 10ms DONE
2023_09_25_000002_create_pages_table ............................... 14ms DONE

然而,在使用快照的Laravel应用程序中,您在初始迁移后可能会有以下情况

php artisan migrate

INFO  Preparing database.

Creating migration table ............................... 13ms DONE

INFO  Running migrations.

2023_09_25_000000_create_users_table    ............................... 10ms DONE
2023_09_25_000001_create_roles_table    ............................... 10ms DONE
2023_09_25_000002_create_pages_table    ............................... 14ms DONE
2023_09_25_000002_create_versions_table ............................... 14ms DONE

当创建第一个Version模型时,假设页面内容是版本化的,并且将auto_migrate设置为true,则包将重新运行您的2023_09_25_000002_create_pages_table迁移,以用于新的Version

以下输出仅作为示例。迁移在后台运行,不会输出。

php artisan migrate

INFO  Running migrations.

v1_0_0_2023_09_25_000000_create_pages_table    ............................... 10ms DONE

最后,假设您添加了一个新的迁移2023_09_25_000003_add_slug_to_pages_table以向pages表添加slug列,并在部署时运行迁移。

php artisan migrate

INFO  Running migrations.

2023_09_25_000003_add_slug_to_pages_table         ............................... 10ms DONE
v1_0_0_2023_09_25_000003_add_slug_to_pages_table  ............................... 10ms DONE

迁移应用于您内容的所有版本,以实现版本间的一致性。

 

模型

版本化模型

此包提供了一个Plank\Snapshots\Contracts\Versioned接口和一个AsVersionedContent特性。对于应该进行版本化的模型,让它们实现Versioned接口,并使用AsVersionedContent特性。

此特性确保模型表的查询以活动版本的表前缀进行前缀。它还覆盖了枢轴关系,以使用版本化的枢轴表。

示例

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Plank\Snapshots\Concerns\AsVersionedContent;
use Plank\Snapshots\Contracts\Versioned;

class Page extends Model implements Versioned
{
    use AsVersionedContent;
}

未版本化模型

对于任何与版本化模型有关联的模型,您可以使用Plank\Snapshots\Concerns\InteractsWithVersionedContent特性。此特性确保当通过枢轴关联版本化模型时,使用版本化的枢轴表。

示例

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Plank\Snapshots\Concerns\InteractsWithVersionedContent;

class User extends Model
{
    use InteractsWithVersionedContent;

    public function pages()
    {
        return $this->belongsToMany(Page::class);
    }
}

 

贡献

有关详细信息,请参阅CONTRIBUTING

 

致谢

 

许可

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

 

安全漏洞

如果您在siren中发现安全漏洞,请发送电子邮件至security@plank.co。所有安全漏洞都将得到及时处理。

 

关注我们!

 

Plank专注于具有影响力的解决方案,为我们的客户及其用户提供引人入胜的体验。我们致力于数字空间中的创新、包容性和可持续性。了解更多关于我们改善网络使命的信息。