Bir filtrenin içine kısa kodun giriş değerleri nasıl alınır?


9

Bir filtre tarafından kullanılan bir işlev içinde bir kısa kod giriş değerini almaya çalışıyorum, ancak başarı yok gibi görünüyor. İşte yaptığım şey:

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');

Şimdi $valueiçeride kullanmak filter_value()değişken kapsamları nedeniyle işe yaramayacağını biliyorum , ancak kullanmak bile $GLOBALS['value']çalışmıyor.

$value = $atts['id']İçinde kullanmayı bile denedim filter_value();ama başarı da yoktu.

[my-shortcode id='123']123 gibi kısa kodumu nasıl kullanabilirim ve filtreye nasıl aktarabilirim?

Teşekkürler.

Yanıtlar:


7

Genel bir değişken kullanmak işe yarayacaktır. İşte bir gösteri:

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;
}

Yan not, bir fonksiyonun başka bir fonksiyon içinde bildirilmesi iyi bir uygulama değildir .


Bu aslında garip. Ben kullanarak değeri ayarlamak $GLOBALS['value'] = some valueve sonra $GLOBALS['value']işe yarıyor, ancak değeri doğrudan olarak ayarlamak $value = some valueve sonra kullanarak çağırırsanız $GLOBALS['value']işe yaramazsa, PHP kılavuzuna göre çalışması gerekir.
Jack Johansson

Bir değere başlatmadan önce $valuegenel kapsamı ayarlamanız gerekir global $value;. Örneğin global $value; $value = $a['id']; , filtrede yapabilirsiniz global $value; echo $value;Bu yardımcı olur mu?
Dave Romsey

Evet teşekkürler. Ben okuyordum bu kılavuzun üzerinde ve ilk örnekteki değerleri doğrudan tanımlanır. Doğrudan kullanarak kullanılabilir herhangi bir işlevi dışında tanımlamak zorunda $GLOBALS['value'];mıyım?
Jack Johansson

2
Güzel. mutlu biz aldık. Bu dokümanlardaki ilk örnekte, değişkenler bir işlevin dışında ve global kapsam içinde bildirilir. Dolayısıyla, globalanahtar kelimeye gerek yoktur . Örneklerimizde, işlevler kapsamında çalıştık, bu yüzden globalanahtar kelime gerekli.
Dave Romsey

1
Filtreler bizim dostlarımız! :-) Eminim bazı istekli cevaplar daha fazla yardıma ihtiyacınız olursa sorularınızı cevaplamak için olacak!
Dave Romsey

7

İşte birkaç geçici çözüm:

Yaklaşım # 1

Sınıf yöntemleri arasında belirli bir değerin etrafında dolaşmak için, örneğin özel değişken gibi , kısa kodun tanımını ve posts_wherefiltrenin geri aramasını bir sınıfa sarabilirsiniz .

Yaklaşım # 2

Başka bir yaklaşım, değeri kısa WP_Querykodunuzun geri aramasına bir girdi olarak iletmek olacaktır :

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

ve sonra posts_where filtrenizden erişebilirsiniz:

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

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

    return $where;

}, 10, 2 );

Yaklaşım # 3

... veya anonim işlevi bir değişkene atayarak daha sonra geri aramayı kaldırabilmek için @the_dramatist tarafından örneği de ayarlayabilirsiniz :

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' );   

Örneğin kontrol PHP dokümanlar bir değişkene, kullanım anahtar sözcüğü ile, anonim bir işlev atamak için nasıl.

ps: Sanırım ilk olarak anonim bir filtrenin geri aramasını kaldırmayı kolaylaştırmak için @gmazzap tarafından bu değişken atama hilesini öğrendim.

Umarım yardımcı olur!


Teşekkürler birgire, nazik ve kesin cevap her zamanki gibi. Genel benzersiz bir değişken kullanarak bir fonksiyonun içindeki bir fonksiyon tanımlamayı önerir misiniz? Evet ise, lütfen bana nedenini söyler misiniz?
Jack Johansson

Bu işlevi yeniden kullanmamız gerekiyorsa ve başka bir işlevin kapsamı içinde sıkışırsa ve diğer geliştiricilerin filtreyi anonim geri aramalarla atlaması daha zor olurdu, bu iyi bir fikir olmaz. Bu yüzden wp.org repo için resmi bir eklenti olarak büyük olasılıkla diğer geliştiricilerin filtreleri olabildiğince kolay çıkarmasına izin vermeye çalışacağım ;-) Ayrıca genel olarak daha fazla küresel eklemekten kaçınmaya çalışacağım, çünkü bununla ilgili çeşitli sorunlar olabilir yaklaşmak. Eklenti yapımızla bir köşeye
girersek

Sanırım 3. yaklaşımınızla gidiyorum. Benim durumumda çalışıyor gibi görünüyor. Şerefe!
Jack Johansson

sizin için en uygun olanı kesinlikle. Kolayca tekrar kaldırmak için # 1 veya # 2 ile herhangi bir işlev olmadan gidebilirim ;-) @JackJohansson
birgire

2
WP_QueryBelirli bir örneği hedeflemek ve buna posts_where, pre_get_postsve gibi çeşitli filtrelerden erişmek için özel bağımsız değişkenleri ve değerlerini aktarabiliriz posts_clauses. 2. yaklaşımda yaptığımız şey budur.
birgire

4

PHPuse anahtar kelimesini kullanabilirsiniz . Yani bu anahtar kelimenin yardımıyla bir fonksiyonun içine değişken getirebilirsiniz. Ayrıca kodu azaltmak için anonim bir işlev yazabilirsiniz. Yani her şey,use

/**
 * 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');

Umarım yardımcı olur.


Bu harika, ama anonim işlevlerin kancalarını çıkarmak zordur.
Dave Romsey

2
Ooh, anonim işlevin kaldırılması şu soruya başka bir cevapta @birgire tarafından karşılandı. Güzel!
Dave Romsey

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.