yii2tech / model-change
为 Yii2 提供模型数据和状态变更跟踪
Requires
- yiisoft/yii2: *
This package is auto-updated.
Last update: 2022-01-10 10:39:58 UTC
README
Yii2 模型变更跟踪扩展
此扩展为 Yii2 提供模型数据和状态变更跟踪。
有关许可信息,请查看 LICENSE 文件。
安装
安装此扩展的首选方式是通过 composer。
运行以下命令
php composer.phar require --prefer-dist yii2tech/model-change
或在您的 composer.json 文件的 require 部分添加以下内容
"yii2tech/model-change": "*"
to
用法
此扩展提供 Yii2 模型数据和状态变更跟踪。它提供了一种解决方案,可以在不修改模型类的情况下,从外部跟踪其事件,并允许任意启用或禁用。
想象以下场景:我们组合复杂的网页,内容基于数据库记录。因此,我们有一个管理面板,它为特定的页面内容部分提供设置,例如 'header'、'footer' 等,以及自定义页面和主菜单项。为了保持高性能,我们广泛使用缓存来缓存不同的页面和页面部分,避免对页面内容的常规数据库查询。然而,一旦某些记录从管理面板更改,缓存应该被失效,以便更改实际上可以出现在页面上。但是,每次内容数据库记录更改时清除整个缓存并不实用,因为系统管理员可能在单个用户会话中编辑多个记录,并且只有在他认为所有更改都已完成后才清除缓存。因此,我们希望在 Web 界面简单地显示一些通知,以提醒用户在更改出现在主站之前清除缓存。
将此类功能放在使用模型事件或行为修改的模型类中不好,因为这只会影响管理面板,不应该在主程序或控制台中消耗资源。这意味着应从外部动态分配响应模型保存和删除的模型事件处理程序。
控制器过滤器
上述用例可以使用 [[\yii2tech\modelchange\ModelChangeFilter]] 解决。作为过滤器,它可以附加到控制器或模块(包括应用程序本身)。
控制器配置示例
class PageController extends \yii\web\Controller { public function behaviors() { return [ 'modelChange' => [ 'class' => ModelChangeFilter::className(), 'except' => [ 'index', 'view' ], 'modelClasses' => [ 'app\models\Page' ], 'afterModelChange' => function ($event) { Yii::$app->getSession()->set('cacheFlushRequired', true); }, ], ]; } // ... }
现在,一旦在某个 PageController
动作运行期间保存了 app\models\Page
模型,会话标志 'cacheFlushRequired' 将被设置。应在管理页面布局中处理此标志,如下所示
<?php if (Yii::$app->session->get('cacheFlushRequired', false)) : ?> <div class="alert alert-warning"> You need to clear cache <?= Html::a('Clear Cache', ['/maintenance/flush-cache'], ['class' => 'btn btn-warning']) ?> </div> <?php endif; ?>
提示:如果控制器类中有
modelClass
属性,其值将自动选择为 [[\yii2tech\modelchange\ModelChangeFilter::$modelClasses]] 的值,因此可以省略它。
最后,在相关控制器操作中清除会话标志
class MaintenanceController extends \yii\web\Controller { public function actionFlushCache() { Yii::$app->cache->flush(); Yii::$app->getSession()->remove('cacheFlushRequired'); return $this->redirect(['index']); } }
您还可以将 [[\yii2tech\modelchange\ModelChangeFilter]] 附加到模块级别或整个应用程序本身
return [ 'as modelChange' => [ 'class' => 'yii2tech\modelchange\ModelChangeFilter', 'modelClasses' => [ 'app\models\Page', 'app\models\PageContent', 'app\models\MenuItem', ], 'afterModelChange' => function ($event) { Yii::$app->getSession()->set('cacheFlushRequired', true); }, ], // ... ];
当某些配置的模型在某个控制器操作中发生变化时,将执行afterModelChange
回调。
除了使用[[\yii2tech\modelchange\ModelChangeFilter::$afterModelChange]]回调,您还可以在过滤器拥有者范围内附加[[\yii2tech\modelchange\ModelChangeFilter::EVENT_AFTER_MODEL_CHANGE]]事件的处理器。例如:您可以创建以下控制器行为
use yii2tech\modelchange\ModelChangeFilter; use yii\base\Behavior; class ModelChangeLogBehavior extends Behavior { public function events() { return [ ModelChangeFilter::EVENT_AFTER_MODEL_CHANGE => 'afterModelChange' ]; } public function afterModelChange(ActionEvent $event) { $logMessage = 'modelId=' . $event->model->id . ' actionId=' . $event->action->id; Yii::info($logMessage); } }
然后,可以将此行为与[\yii2tech\modelchange\ModelChangeFilter]]一起附加
class PageController extends \yii\web\Controller { public function behaviors() { return [ 'modelChange' => [ 'class' => ModelChangeFilter::className(), 'modelClasses' => [ 'app\models\Page' ], ], 'modelChangeLog' => [ 'class' => ModelChangeLogBehavior::className(), ], ]; } // ... }
创建自定义解决方案
此扩展提供了[[\yii2tech\modelchange\ModelChangeTrait]]特性,其中包含创建您自己的外部模型更改跟踪器所需的基本功能。例如:您可以直接将此类功能绑定到特定的控制器类,而不是使用过滤器
class PageController extends \yii\web\Controller { use ModelChangeTrait; protected function defaultModelClasses() { return [ 'app\models\Page' ]; } public function beforeAction($action) { $this->attachModelEventListeners(); return parent::beforeAction($action); } public function afterAction($action, $result) { $result = parent::afterAction($action, $result); $this->detachModelEventListeners(); return $result; } protected function afterModelChange($event) { // handle model change } }