私が達成しようとしているのは、高度にモジュール化されたアプリケーションを作成することです。すべてのサブモジュールで起動する必要があるすべての cron スクリプトに対処する cron スクリプトを作成しようとしています。私が実際にやりたいことは、イベントを作成することです。たとえばrunCron
、それが a から起動され、メソッドを使用CController
してサブモジュール内から発生したときにそれにフックしonRunCron
ます。私がやろうとしていることの概要:
Application
|- CronController.php - Raise the event 'RunCron', not knowing which modules will fire after this.
|- Modules
|- Nodes
|- Observe the event 'onRunCron' and run own cron script
|- Users
|- Observe the event 'onRunCron' and run own cron script
私が Yii のイベント システムに従って行う必要があると思うのは、イベントを作成し、それをアプリケーション レベルで発生させることです (それはまだ私がやろうとしていることです)。また、サブモジュールからのコールバックをコントローラーのアプリケーション レベルで割り当てる必要があります。サブモジュールが追加/削除されると、アプリケーションを調整する必要があり、モジュラーのように聞こえないため、これは望ましくありません。
このようなイベントを設定し、可能な限りモジュール化するための基本を説明してくれる人はいますか? 私はこれを完全に間違った方法で見ていると思うので。
編集(解決策):
acorncom's answer のおかげで、私は次のシステムを解決することができました。
application.components.CronSingleton
<?php
class CronSingleton extends CApplicationComponent {
/**
* Make sure we "touch" the modules, so they are initialised and are able to attach their listeners.
*/
public function touchModules () {
$modules = Yii::app()->getModules();
if (!empty($modules)) {
foreach ($modules as $name => $module) {
Yii::app()->getModule($name);
}
}
}
/**
* This method should be run to run the cron. It will commense all the procedures in cronjobs
*/
public function execCron($caller) {
$this->touchModules();
$this->onStartCron(new CEvent($caller));
$this->onRunCron(new CEvent($caller));
$this->onExitCron(new CEvent($caller));
}
/**
* Raise an event when starting cron, all modules should add their listeners to this event if they would like to fire something before running the cron.
*/
public function onStartCron ($event) {
$this->raiseEvent('onStartCron', $event);
}
/**
* Raise an event when running cron, all modules should add their listeners to this event to execute during cron run. Mosty this event should be used.
*/
public function onRunCron ($event) {
$this->raiseEvent('onRunCron', $event);
}
/**
* Raise an event when cron exits, all modules should add their listeners to this event when cron exits.
*/
public function onExitCron ($event) {
$this->raiseEvent('onExitCron', $event);
}
}
?>
アプリケーション.コントローラー.CronController
<?php
class CronController extends Controller
{
public $layout='//layouts/bare';
public function actionIndex($k) {
Yii::app()->cron->onStartCron = array($this, 'startcron');
Yii::app()->cron->onRunCron = array($this, 'runcron');
Yii::app()->cron->onExitCron = array($this, 'exitcron');
Yii::app()->cron->execCron($this);
}
public function startcron(){
var_dump('CronController - Starting cron');
}
public function runcron(){
var_dump('CronController - Run cron');
}
public function exitcron(){
var_dump('CronController - Ending cron');
}
}
?>
application.modules.admin.AdminModule
<?php
class AdminModule extends CWebModule
{
public function init()
{
// this method is called when the module is being created
// you may place code here to customize the module or the application
// import the module-level models and components
$this->setImport(array(
'admin.models.*',
'admin.components.*',
));
Yii::app()->cron->onRunCron = array($this, 'runCron');
}
public function runCron($event) {
var_dump('AdminModule - Run cron');
}
public function beforeControllerAction($controller, $action)
{
if(parent::beforeControllerAction($controller, $action))
{
// this method is called before any module controller action is performed
// you may place customized code here
return true;
}
else
return false;
}
}
?>
この「概念実証」セットアップは、まさに私がやりたかったことである、次の結果を出力することに成功しました。
string(30) "CronController - Starting cron"
string(25) "CronController - Run cron"
string(22) "AdminModule - Run cron"
string(28) "CronController - Ending cron"