it-swarm-ja.com

高度なadd_ *関数ラッパーの実装

add_action()add_filter()は主要な関数です。ただし、シナリオによっては関数をもう1つ追加してどこかにフックする方法は大きくて不便になります。

add_*関数の上にラッパーを使ってコードを合理化できるいくつかのユースケースを自分で決めました。毎回余分な機能よりもシングルライナーの方が扱いやすいもの。

  1. 任意のフィルタリターンを追加します。すでに__return_*関数がありますが、それらは定義によって非常に制限されています。あなたが欲しいものを単にfilterに渡してはいけません。無数のfunction return_stuff(){return 'stuff';}から節約

  2. フィルタ内でXをYに置き換えます。無数のfunction replace_stuff(){return str_replace();}から節約

  3. 任意の引数でアクションを追加します。アクションはフックで渡された引数で起動します。しかし時々あなたはそれを気にせず、単に特定のフックであなた自身の引数であなたの関数を走らせたいだけです。無数のfunction echo_stuff(){echo 'stuff'};などから節約できます。

そう...

  • あなたが望む、そして/または実際に使用する他のユースケースはありますか?

  • そのようなラッパーをどのように実装しますか?可能なアプローチはたくさんあります(クロージャ、追加の引数を保持するためのグローバル変数、コールバックでオブジェクトを渡すなど)。

PS(1)(3)の実装はすでにいくつかあります。提案された)はしばらくして私のコードの一部を投稿するので、私は楽しみを損なうことはない:)

現在の方法:

add_filter('wp_feed_cache_transient_lifetime', 'change_transient_lifetime', 10);

function change_transient_lifetime($lifetime) {

    return 3600;
}

ラッパー:

add_filter_return('wp_feed_cache_transient_lifetime', 10, 3600);
5
Rarst

私は自分のコードを Advanced Hooks API ライブラリとしてリリースしました。

いくつかの例:

add_action_with_arguments('test', 'printf', 10, 'boo%s', '<br />');
do_action('test');
// boo

add_filter_return('test2',10,'boo');
echo apply_filters('test2','not boo') . '<br />';
// boo

add_filter_append('test3',10,' and boo');
echo apply_filters('test3','boo') . '<br />';
// boo and boo

add_filter_prepend('test4',10,'boo and ');
echo apply_filters('test4','boo') . '<br />';
// boo and boo

add_filter_replace('test5','boo','you thought...');
echo apply_filters('test5','boo');
// you thought...
5
Rarst

クイックワンライナーリターンのような単純なケースでは、匿名関数を直接add filter呼び出しにフックすることが可能であることを覚えておいてください。例えば:

add_filter('some_filter_hook', function($v){return str_replace('..', '.', $v);});

add_action('some_action_hook', function(){echo '....';});
6
wyrfel

あなたは マジッククラスメソッドとPHPでのオーバーロード を調べたいと思うかもしれません。それならreturn__some_stringのような関数名に基づいて決定を下すことができます。

class magiCall {
    public static function __callStatic ( string $name , array $arguments ) {
        // your code here, $name is the function name called.
    }
}

add_filter('hookname', 'magiCall::return__the_string');

私はその例がそのアイデアをかなり示していると思います。

これはPHP 5.3.xです__callマジックメソッドを使ってこのPHP 5.2互換性を持たせることができます、そしてあなたがコールバックを返すために静的なパブリック関数を持っているなら、それを書くためには比較を単純化しました。上記のphpマニュアルへのリンクを参照してください。

5
hakre

匿名またはラムダ関数の広告)いずれにしても、名前がわからない場合や、非常に不可解な出力が表示される場合は避けてください。後でフックする。デバッグは面倒です。

Ad A)このアプローチは見栄えがよく、かなり単純なAPI(+1)を提供します。

Ad @hakre A)私のフレームワークのコアでもほぼ同じ関数[1]を使っています - "set_"と例外で拡張 - その場で変数を取得します。このように、私はこのクラスを「変数のみ」のインターフェースのように見える子クラス(利用可能になるもの)で拡張するだけでよいです。これは、単一のタスクを処理するものだけをファイルに保存するという、よく整理されたアプローチです。このようなものを使えば、 "_replace"などのようなすべてのtakに対して特定の関数を書くことを避けることができます。

[1]コード - これは常に実行されているので、「テスト済みで動作します」と呼ぶことができます

/**
 * Magic getter/setter method
 * Guesses for a class variable & calls/fills it or throws an exception.
 * Note: Already defined methods override this method.
 * 
 * Original @author Miles Keaton <[email protected]> 
 * on {@link http://www.php.net/manual/de/language.oop5.overloading.php#48440}
 * The function was extended to also allow 'set' tasks/calls and throws an exception.
 * 
 * @param (string) $name | Name of the property
 * @param unknown_type $args | arguments the function can take
 */
function __call( $name, $args )
{
    $_get = false;

    // See if we're calling a getter method & try to guess the variable requested
    if( substr( $val, 0, 4 ) == 'get_' )
    {
        $_get = true;
        $varname = substr( $val, 4 );
    }
    elseif( substr( $val, 0, 3 ) == 'get' )
    {
        $_get = true;
        $varname = substr( $val, 3 );
    }

    // See if we're calling a setter method & try to guess the variable requested
    if( substr( $val, 0, 4 ) == 'set_' )
    {
        $varname = substr( $val, 4 );
    }
    elseif( substr( $val, 0, 3 ) == 'set' )
    {
        $varname = substr( $val, 3 );
    }

    if ( ! isset( $varname ) )
        return new Exception( sprintf( __( "The method %1$s doesn't exist" ), "<em>{$val}</em>" ) );

    // Now see if that variable exists:
    foreach( $this as $class_var => $class_var_value )
    {
        if ( strtolower( $class_var ) == strtolower( $varname ) )
        {
            // GET
            if ( $_get )
            {
                return $this->{$class_var};
            }
            // SET
            else 
            {
                return $this->{$class_var} = $x[0];
            }
        }
    }

    return false;
}
0
kaiser

単純な戻り値のためにあなたは多くの追加の関数を必要としません。便利な current_filter() があります。あなたはそれをあなた自身の関数の中で使うことができます。

<?php # -*- coding: utf-8 -*-
/*
Plugin Name: Filter System From Mail
Description: Sets the WP from mail address to the first admin’s mail and the from name to blog name.
Version:     1.1
Author:      Thomas Scholz
Author URI:  http://toscho.de
License:     GPL
*/

if ( ! function_exists( 'filter_system_from_mail' ) )
{
    /**
     * First admin's e-mail address or blog name depending on current filter.
     *
     * @return string
     */
    function filter_system_from_mail()
    {
        return get_option( 'wp_mail_from' == current_filter()
            ? 'admin_email' : 'blogname' );
    }

    add_filter( 'wp_mail_from',      'filter_system_from_mail' );
    add_filter( 'wp_mail_from_name', 'filter_system_from_mail' );
}

それとも…あなたの質問を誤解しましたか?

0
fuxia