自作プラグイン EntryKeywords のオプション設定画面を CSS で装飾したくて作業中。
マニュアルを見ていて add_action('admin_head ', '関数');
とすればいいはずと目星をつけていましたが、なぜか動いてくれません。2日以上悩み続けています。仕方がないので流れを追いかけてみることに。
結局動くまでには至っていませんが、せっかくなので仕組みをメモ。
登録
まず、関数 add_action
でフックに対応する関数の登録を行います。2.0.7 では add_filter
を呼び出すだけなので、実際の処理は 関数 add_filter
を見ます。定義は、/wp-includes/functions.php
にあります。
function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
global $wp_filter;
// check that we don't already have the same filter at the same priority
if ( isset($wp_filter[$tag]["$priority"]) ) {
foreach($wp_filter[$tag]["$priority"] as $filter) {
// uncomment if we want to match function AND accepted_args
// if ( $filter == array($function, $accepted_args) ) {
if ( $filter['function'] == $function_to_add ) {
return true;
}
}
}
// So the format is wp_filter['tag']['array of priorities']['array of ['array (functions, accepted_args)]']
$wp_filter[$tag]["$priority"][] = array('function'=>$function_to_add, 'accepted_args'=>$accepted_args);
return true;
}
フックの登録は、グローバル変数 $wp_filter に配列として登録されます。関数 add_filter
の処理は大きく2つに分かれていて、登録処理は後半の部分で行います。前半は重複して登録しないためのチェックです。
登録処理のコメントにもありますが、登録情報はフックと優先度で分類されています。また、関数にはオブジェクトのメンバー関数も登録できます。その場合は、array(オブジェクトインスタンス, 関数名)
という配列を使います。オブジェクトインスタンスは参照渡しする必要があります。そのため、PHP 4 では変数の頭に & をつけて明示的に参照渡しにする必要があります。
実行
登録した関数を実行するには、関数 do_action
を使います。この定義も /wp-includes/functions.php
にあります。
function do_action($tag, $arg = '') {
global $wp_filter;
$extra_args = array_slice(func_get_args(), 2);
if ( is_array($arg) )
$args = array_merge($arg, $extra_args);
else
$args = array_merge(array($arg), $extra_args);
merge_filters($tag);
if ( !isset($wp_filter[$tag]) ) {
return;
}
foreach ($wp_filter[$tag] as $priority => $functions) {
if ( !is_null($functions) ) {
foreach($functions as $function) {
$function_name = $function['function'];
$accepted_args = $function['accepted_args'];
if ( $accepted_args == 1 ) {
if ( is_array($arg) )
$the_args = $arg;
else
$the_args = array($arg);
} elseif ( $accepted_args > 1 ) {
$the_args = array_slice($args, 0, $accepted_args);
} elseif ( $accepted_args == 0 ) {
$the_args = NULL;
} else {
$the_args = $args;
}
$string = call_user_func_array($function_name, $the_args);
}
}
}
}
前半は飛ばして、後半の foreach
を見ます。
特定のフックに対する登録情報を順に処理しています。情報を取り出し、引数の処理をし、最後に組み込み関数 call_user_func_array
で関数をコールします。
どこまでは動いているのか
調べた結果、少なくとも add_filter
での重複チェックを通過していることはわかりました。最後の return
の直前($wp_filter への登録直後)で $wp_filter[$tag]["$priority"] の値を表示させて確認しました。
add_action
を経由しないで直接登録した場合ではきちんと動作しましたので、何らかの理由により登録を削除されているのではないかと考えています。