Passando um parâmetro para filtrar e funções de ação

49

É uma maneira de passar meus próprios parâmetros para a função em add_filter ou add_action . Por exemplo, dê uma olhada no seguinte código:

function my_content($content, $my_param)
{
do something...
using $my_param here ...
return $content;
}
add_filter('the_content', 'my_content', 10, 1);

Posso passar meu próprio parâmetro? algo como:

add_filter('the_content', 'my_content($my_param)', 10, 1)

ou

add_filter('the_content', 'my_content', 10, 1, $my_param)
    
por Aakash Chakravarthy 17.03.2012 / 12:24
fonte

8 respostas

74

Por padrão, isso não é possível. Existem soluções alternativas se você fizer isso da maneira OOP.
Você pode criar uma classe para armazenar os valores que deseja usar posteriormente.

Exemplo:

/**
 * Stores a value and calls any existing function with this value.
 */
class WPSE_Filter_Storage
{
    /**
     * Filled by __construct(). Used by __call().
     *
     * @type mixed Any type you need.
     */
    private $values;

    /**
     * Stores the values for later use.
     *
     * @param  mixed $values
     */
    public function __construct( $values )
    {
        $this->values = $values;
    }

    /**
     * Catches all function calls except __construct().
     *
     * Be aware: Even if the function is called with just one string as an
     * argument it will be sent as an array.
     *
     * @param  string $callback Function name
     * @param  array  $arguments
     * @return mixed
     * @throws InvalidArgumentException
     */
    public function __call( $callback, $arguments )
    {
        if ( is_callable( $callback ) )
            return call_user_func( $callback, $arguments, $this->values );

        // Wrong function called.
        throw new InvalidArgumentException(
            sprintf( 'File: %1$s<br>Line %2$d<br>Not callable: %3$s',
                __FILE__, __LINE__, print_r( $callback, TRUE )
            )
        );
    }
}

Agora você pode chamar a classe com qualquer função que desejar - se a função existir em algum lugar, ela será chamada com seus parâmetros armazenados.

Vamos criar uma função de demonstração ...

/**
 * Filter function.
 * @param  array $content
 * @param  array $numbers
 * @return string
 */
function wpse_45901_add_numbers( $args, $numbers )
{
    $content = $args[0];
    return $content . '<p>' . implode( ', ', $numbers ) . '</p>';
}

… e use uma vez…

add_filter(
    'the_content',
    array (
        new WPSE_Filter_Storage( array ( 1, 3, 5 ) ),
        'wpse_45901_add_numbers'
    )
);

… e novamente…

add_filter(
    'the_content',
    array (
        new WPSE_Filter_Storage( array ( 2, 4, 6 ) ),
        'wpse_45901_add_numbers'
    )
);

Saída:

  

Achaveéreusabilidade:vocêpodereutilizaraclasse(eemnossosexemplostambémafunção).

PHP5.3+

SevocêpuderusarumaversãodoPHP5.3oumaisrecente, encerramentos facilitará muito:

$param1 = '<p>This works!</p>';
$param2 = 'This works too!';

add_action( 'wp_footer', function() use ( $param1 ) {
        echo $param1;
    }, 11 
);
add_filter( 'the_content', function( $content ) use ( $param2 ) {
        return t5_param_test( $content, $param2 );
    }, 12
);

/**
 * Add a string to post content
 *
 * @param  string $content
 * @param  string $string This is $param2 in our example.
 * @return string
 */
function t5_param_test( $content, $string )
{
    return "$content <p><b>$string</b></p>";
}

A desvantagem é que você não pode escrever testes unitários para encerramentos.

    
por fuxia 17.03.2012 / 19:32
fonte
1

Crie uma função com os argumentos necessários que retornem uma função. Passe esta função (função anônima, também conhecida como fechamento) para o gancho wp.

Mostrado aqui para um aviso de administração no backend do wordpress.

public function admin_notice_func( $message = '')
{
$class = 'error';
    $output = sprintf('<div class="%s"><p>%s</p></div>',$class, $message);
    $func = function() use($output) { print $output; };
    return $func;
}
$func = admin_notice_func('Message');
add_action('admin_notices', $func);
    
por hornament 20.01.2016 / 19:53
fonte
1

Eu sei que o tempo passou, mas tive algum problema ao passar meu próprio parâmetro até descobrir que o quarto parâmetro em add_filter é o número de parâmetros passados incluindo o conteúdo a ser alterado. Portanto, se você passar 1 parâmetro adicional, o número deverá ser 2 e não 1 no seu caso

add_filter('the_content', 'my_content', 10, 2, $my_param)

e usando

function my_content($content, $my_param) {...}
    
por giacoder 16.02.2017 / 13:48
fonte
0

se você criar seu próprio gancho, aqui está o exemplo.

// lets say we have three parameters  [ https://codex.wordpress.org/Function_Reference/add_filter ]
add_filter( 'filter_name', 'my_func', 10, 3 );
my_func( $first, $second, $third ) {
  // code
}

implemente o gancho:

// [ https://codex.wordpress.org/Function_Reference/apply_filters ]
echo apply_filters( 'filter_name', $first, $second, $third );
    
por T.Todua 14.05.2015 / 11:20
fonte
0

Use o php Funções anônimas :

$my_param = 'my theme name';
add_filter('the_content', function ($content) use ($my_param) {
    //$my_param is available for you now
    if (is_page()) {
        $content = $my_param . ':<br>' . $content;
    }
    return $content;
}, 10, 1);
    
por Wesam Alalem 23.01.2016 / 11:26
fonte
0

Você sempre pode usar o global, não consegue?

  global $my_param;
    
por samjco 25.08.2017 / 01:47
fonte
0

A maneira correta, realmente curta e mais eficiente de passar qualquer número de argumentos para os filtros e ações do WP é da @Wesam Alalem aqui , que usa o fechamento.

Gostaria apenas de acrescentar que você poderia torná-lo ainda mais claro e muito mais flexível, separando o método do usuário real do fechamento anônimo. Para isso, basta chamar o método do encerramento da seguinte forma (exemplo modificado da resposta @Wesam Alalem).

Dessa forma, você pode escrever uma lógica tão longa ou complicada quanto desejar, de forma lexical, fora do fechamento que você usa para chamar o executor real.

// ... inside some class

private function myMethod() {
    $my_param = 'my theme name';
    add_filter('the_content', function ($content) use ($my_param) {
        // This is the anonymous closure that allows to pass 
        // whatever number of parameters you want via 'use' keyword.
        // This is just oneliner.
        // $my_param is available for you now via 'use' keyword above
        return $this->doThings($content, $my_param);
    }, 10, 2);
}

private function doThings($content, $my_param) {
    // Call here some other method to do some more things
    // however complicated you want.
    $morethings = '';
    if ($content = 'some more things') {
        $morethings = (new MoreClass())->get();
    }
    return $my_param . ':<br>' . $content . $morethings;
}
    
por bob-12345 14.10.2018 / 18:10
fonte
-1

Eu estava esperando para fazer o mesmo, mas como não é possível, eu acho que uma solução simples é chamar uma função diferente como      add_filter('the_content', 'my_content_filter', 10, 1);

então my_content_filter () pode apenas chamar my_content () passando qualquer argumento que quiser.

    
por Pierre-Verthume Larivière 12.12.2017 / 22:24
fonte