Roundcubeでフックを設置する方法を紹介します。
今回はsample_aプラグインにフックを設置し、それをsample_bから利用する例です。
sample_aは画面をもったプラグインでボタンをクリックしたら、フックを実行し
元の画面を再度表示するようにしています。
ソースは以下のようになります。
sample_a.php
rc = rcmail::get_instance();
//ローカライズ対応
$this->add_texts('localization/');
//タスクとしてsample_aを設定
$this->register_task('sample_a');
//タスクバーにボタンを追加
$this->add_button(array(
'command' => 'sample_a',
'label' => 'sample_a.sample',
), 'taskbar');
//sampleタスクの場合のみ、アクションのコールバックを登録
if($this->rc->task == 'sample_a'){
$this->register_action('index', array($this, 'action'));
$this->register_action('fook_test', array($this, 'action'));
}
}
public function action(){
if($this->rc->action === 'fook_test'){
$data = $this->rc->plugins->exec_hook('sample_hook', array('data_a' => 'hoge'));
error_log(print_r($data,true));
}
$this->rc->output->send('sample_a.index');
}
}
?>
index.html
sample_b.php
add_hook('sample_hook', array($this, 'set_data'));
}
public function set_data($args){
error_log(print_r($args,true));
$data['data_b'] = "foo";
return $data;
}
}
?>
①フックを設置するコードは以下の部分になります。
$data = $this->rc->plugins->exec_hook('sample_hook', array('data_a' => 'hoge'));
引数として配列を渡しています。
②フックを利用するコードは以下の部分になります。
function init(){
$this->add_hook('sample_hook', array($this, 'set_data'));
}
public function set_data($args){
error_log(print_r($args,true));
$data['data_b'] = "foo";
return $data;
}
このような配列が渡されてきます。
(
[data_a] => hoge
[abort] =>
)
渡された引数を処理して戻り値を返したりすることが出来ます。
戻り値はこのようになります。
(
[data_b] => foo
[data_a] => hoge
[abort] =>
)
exec_hookの定義が以下のようになっているため、戻り値が配列の場合は自動的に
渡された配列に足して返されます。
public function exec_hook($hook, $args = array())
{
if (!is_array($args))
$args = array('arg' => $args);
$args += array('abort' => false);
$this->active_hook = $hook;
foreach ((array)$this->handlers[$hook] as $callback) {
$ret = call_user_func($callback, $args);
if ($ret && is_array($ret))
$args = $ret + $args;
if ($args['abort'])
break;
}
$this->active_hook = false;
return $args;
}