首页 >后端开发 >php教程 >延长10月CMS-构建软耗尽插件

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

Joseph Gordon-Levitt
Joseph Gordon-Levitt原创
2025-02-10 10:21:14999浏览

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本身,也包括插件!

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

<code class="language-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();
    }
}</code>

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

<code class="language-php">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);
        });
    });
});</code>

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

Rainlab Blog 插件

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

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

创建新插件

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

<code class="language-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();
    }
}</code>

扩展数据库模式

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

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

<code class="language-php">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);
        });
    });
});</code>
<code class="language-bash">php artisan create:plugin rafie.blogplus</code>

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

扩展文章列表

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

<code class="language-yaml"># updates/version.yaml

1.0.1:
    - First version of blogplus.
    - create_posts_deleted_at_field.php</code>

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

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

Extending OctoberCMS - Building a Soft-Delete Plugin

扩展过滤器

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

<code class="language-php"># 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');
        });
    }
}</code>

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

可扩展类

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

<code class="language-php">// 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',
        ],
    ]);
});</code>

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

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

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

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

<code class="language-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();
    }
}</code>

Eloquent 事件

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

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

<code class="language-php">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);
        });
    });
});</code>

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

结论

本文快速概述了如何扩展 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