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

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
您如何防止与会议有关的跨站点脚本(XSS)攻击?您如何防止与会议有关的跨站点脚本(XSS)攻击?Apr 23, 2025 am 12:16 AM

要保护应用免受与会话相关的XSS攻击,需采取以下措施:1.设置HttpOnly和Secure标志保护会话cookie。2.对所有用户输入进行输出编码。3.实施内容安全策略(CSP)限制脚本来源。通过这些策略,可以有效防护会话相关的XSS攻击,确保用户数据安全。

您如何优化PHP会话性能?您如何优化PHP会话性能?Apr 23, 2025 am 12:13 AM

优化PHP会话性能的方法包括:1.延迟会话启动,2.使用数据库存储会话,3.压缩会话数据,4.管理会话生命周期,5.实现会话共享。这些策略能显着提升应用在高并发环境下的效率。

什么是session.gc_maxlifetime配置设置?什么是session.gc_maxlifetime配置设置?Apr 23, 2025 am 12:10 AM

thesession.gc_maxlifetimesettinginphpdeterminesthelifespanofsessiondata,setInSeconds.1)它'sconfiguredinphp.iniorviaini_set().2)abalanceIsiseededeedeedeedeedeedeedto to to avoidperformance andununununununexpectedLogOgouts.3)

您如何在PHP中配置会话名?您如何在PHP中配置会话名?Apr 23, 2025 am 12:08 AM

在PHP中,可以使用session_name()函数配置会话名称。具体步骤如下:1.使用session_name()函数设置会话名称,例如session_name("my_session")。2.在设置会话名称后,调用session_start()启动会话。配置会话名称可以避免多应用间的会话数据冲突,并增强安全性,但需注意会话名称的唯一性、安全性、长度和设置时机。

您应该多久再生一次会话ID?您应该多久再生一次会话ID?Apr 23, 2025 am 12:03 AM

会话ID应在登录时、敏感操作前和每30分钟定期重新生成。1.登录时重新生成会话ID可防会话固定攻击。2.敏感操作前重新生成提高安全性。3.定期重新生成降低长期利用风险,但需权衡用户体验。

如何在PHP中设置会话cookie参数?如何在PHP中设置会话cookie参数?Apr 22, 2025 pm 05:33 PM

在PHP中设置会话cookie参数可以通过session_set_cookie_params()函数实现。1)使用该函数设置参数,如过期时间、路径、域名、安全标志等;2)调用session_start()使参数生效;3)根据需求动态调整参数,如用户登录状态;4)注意设置secure和httponly标志以提升安全性。

在PHP中使用会议的主要目的是什么?在PHP中使用会议的主要目的是什么?Apr 22, 2025 pm 05:25 PM

在PHP中使用会话的主要目的是维护用户在不同页面之间的状态。1)会话通过session_start()函数启动,创建唯一会话ID并存储在用户cookie中。2)会话数据保存在服务器上,允许在不同请求间传递数据,如登录状态和购物车内容。

您如何在子域中分享会议?您如何在子域中分享会议?Apr 22, 2025 pm 05:21 PM

如何在子域名间共享会话?通过设置通用域名的会话cookie实现。1.在服务器端设置会话cookie的域为.example.com。2.选择合适的会话存储方式,如内存、数据库或分布式缓存。3.通过cookie传递会话ID,服务器根据ID检索和更新会话数据。

See all articles

热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

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

热工具

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!