事件与监听器
Chamilo 使用 Symfony 的事件系统来实现组件之间的解耦通信。
事件监听器
Chamilo 使用两个监听器位置:
src/CoreBundle/EventListener/— Symfony 内核/HTTP 监听器(请求、响应、异常、登录/登出、课程/会话访问等)。示例:CidReqListener、CourseAccessListener、LoginSuccessHandler、LogoutListener、ExceptionListener、ResourceDoctrineListener。src/CoreBundle/Entity/Listener/— 附加到特定实体的 Doctrine 实体监听器。示例:ResourceNodeListener、CourseListener、SessionListener、LanguageListener、UserListener、MessageListener。
根据您需要响应的内容选择合适的位置:HTTP 管道事件放在 EventListener/ 中;实体生命周期钩子放在 Entity/Listener/ 中。
事件订阅者
位于 src/CoreBundle/EventSubscriber/:
事件订阅者可以监听多个事件:
安全订阅者 — 处理登录/登出事件,追踪登录尝试
API 订阅者 — 对 API 请求进行前/后处理
Doctrine 订阅者 — 响应实体生命周期事件
Doctrine 生命周期事件
实体使用 #[ORM\HasLifecycleCallbacks] 来处理数据库级别的事件:
创建自定义监听器
要添加自定义行为:
在适当的 bundle 中创建监听器/订阅者类
在服务配置中将其标记为事件监听器或订阅者
实现处理方法
关键事件
kernel.request
每次 HTTP 请求
kernel.response
发送 HTTP 响应之前
security.interactive_login
用户登录时
doctrine.prePersist
实体首次保存之前
doctrine.postUpdate
实体更新之后
Chamilo 特定事件
这些事件由 Chamilo 自身的代码触发,是插件的主要集成点。常量定义在 Chamilo\CoreBundle\Event\Events 中。
Events::COURSE_CREATED
chamilo.event.course_created
课程创建后
Events::COURSE_ACCESS_CHECK
chamilo.course_access_check
用户访问课程之前
Events::COURSE_USER_SUBSCRIPTION_CHECK
chamilo.event.course_user_subscription_check
用户注册课程之前
Events::SESSION_RESUBSCRIPTION
chamilo.event.session_resubscription
用户尝试重新订阅会话时
Events::LOGIN_CREDENTIALS_CHECKED
chamilo.event.login_credentials_checked
登录凭据验证后
Events::LOGIN_CONDITION_CHECKED
chamilo.event.login_condition_checked
额外登录条件检查后
Events::DOCUMENT_ACTION
chamilo.event.document_action
文档工具栏渲染时
Events::DOCUMENT_ITEM_ACTION
chamilo.event.document_item_action
每个文件的操作按钮渲染时
Events::DOCUMENT_ITEM_VIEW
chamilo.event.document_item_view
文档打开查看时
Events::EXERCISE_REPORT_ACTION
chamilo.event.exercise_report_action
练习报告页面渲染操作链接时
Events::EXERCISE_ENDED
chamilo.event.exercise_ended
学习者提交练习后
Events::EXERCISE_QUESTION_ANSWERED
chamilo.event.question_answered
每个问题回答后
Events::LP_CREATED
chamilo.event.learning_path_created
学习路径创建后
Events::LP_ITEM_VIEWED
chamilo.event.learning_path_item_viewed
学习者打开学习路径项目时
Events::LP_ENDED
chamilo.event.learning_path_ended
学习者完成学习路径后
Events::ADMIN_BLOCK_DISPLAYED
chamilo.event.admin_block_displayed
管理员仪表板构建块列表时
Events::USER_CREATED
chamilo.event.user_created
用户账户创建后
Events::USER_UPDATED
chamilo.event.user_updated
用户账户更新后
Events::USER_DELETED
chamilo.event.user_deleted
用户账户删除后
Events::PORTFOLIO_ITEM_ADDED
chamilo.event.portfolio_item_added
作品集项目创建后
Events::NOTIFICATION_CONTENT_FORMATTED
chamilo_hook_event.notification_content
通知内容格式化时
插件示例:在文档查看器中添加按钮
本节将介绍如何通过事件订阅者让插件在现有的 Chamilo 页面中注入一个按钮,而无需修改核心代码。
场景
一个名为 MyViewer 的插件希望在课程文件管理器中的每个文档旁边添加一个“在 MyViewer 中打开”按钮。相关事件是 Events::DOCUMENT_ITEM_VIEW,由 Chamilo 在文档即将显示时触发,携带 CDocument 实体和一个可变的链接列表。
插件目录结构
主插件类 (src/MyViewerPlugin.php)
src/MyViewerPlugin.php)Plugin 基类提供了 isEnabled()、get($settingKey) 以及用于安装课程工具和设置的辅助方法。单例模式(static $instance)是 Chamilo 的标准约定,因为插件类也会在 Symfony 容器之外(在旧版 PHP 页面中)被实例化。
事件订阅者 (src/EventSubscriber/MyViewerEventSubscriber.php)
src/EventSubscriber/MyViewerEventSubscriber.php)addLink() 将 HTML 添加到数组中,Chamilo 的文档视图模板会将其与内置的“下载”和“预览”操作一起渲染。订阅者从不修改 Chamilo 核心文件。
注册
无需手动注册服务。Chamilo 的 config/services.yaml 全局启用了 Symfony 的 autoconfigure 标志,该标志会自动将任何实现 EventSubscriberInterface 的类标记为 kernel.event_subscriber。只要插件目录被加载(通过 Composer's classmap 或 PSR-4 自动加载),Symfony 会在下一次缓存清除时自动识别订阅者。
事件数据流转方式
多个插件可以独立订阅同一事件;每个插件都会向共享数据中添加内容,而无需了解其他插件。执行顺序遵循 Symfony 的优先级系统——如果顺序重要,可以在 getSubscribedEvents() 中将优先级整数作为处理程序元组的第二个元素传递:
最后更新于
这有帮助吗?