Como obter valores de entrada do shortcode dentro de um filtro?

10

Estou tentando obter o valor de entrada de um shortcode dentro de uma função que é usada por um filtro, mas parece não haver êxito. Aqui está o que eu fiz:

function my_shortcode_function($atts){
    $value = $atts['id'];
    function filter_value(){
        echo $value;
    }
    add_filter('posts_where','filter_value');
}
add_shortcode('my-shortcode','my_shortcode_function');

Agora eu sei que usar $value dentro de filter_value() não funcionará por causa dos escopos de variável, mas mesmo usando $GLOBALS['value'] não funciona.

Eu até tentei usar $value = $atts['id'] dentro do filter_value(); , mas também não tive sucesso.

Como posso usar meu shortcode como [my-shortcode id='123'] e passar o valor 123 para o filtro?

Obrigado.

    
por Jack Johansson 15.05.2017 / 03:39

4 respostas

7

O uso de uma variável global funcionará. Aqui está uma demonstração:

function wpse_shortcode_function( $atts ){
    // User provided values are stored in $atts.
    // Default values are passed to shortcode_atts() below.
    // Merged values are stored in the $a array.
    $a = shortcode_atts( [
                'id'   => false,
    ], $atts );

    // Set global variable $value using value of shortcode's id attribute.
    $GLOBALS['value'] = $a['id'];

    // Add our filter and do a query.
    add_filter( 'posts_where', 'wpse_filter_value' );

    $my_query = new WP_Query( [
        'p' => $GLOBALS['value'],
    ] );

    if ( $my_query->have_posts() ) {
        while ( $my_query->have_posts() ) {
            $my_query->the_post();
            the_title( '<h1>', '</h1>');
        }
        wp_reset_postdata();
    }

    // Disable the filter.
    remove_filter( 'posts_where', 'wpse_filter_value' );
}
add_shortcode( 'my-shortcode', 'wpse_shortcode_function' );

function wpse_filter_value( $where ){
    // $GLOBALS['value'] is accessible here.

    // exit ( print_r( $GLOBALS['value'] ) );

    return $where;
}

Nota lateral, declarar uma função dentro de outra função não é um bom prática .

    
por Dave Romsey 15.05.2017 / 05:48
7

Aqui estão algumas soluções alternativas:

Abordagem # 1

Você poderia agrupar a definição do código de acesso e o retorno de chamada do filtro posts_where em uma classe para poder transmitir um determinado valor entre os métodos da classe, por exemplo como uma variável privada .

Abordagem # 2

Outra abordagem seria passar o valor como uma entrada para WP_Query no retorno de chamada do seu código de acesso:

$query = new WP_Query ( [ 'wpse_value' => 5, ... ] );

e, em seguida, dentro do seu filtro de posts_where, você pode acessá-lo:

add_filter( 'posts_where', function( $where, \WP_Query $query )
{

    if( $value = $query->get( 'wpse_value' ) )
    {
        // can use $value here
    }

    return $where;

}, 10, 2 );

Abordagem # 3

... ou você também pode ajustar o exemplo por @the_dramatist para poder remover o retorno de chamada posteriormente atribuindo a função anônima a uma variável:

function my_shortcode_function( $atts, $content )
{
    // shortcode_atts stuff here

    $value = 5; // just an example  

    // Add a filter's callback
    add_filter( 'posts_where',  $callback = function( $where ) use ( $value ) {
        // $value accessible here
        return $where;
    } );

    // WP_Query stuff here and setup $out

    // Remove the filter's callback
    remove_filter( 'posts_where', $callback );

    return $out;
}

add_shortcode( 'my-shortcode', 'my_shortcode_function' );   

Verifique, por exemplo os documentos do PHP sobre como atribuir uma função anônima, com a palavra-chave use, a uma variável.

ps: Acho que aprendi primeiro sobre esse truque de atribuição de variáveis por @gmazzap, para facilitar a remoção do retorno de chamada de um filtro anônimo.

Espero que ajude!

    
por birgire 15.05.2017 / 11:24
4

Você pode usar a palavra-chave use do PHP . Então, com a ajuda dessa palavra-chave use , você pode trazer variáveis dentro de uma função. E também você pode escrever uma função anônima para reduzir o código. Então a coisa toda será -

/**
 * How to get shorcode's input values inside a filter?
 *
 * @param $atts
 */
function my_shortcode_function($atts){
    $value = $atts['id'];
    add_filter('posts_where',function() use ( $value ){
        echo $value;
    });

}
add_shortcode('my-shortcode','my_shortcode_function');

Espero que ajude.

    
por CodeMascot 15.05.2017 / 05:33
0

Por que não passar o valor $ como um parâmetro?

 function filter_value($value){
        echo $value;
    }
documentação

    
por madalinivascu 15.05.2017 / 07:49