plugins - Why is an action callback function from an instance of a class always invoking the same function from an instance?

I have a class whose constructor is the following:public function __construct( $content_type, $filter_fields, $meta_quer

I have a class whose constructor is the following:

public function __construct( $content_type, $filter_fields, $meta_query = '', $taxonomy = '') {
        if ( !empty ( $content_type ) ) {
          add_action('wp_ajax_myfilter', array($this, 'filter_function'));
          add_action('wp_ajax_nopriv_myfilter', array($this, 'filter_function));
...

I create two instances of the class as follows (filter_list is an array that contains the properties which are not relevant for this purpose)

    global $filter_builder;

    foreach ($filter_list as $filter ) {
        $filter_builder[$filter['content_type']] = new FilterBuilder( 
            $filter[ 'content_type' ], $filter[ 'filter_fields' ], $filter['meta_query'], $filter['taxonomy']
        );
    }

The instances are created correctly and everything shows fine until the ajax call is made and the callback function, 'filter_function', is invoked. In theory, each instance has their own callback function when they were created, however, every time that ajax call is made, the function the first instance of the global array is called.

The global array has two instances and when I try and debug the callback, it seems like the same callback is invoked for both instances.

Even though the callbacks have the same name, it should not make a difference. I have created an anonymous function and this odd behaviour continues.

Is there something I am missing? The callback function depends on the content type when it is invoked, and it's always defaulting to the post type that is defined first in the array.

Here is the instance creation simplified in case it helps:

    $filter_list = array(
        array(
            'content_type' => 'event',
            'filter_fields' => array(
                // Text to Display => Field Name
                'Suburb' => 'city',
                'Postal Code' => 'zip',
            ),
            'meta_query' => '',
            'taxonomy' => '',
        ),
        array(
            'content_type' => 'contact_center',
            'filter_fields' => array(
                // Text to Display => Field Name
                'Suburb' => 'suburb',
                'Postal Code' => 'postal_code',
            ),
            'meta_query' => '',
            'taxonomy' => '',
        ),
    );

If you get this far, I thank you, and if you can help, I thank you even more! :-)

I have a class whose constructor is the following:

public function __construct( $content_type, $filter_fields, $meta_query = '', $taxonomy = '') {
        if ( !empty ( $content_type ) ) {
          add_action('wp_ajax_myfilter', array($this, 'filter_function'));
          add_action('wp_ajax_nopriv_myfilter', array($this, 'filter_function));
...

I create two instances of the class as follows (filter_list is an array that contains the properties which are not relevant for this purpose)

    global $filter_builder;

    foreach ($filter_list as $filter ) {
        $filter_builder[$filter['content_type']] = new FilterBuilder( 
            $filter[ 'content_type' ], $filter[ 'filter_fields' ], $filter['meta_query'], $filter['taxonomy']
        );
    }

The instances are created correctly and everything shows fine until the ajax call is made and the callback function, 'filter_function', is invoked. In theory, each instance has their own callback function when they were created, however, every time that ajax call is made, the function the first instance of the global array is called.

The global array has two instances and when I try and debug the callback, it seems like the same callback is invoked for both instances.

Even though the callbacks have the same name, it should not make a difference. I have created an anonymous function and this odd behaviour continues.

Is there something I am missing? The callback function depends on the content type when it is invoked, and it's always defaulting to the post type that is defined first in the array.

Here is the instance creation simplified in case it helps:

    $filter_list = array(
        array(
            'content_type' => 'event',
            'filter_fields' => array(
                // Text to Display => Field Name
                'Suburb' => 'city',
                'Postal Code' => 'zip',
            ),
            'meta_query' => '',
            'taxonomy' => '',
        ),
        array(
            'content_type' => 'contact_center',
            'filter_fields' => array(
                // Text to Display => Field Name
                'Suburb' => 'suburb',
                'Postal Code' => 'postal_code',
            ),
            'meta_query' => '',
            'taxonomy' => '',
        ),
    );

If you get this far, I thank you, and if you can help, I thank you even more! :-)

Share Improve this question asked Apr 1, 2019 at 23:09 csaboriocsaborio 1122 silver badges13 bronze badges 4
  • 1 Are wp_ajax_myfilter and wp_ajax_nopriv_myfilter the same for both classes? Or is the myfilter part different for each class? – czerspalace Commented Apr 1, 2019 at 23:36
  • Thanks for reply, both (wp_ajax_myfilter and wp_ajax_nopriv_myfilter) have the same callback function. The callback function is different for every instance. Does that make sense? – csaborio Commented Apr 2, 2019 at 0:43
  • Hi, sorry, I meant are the actions named wp_ajax_myfilter and wp_ajax_nopriv_myfilter in both classes. The callback is ok, but if the action name is the same for both, the ajax call will only go to one of them. What happens if you name them wp_ajax_nopriv_myfilter1 and wp_ajax_nopriv_myfilter2? – czerspalace Commented Apr 2, 2019 at 0:50
  • I'll try your suggestion in the evening and report back, thanks for the idea. – csaborio Commented Apr 2, 2019 at 1:32
Add a comment  | 

2 Answers 2

Reset to default 2

It's possible I'm misunderstanding your question, but the way it is written it seems as though every instance of your FilterBuilder class will always get called.

Each instance of your class has in its constructor:

add_action('wp_ajax_myfilter', array($this, 'filter_function'));

(as well as the non-logged-in-user version)

There is no conditional here telling it when to run based on which "content type" or class instance you have. WordPress is literally being told, "Every time you get an ajax request for 'myfilter', run this instance's filter_function function." And since there are 2 instances in your example, and thus 2 constructors, WordPress is being told that twice (once for each).

WP AJAX functions are generally written to return data and die. (Grim maybe, but true :) So if your's is written as such, only the first registered action will run.

So, in short, it is true that each of your registered hooks is tied to its respective object ($this), and that their similar names is not a hindrance. However, you haven't given WordPress or your AJAX workflow anything to know which instance it should load.

As czerspalace & tmdesigned pointed out, the ajax call needed to be different for each instance. The action registration now looks like this:

            add_action("wp_ajax_myfilter_{$content_type}", array( $this, 'scorpiotek_filter_function' ) );
            add_action("wp_ajax_nopriv_myfilter_{$content_type}", array( $this, 'scorpiotek_filter_function' ) );

And I had to match the value filter of my hidden action input to reflect this change:

<input type="hidden" name="action" value="myfilter_<?php echo $this->get_content_type(); ?>">

Thanks both!! :-)

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745637549a4637484.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信