vildanbina/laravel-versions
Composer 安装命令:
composer require vildanbina/laravel-versions
包简介
A Laravel package for managing model drafts.
README 文档
README
Laravel Versions
Laravel Versions is a package that adds powerful draft and versioning capabilities to your Eloquent models. With this package, you can create drafts, manage versions, and publish changes to your models without affecting the currently published version. When a model is updated, it modifies the existing active draft instead of creating a new one for each change. If no active draft exists, a new one is created. Once you're ready, you can publish the draft to make it the active version while maintaining a history of all previous versions.
Requirements
- PHP >= 8.0
- Laravel 9.x, 10.x, or 11.x
Installation
You can install the package via Composer:
composer require vildanbina/laravel-versions
After installation, you need to publish the configuration file:
php artisan vendor:publish --provider="VildanBina\LaravelVersions\VersionsServiceProvider"
Database Migrations
The package provides schema macros to add the necessary columns to your tables. You'll need to update your existing migrations or create new ones to add the drafts columns to your models' tables.
To add the drafts columns to a table (e.g., posts), you can use the drafts() macro in your migration:
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class AddDraftsColumnsToPostsTable extends Migration { public function up() { Schema::table('posts', function (Blueprint $table) { $table->versionables(); }); } public function down() { Schema::table('posts', function (Blueprint $table) { $table->dropVersionables(); }); } }
After updating your migrations, run:
php artisan migrate
Configuration
The package includes a configuration file config/drafts.php that allows you to customize column names and the
authentication guard. Below is the default configuration:
<?php return [ 'column_names' => [ 'is_current' => 'is_current', 'is_published' => 'is_published', 'published_at' => 'published_at', 'uuid' => 'uuid', 'publisher_morph_name' => 'publisher', ], 'auth' => [ 'guard' => 'web', ], ];
You can customize these settings as needed.
Getting Started
Follow these steps to set up versioning for your models:
-
Install the package via Composer:
composer require vildanbina/laravel-versions
-
Publish the configuration file:
php artisan vendor:publish --provider="VildanBina\LaravelVersions\VersionsServiceProvider" -
Add the drafts columns to your database:
Create a new migration or update an existing one to include the
drafts()macro:<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class AddDraftsColumnsToPostsTable extends Migration { public function up() { Schema::table('posts', function (Blueprint $table) { $table->versionables(); }); } public function down() { Schema::table('posts', function (Blueprint $table) { $table->dropVersionables(); }); } }
Then run:
php artisan migrate
-
Update your model:
Implement the
Versionableinterface and use theHasVersionstrait:<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use VildanBina\LaravelVersions\Contracts\Versionable; use VildanBina\LaravelVersions\Concerns\HasVersions; class Post extends Model implements Versionable { use HasVersions; // Optionally, define excluded columns protected array $excludedColumns = ['created_at', 'updated_at']; }
-
Use the package in your application:
Now you can create, update, and publish drafts.
<?php // Create a new post (initially a draft) $post = Post::create(['title' => 'My First Post', 'content' => 'Hello World']); // Publish the postha $post->publish(); // Update the post, which modifies the existing draft or creates a new one $post->update(['content' => 'Updated content']); // Get the current draft $draft = $post->draft; // Publish the draft $draft->publish();
Usage
To enable versioning for a model, implement the Versionable interface and use the HasVersions trait provided by the
package.
Example with a Post Model
First, update your Post model:
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use VildanBina\LaravelVersions\Contracts\Versionable; use VildanBina\LaravelVersions\Concerns\HasVersions; class Post extends Model implements Versionable { use HasVersions; // Optionally, define excluded columns protected array $excludedColumns = ['created_at', 'updated_at']; }
The $excludedColumns property allows you to specify which columns should be excluded from being replaced when creating
drafts or exchanging data between drafts and published versions.
Core Functionality
Draft Management Workflow
- Single Active Draft: The package maintains a single active draft for each model instance. When you update a model, it modifies the existing active draft. If no active draft exists, a new one is created.
- Publishing: When you publish a draft, the changes are applied to the main published version. The data from the published version is then applied to the current draft to keep it as the previous version.
- New Draft After Publishing: After publishing, if you make new changes, a new draft is created. All subsequent changes are saved to this active draft until it is published.
Automatic Draft Creation
- When a model instance is updated, it modifies the existing active draft. If there is no active draft, a new one is created automatically.
- The
publish()method can be used to publish the draft, making it live.
UUID as Grouping Identifier
The uuid column serves as a unique identifier for each set of versions. This means that a published model and all its
related drafts share the same uuid, allowing you to group them together and track the history of a specific model
instance.
Model Events
The package includes model events such as publishing and published. You can attach custom logic to these events
using observers to handle additional tasks whenever a model is published or a draft is being published.
Core Methods and Relationships
Publishing
publish(): Publishes the current draft, updating the original model data and settingis_publishedandis_currentflags accordingly.
Retrieving Versions
revisions(): Returns a collection of all versions (drafts and published) associated with the model, providing easy access to the version history.draft(): Retrieves the current active draft version of the model, if available.published(): Retrieves the published version of the model.
Checking Draft Status
isDraft(): Returns a boolean indicating whether the current instance is a draft or not.draftWithoutSelf(): Retrieves drafts that are not the same as the current instance, helping you identify other drafts for the model.
User Associations
publisher(): Returns the user or entity that published the current version, allowing you to trace who made specific changes.
Additional Functionalities
getExcludedColumns(): Returns an array of columns that are excluded from being saved or overwritten when creating drafts. This ensures certain fields remain unchanged across versions.
Example Usage
Creating and Publishing a Model
<?php // Create a new post (initially a draft) $post = Post::create(['title' => 'Initial Title', 'content' => 'Initial Content']); // Publish the post $post->publish();
Updating a Model and Working with Drafts
<?php // Update the post, which modifies the existing draft or creates a new one $post->update(['title' => 'Updated Title']); // Get the current draft $draft = $post->draft; // Check if the post is a draft if ($draft->isDraft()) { echo "This post is currently a draft!"; } // Publish the updated draft $draft->publish();
Retrieving Version History
<?php // Get all versions (drafts and published) $revisions = $post->revisions; // Loop through revisions foreach ($revisions as $revision) { echo $revision->title . ' - ' . ($revision->is_published ? 'Published' : 'Draft'); }
Getting the Publisher
<?php // Get the user who published the post $publisher = $post->publisher;
Query Scopes
The package provides the following query scopes that can be used for querying models:
whereCurrent(): Retrieve records whereis_currentistrue.wherePublished(): Retrieve records whereis_publishedistrue.withoutCurrent(): Retrieve records whereis_currentisfalse.excludeRevision($revision): Exclude a specific revision from the query.
Examples
<?php // Retrieve all current posts (either published or drafts that are current) $currentPosts = Post::whereCurrent()->get(); // Retrieve all published posts $publishedPosts = Post::wherePublished()->get(); // Retrieve all drafts $drafts = Post::whereCurrent()->wherePublished(false)->get();
Tips & Best Practices
-
Using Transactions: When performing operations that involve multiple steps, it's recommended to use database transactions to ensure data consistency. If any step fails, all changes will be rolled back, preventing any incomplete versioning states.
<?php use Illuminate\Support\Facades\DB; DB::transaction(function () use ($post) { $post->update(['title' => 'Updated Title']); $post->publish(); });
-
Customizing Excluded Columns: Use the
$excludedColumnsproperty in your model to specify columns that should not be versioned, such as timestamps or other metadata. -
Handling Unique Constraints: Currently, the package doesn't manage unique constraints automatically. To ensure uniqueness (e.g., for slugs) only for published records, you can use a composite unique index combining
slugandis_published.Example Migration:
return new class extends Migration { public function up() { Schema::create('posts', function (Blueprint $table) { // other columns $table->unique(['slug', 'is_published'], 'posts_slug_is_published_unique'); }); } };
This setup ensures that only published posts have unique slugs, while drafts can share the same slug without conflicts.
This concise addition provides clear guidance on handling unique constraints and includes a practical example for developers to implement.
Extensibility and Customization
The package is designed to be flexible and can be customized to fit your application's needs.
Overriding Methods
You can extend the functionality by overriding methods in the HasVersions trait within your model.
Custom Events
Leverage the publishing and published model events to add custom logic when a draft is being published.
Customizing Authentication Guard
You can change the authentication guard used to associate the publisher by updating the auth.guard setting in the
config/drafts.php configuration file.
Observers
The package automatically handles the creating, saving, and published events via the VersionObserver to manage
the
draft lifecycle. If you need to customize this behavior, you can create your own observer or extend the existing one.
To Do
-
Handling Relationships: Implementing support for all relationships in the versioning process, allowing relationships to be included and managed across drafts and published versions.
-
Service for Detecting Changes: Create a service that can identify and compare all changes between different versions of a model, providing a clear history of what has changed across versions.
-
Enable/Disable Versioning: Add functionality to globally enable or disable the versioning system, for scenarios such as when super admins want to bypass the versioning process or temporarily deactivate it.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please e-mail vildanbina@gmail.com to report any security vulnerabilities instead of the issue tracker.
Credits
License
The MIT License (MIT). Please see License File for more information.
vildanbina/laravel-versions 适用场景与选型建议
vildanbina/laravel-versions 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 4.18k 次下载、GitHub Stars 达 32, 最近一次更新时间为 2024 年 10 月 05 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「versioning」 「laravel」 「models」 「drafts」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 vildanbina/laravel-versions 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 vildanbina/laravel-versions 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 vildanbina/laravel-versions 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Versioning behaviour for eloquent models
Wordpress Query Builder class library for custom models and data querying.
A decent, standards-compliant, Semantic Versioning (SemVer) parser and library
A package to better handle database operations via Eloquent Models.
Initiate versioning the database like code.
Automatically create git tag about your Laravel app version
统计信息
- 总下载量: 4.18k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 32
- 点击次数: 7
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2024-10-05