目录
关键要点
引言
Rainlab Blog 插件
创建新插件
扩展数据库模式
扩展文章列表
扩展过滤器
可扩展类
Eloquent 事件
结论
关于扩展 OctoberCMS 和构建软删除插件的常见问题
OctoberCMS 中软删除插件的用途是什么?
软删除功能与硬删除有何不同?
如何在 OctoberCMS 中实现软删除功能?
如何测试 OctoberCMS 中的软删除功能?
我可以将软删除功能与现有记录一起使用吗?
如何在 OctoberCMS 中恢复软删除的记录?
我可以在 OctoberCMS 中永久删除软删除的记录吗?
如何在 OctoberCMS 中查看所有记录,包括软删除的记录?
我可以在 OctoberCMS 中自定义 deleted_at 列的名称吗?
我可以在 OctoberCMS 中为某些记录禁用软删除功能吗?
首页 后端开发 php教程 延长10月CMS-构建软耗尽插件

延长10月CMS-构建软耗尽插件

Feb 10, 2025 am 10:21 AM

Extending OctoberCMS - Building a Soft-Delete Plugin

OctoberCMS:插件扩展性深度探索及软删除插件实战

开发者通常青睐易用且可扩展的CMS。OctoberCMS 秉持简洁至上的理念,为开发者和用户带来愉悦的体验。本文将演示OctoberCMS 的一些可扩展特性,并通过一个简单的插件扩展另一个插件的功能。

Extending OctoberCMS - Building a Soft-Delete Plugin

关键要点

  • OctoberCMS 提供了一个简洁易用的CMS,同时允许通过插件进行扩展。这种扩展性体现在开发者可以深入CMS内部机制的程度,包括修改其他开发者插件的功能。
  • Rainlab Blog 插件允许创建文章并将其分配到不同的类别。本教程演示如何扩展此插件,添加软删除功能,防止文章被永久删除,而是标记为“已删除”并记录时间戳。
  • 要创建软删除功能,需要创建一个新插件,并在数据库中添加一个 deleted_at 字段。此字段将保存文章删除的时间戳。然后,插件扩展文章列表以包含此新字段作为列,并添加一个过滤器来显示或隐藏已删除的文章。
  • 创建软删除功能的最后一步是拦截文章的删除操作,并更新 deleted_at 列。这是通过挂接到 Eloquent 触发的 deleting 事件来实现的,阻止记录的删除。取而代之的是,deleted_at 字段将更新为当前时间戳,并保存记录。

引言

每个CMS都有一个插件系统来扩展平台的功能,我们通过可以深入CMS内部机制的程度来衡量其扩展性。然而,我们这里讨论的不仅仅是CMS本身,也包括插件!

如果您构建一个插件,您需要确保其他开发者可以修改您的部分功能。例如,我们有一个博客插件,用户可以通过选择列表中的文章来发布文章。最好触发一个事件来表明已发布新文章,另一个开发者可以挂接到此事件,并通过电子邮件通知订阅的用户!

class Posts extends Controller
{
    public function index_onPublish()
    {
        if (($checkedIds = post('checked')) && is_array($checkedIds) && count($checkedIds)) {

            foreach ($checkedIds as $postId) {
                if ((!$post = Post::find($postId)) || !$post->canEdit($this->user))
                    continue;

                $post->publish();
                Event::fire('rainlab.blog.posts.published', [$post]);
            }

            Flash::success('Successfully published those posts.');
        }

        return $this->listRefresh();
    }
}
登录后复制
登录后复制
登录后复制

其他开发者可以监听此事件来处理已发布的文章。

Event::listen('rainlab.blog.posts.published', function($post) {
    User::subscribedTo($post)->each(function($user) use($post) {
        Mail::send('emails.notifications.post-published', ['user' => $user, 'post' => $post], function($message) use($user, $post) {
            $message->from('us@example.com', 'New post by ' . $user->name);

            $message->to($user->email);
        });
    });
});
登录后复制
登录后复制
登录后复制

我们将主要使用事件来挂接到请求周期的不同部分。让我们从一个具体的例子开始,以便更好地理解。

Rainlab Blog 插件

如果您使用过OctoberCMS一段时间,您一定知道Rainlab Blog插件。它允许您在后端添加文章并将其附加到类别,并且您可以使用组件在前端显示它们。

在文章列表页面,我们可以删除文章。但是,如果我们想软删除它们呢?让我们看看我们能否做到这一点,并了解更多关于OctoberCMS扩展性的知识。

创建新插件

使用脚手架助手命令创建一个新的插件用于我们的演示,并在Plugin.php文件中更新插件详细信息。

class Posts extends Controller
{
    public function index_onPublish()
    {
        if (($checkedIds = post('checked')) && is_array($checkedIds) && count($checkedIds)) {

            foreach ($checkedIds as $postId) {
                if ((!$post = Post::find($postId)) || !$post->canEdit($this->user))
                    continue;

                $post->publish();
                Event::fire('rainlab.blog.posts.published', [$post]);
            }

            Flash::success('Successfully published those posts.');
        }

        return $this->listRefresh();
    }
}
登录后复制
登录后复制
登录后复制

扩展数据库模式

谈到软删除时,首先想到的是数据库中需要存在的 deleted_at 字段列。

blogplus/updates 文件夹下创建一个名为 create_posts_deleted_at_field.php 的新文件,并更新 version.yaml 文件。

Event::listen('rainlab.blog.posts.published', function($post) {
    User::subscribedTo($post)->each(function($user) use($post) {
        Mail::send('emails.notifications.post-published', ['user' => $user, 'post' => $post], function($message) use($user, $post) {
            $message->from('us@example.com', 'New post by ' . $user->name);

            $message->to($user->email);
        });
    });
});
登录后复制
登录后复制
登录后复制
php artisan create:plugin rafie.blogplus
登录后复制

迁移类将更改 rainlab_blog_posts 表并添加我们的 deleted_at 列,其默认值为 null。不要忘记运行 php artisan plugin:refresh rafie.blogplus 命令才能使更改生效。

扩展文章列表

接下来,我们必须将我们的字段作为列添加到列表中以进行显示。OctoberCMS 为我们提供了一个事件来挂接,并更改当前显示的小部件(后端列表被认为是小部件)。

# updates/version.yaml

1.0.1:
    - First version of blogplus.
    - create_posts_deleted_at_field.php
登录后复制

注意:以上代码应放在 Plugin@boot 方法中。

我们有一个 if 语句来防止我们的代码在每个页面上执行,然后我们将一个新列添加到列表小部件中,我们还可以使用 removeColumn 方法删除任何现有的列。查看文档以了解可用的列选项列表。

Extending OctoberCMS - Building a Soft-Delete Plugin

扩展过滤器

文章列表顶部的栏允许用户使用日期、类别等过滤列表。在我们的例子中,我们需要一个过滤器来显示/隐藏已删除的文章。

# updates/create_posts_deleted_at_field.php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePostsDeletedAtField extends Migration
{
    public function up()
    {
        Schema::table('rainlab_blog_posts', function (Blueprint $table) {
            $table->timestamp('deleted_at')->nullable()->default(null);
        });
    }

    public function down()
    {
        Schema::table('rainlab_blog_posts', function (Blueprint $table) {
            $table->dropColumn('deleted_at');
        });
    }
}
登录后复制

您可以在文档中阅读更多关于列表过滤器的信息。上面的代码相当简单,只包含几个选项。但是,scope 属性应该是 Models\Post 模型实例中定义的查询范围方法的名称。

可扩展类

OctoberRainExtensionExtendableTrait trait 提供了一种神奇的方法来动态扩展现有类,方法是添加新的方法、属性、行为等。在我们的示例中,我们需要向文章模型添加一个新方法来处理我们的范围过滤器。

// plugin.php  在Plugin类的boot方法中

Event::listen('backend.list.extendColumns', function ($widget) {
    if (!($widget->getController() instanceof \Rainlab\Blog\Controllers\Posts)) {
        return;
    }

    $widget->addColumns([
        'deleted_at' => [
            'label' => 'Deleted',
            'type' => 'date',
        ],
    ]);
});
登录后复制

我们可以对 addDynamicPropertyasExtension 等做同样的事情。让我们刷新我们的文章列表,看看我们的更改是否有效。

Extending OctoberCMS - Building a Soft-Delete Plugin Extending OctoberCMS - Building a Soft-Delete Plugin

当然,我们还没有任何已删除的文章,因为我们需要完成最后一部分:拦截文章的删除操作,只更新 deleted_at 列。

提示:与其使用 scope 属性,您可以使用条件来指定一个简单的 where 条件。下面的代码与使用模型范围的效果相同。

class Posts extends Controller
{
    public function index_onPublish()
    {
        if (($checkedIds = post('checked')) && is_array($checkedIds) && count($checkedIds)) {

            foreach ($checkedIds as $postId) {
                if ((!$post = Post::find($postId)) || !$post->canEdit($this->user))
                    continue;

                $post->publish();
                Event::fire('rainlab.blog.posts.published', [$post]);
            }

            Flash::success('Successfully published those posts.');
        }

        return $this->listRefresh();
    }
}
登录后复制
登录后复制
登录后复制

Eloquent 事件

Eloquent 在每个操作(创建、更新、删除等)上都会触发一系列事件。在这种情况下,我们需要挂接到删除事件并阻止记录的删除。

删除记录时,在执行实际删除操作之前会触发 deleting 事件,之后会触发 deleted 事件。如果您在 deleting 事件中返回 false,则操作将中止。

Event::listen('rainlab.blog.posts.published', function($post) {
    User::subscribedTo($post)->each(function($user) use($post) {
        Mail::send('emails.notifications.post-published', ['user' => $user, 'post' => $post], function($message) use($user, $post) {
            $message->from('us@example.com', 'New post by ' . $user->name);

            $message->to($user->email);
        });
    });
});
登录后复制
登录后复制
登录后复制

现在我们准备测试最终结果!继续删除一些记录,然后转到文章列表页面,看看是否可以切换列表中的已删除项目。

结论

本文快速概述了如何扩展 OctoberCMS 平台的不同部分。您可以在文档的扩展插件部分阅读更多相关信息。如果您有任何问题或意见,请在下方留言!

关于扩展 OctoberCMS 和构建软删除插件的常见问题

OctoberCMS 中软删除插件的用途是什么?

OctoberCMS 中的软删除插件旨在防止永久性数据丢失。当您删除记录时,它不会从数据库中完全删除。相反,会为该记录设置一个 deleted_at 时间戳。这意味着从应用程序的角度来看,该记录被认为是“已删除”的,但如果需要,仍然可以检索到它。这在可能意外删除数据的场景中特别有用,因为它允许轻松恢复。

软删除功能与硬删除有何不同?

硬删除会永久地从数据库中删除记录,除非您有备份,否则无法恢复。另一方面,软删除只是将记录标记为已删除,而不会实际将其从数据库中删除。这允许您在需要时恢复记录。

如何在 OctoberCMS 中实现软删除功能?

要在 OctoberCMS 中实现软删除功能,您需要创建一个插件。这包括创建一个新插件,向数据库表添加 deleted_at 列,并更新您的模型以使用 SoftDeletes trait。然后,您可以使用模型上的 delete 方法来软删除记录,并使用 restore 方法来恢复它。

如何测试 OctoberCMS 中的软删除功能?

您可以通过创建单元测试来测试软删除功能。这包括创建一个新的测试用例,在数据库中创建一个新记录,软删除它,然后断言它仍然存在于数据库中,但被标记为已删除。

我可以将软删除功能与现有记录一起使用吗?

是的,您可以将软删除功能与现有记录一起使用。您只需要向现有的数据库表添加 deleted_at 列。所有现有记录的此列都将具有 null 值,表示它们尚未被删除。

如何在 OctoberCMS 中恢复软删除的记录?

要恢复软删除的记录,您可以使用模型上的 restore 方法。这将从记录中删除 deleted_at 时间戳,有效地“取消删除”它。

我可以在 OctoberCMS 中永久删除软删除的记录吗?

是的,您可以使用模型上的 forceDelete 方法永久删除软删除的记录。这将像硬删除一样从数据库中删除记录。

如何在 OctoberCMS 中查看所有记录,包括软删除的记录?

要查看所有记录,包括软删除的记录,您可以使用模型上的 withTrashed 方法。这将返回所有记录,无论它们是否已被软删除。

我可以在 OctoberCMS 中自定义 deleted_at 列的名称吗?

是的,您可以通过覆盖模型中的 getDeletedAtColumn 方法来自定义 deleted_at 列的名称。如果 deleted_at 不适合您的需求,这允许您使用不同的列名。

我可以在 OctoberCMS 中为某些记录禁用软删除功能吗?

是的,您可以使用模型上的 withoutGlobalScope 方法为某些记录禁用软删除功能。这允许您从软删除功能中排除某些记录。

以上是延长10月CMS-构建软耗尽插件的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

在PHP API中说明JSON Web令牌(JWT)及其用例。 在PHP API中说明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

JWT是一种基于JSON的开放标准,用于在各方之间安全地传输信息,主要用于身份验证和信息交换。1.JWT由Header、Payload和Signature三部分组成。2.JWT的工作原理包括生成JWT、验证JWT和解析Payload三个步骤。3.在PHP中使用JWT进行身份验证时,可以生成和验证JWT,并在高级用法中包含用户角色和权限信息。4.常见错误包括签名验证失败、令牌过期和Payload过大,调试技巧包括使用调试工具和日志记录。5.性能优化和最佳实践包括使用合适的签名算法、合理设置有效期、

会话如何劫持工作,如何在PHP中减轻它? 会话如何劫持工作,如何在PHP中减轻它? Apr 06, 2025 am 12:02 AM

会话劫持可以通过以下步骤实现:1.获取会话ID,2.使用会话ID,3.保持会话活跃。在PHP中防范会话劫持的方法包括:1.使用session_regenerate_id()函数重新生成会话ID,2.通过数据库存储会话数据,3.确保所有会话数据通过HTTPS传输。

描述扎实的原则及其如何应用于PHP的开发。 描述扎实的原则及其如何应用于PHP的开发。 Apr 03, 2025 am 12:04 AM

SOLID原则在PHP开发中的应用包括:1.单一职责原则(SRP):每个类只负责一个功能。2.开闭原则(OCP):通过扩展而非修改实现变化。3.里氏替换原则(LSP):子类可替换基类而不影响程序正确性。4.接口隔离原则(ISP):使用细粒度接口避免依赖不使用的方法。5.依赖倒置原则(DIP):高低层次模块都依赖于抽象,通过依赖注入实现。

在PHPStorm中如何进行CLI模式的调试? 在PHPStorm中如何进行CLI模式的调试? Apr 01, 2025 pm 02:57 PM

在PHPStorm中如何进行CLI模式的调试?在使用PHPStorm进行开发时,有时我们需要在命令行界面(CLI)模式下调试PHP�...

如何在系统重启后自动设置unixsocket的权限? 如何在系统重启后自动设置unixsocket的权限? Mar 31, 2025 pm 11:54 PM

如何在系统重启后自动设置unixsocket的权限每次系统重启后,我们都需要执行以下命令来修改unixsocket的权限:sudo...

解释PHP中的晚期静态绑定(静态::)。 解释PHP中的晚期静态绑定(静态::)。 Apr 03, 2025 am 12:04 AM

静态绑定(static::)在PHP中实现晚期静态绑定(LSB),允许在静态上下文中引用调用类而非定义类。1)解析过程在运行时进行,2)在继承关系中向上查找调用类,3)可能带来性能开销。

如何用PHP的cURL库发送包含JSON数据的POST请求? 如何用PHP的cURL库发送包含JSON数据的POST请求? Apr 01, 2025 pm 03:12 PM

使用PHP的cURL库发送JSON数据在PHP开发中,经常需要与外部API进行交互,其中一种常见的方式是使用cURL库发送POST�...

See all articles