admin管理员组

文章数量:1203386

I'm using the Wordpress boilerplate to develop a plugin. At some point, I wanted to make dynamic functions with some external parameters when using $this->loader->add_action() so I used an anonymous function... but it doesn't work. So I resolved to bypass the loader and use the Wordpress standard add_action() and it works! But I know it's not good practice. How to pass an anonymous function through the loader? I'd like to know if any of you have a idea of how to implement this with the loader.

What I tried

$this->loader->add_action("views_edit-{$post_type}", $plugin_admin, function($views) use ($plugin_admin, $post_type) { 
                return $plugin_admin->some_function($views, $post_type); 
            });

The error I get

 Your PHP code changes were rolled back due to an error on line 959 of file wp-includes/plugin.php. Please fix and try saving again.

Uncaught Error: Object of class Closure could not be converted to string in wp-includes/plugin.php:959
Stack trace:
#0 wp-includes/class-wp-hook.php(74): _wp_filter_build_unique_id()
#1 wp-includes/plugin.php(121): WP_Hook->add_filter()
#2 wp-includes/plugin.php(399): add_filter()
#3 wp-content/plugins/myplugin/includes/class-myplugin-loader.php(124): add_action()
#4 wp-content/plugins/myplugin/includes/class-myplugin.php(266): MyPlugin_Loader->run()
#5 wp-content/plugins/myplugin/myplugin.php(76): MyPlugin->run()
#6 wp-content/plugins/myplugin/myplugin.php(79): run_myplugin()
#7 wp-settings.php(418): include_once('/home/...')
#8 wp-config.php(106): require_once('/home/...')
#9 wp-load.php(50): require_once('/home/...')
#10 wp-admin/admin.php(34): require_once('/home/...')
#11 wp-admin/plugin-editor.php(10): require_once('/home/...')
#12 {main}
  thrown

What I used instead by bypassing the loader (it works)

add_action("views_edit-{$post_type}", function($views) use ($plugin_admin, $post_type) {
            return $plugin_admin->some_function($views, $post_type); 
        });

I'm using the Wordpress boilerplate to develop a plugin. At some point, I wanted to make dynamic functions with some external parameters when using $this->loader->add_action() so I used an anonymous function... but it doesn't work. So I resolved to bypass the loader and use the Wordpress standard add_action() and it works! But I know it's not good practice. How to pass an anonymous function through the loader? I'd like to know if any of you have a idea of how to implement this with the loader.

What I tried

$this->loader->add_action("views_edit-{$post_type}", $plugin_admin, function($views) use ($plugin_admin, $post_type) { 
                return $plugin_admin->some_function($views, $post_type); 
            });

The error I get

 Your PHP code changes were rolled back due to an error on line 959 of file wp-includes/plugin.php. Please fix and try saving again.

Uncaught Error: Object of class Closure could not be converted to string in wp-includes/plugin.php:959
Stack trace:
#0 wp-includes/class-wp-hook.php(74): _wp_filter_build_unique_id()
#1 wp-includes/plugin.php(121): WP_Hook->add_filter()
#2 wp-includes/plugin.php(399): add_filter()
#3 wp-content/plugins/myplugin/includes/class-myplugin-loader.php(124): add_action()
#4 wp-content/plugins/myplugin/includes/class-myplugin.php(266): MyPlugin_Loader->run()
#5 wp-content/plugins/myplugin/myplugin.php(76): MyPlugin->run()
#6 wp-content/plugins/myplugin/myplugin.php(79): run_myplugin()
#7 wp-settings.php(418): include_once('/home/...')
#8 wp-config.php(106): require_once('/home/...')
#9 wp-load.php(50): require_once('/home/...')
#10 wp-admin/admin.php(34): require_once('/home/...')
#11 wp-admin/plugin-editor.php(10): require_once('/home/...')
#12 {main}
  thrown

What I used instead by bypassing the loader (it works)

add_action("views_edit-{$post_type}", function($views) use ($plugin_admin, $post_type) {
            return $plugin_admin->some_function($views, $post_type); 
        });
Share Improve this question edited Mar 20, 2022 at 12:30 Tom asked Mar 20, 2022 at 12:16 TomTom 11 bronze badge 3
  • 1 unfortunately this boilerplate framework doesn't support closures - the 2nd parameter MUST be an object, and the 3rd parameter MUST be a string representing a publicly accessible method available on the object provided in the 2nd parameter. To use the boilerplate approach, the siimplest solution is create a dedicated class with a method you can use in place of your anonymous function. I suppose you could use an anonymous class (php.net/manual/en/language.oop5.anonymous.php) but this would complicate things. Just create a class to do your work, and hook that in. Why not? – Paul G. Commented Mar 20, 2022 at 13:09
  • Thank you for your fast reply. I didn't know the boilerplate doesn't support closures, thanks for the clarification. As for your suggestion, even if I created a dedicated class to replace the anonymous function, I don't see where I could pass arguments through the loader since their is no parameter where to pass them? – Tom Commented Mar 20, 2022 at 21:32
  • Do you mean I should create a class where I pass the arguments I want to pass, then call that class in the 2nd parameter of the loader (object) and then call a function name inside that class as a 3rd parameter of the loader (string)? – Tom Commented Mar 20, 2022 at 21:40
Add a comment  | 

1 Answer 1

Reset to default 0

Thanks Paul, you led me to the solution.

What I did

In class-mypluging-admin.php, I added this:

/**
 * Additional arguments for this plugin.
 *
 * @since    1.0.0
 * @access   private
 * @var      array $args The current arguments of this plugin.
 */
private $args;

/**
 * Initialize the class and set its properties.
 *
 * @since    1.0.0
 * @param      string    $plugin_name       The name of this plugin.
 * @param      string    $version    The version of this plugin.
 * @param      array     $args  The additional arguments of this plugin.
 */
public function __construct( $plugin_name, $version, $args = null ) {

    $this->plugin_name = $plugin_name;
    $this->version = $version;
    $this->args = $args;

}

Then for the functions in class-mypluging-admin.php

function some_function( $views ) {
    
    $post_type = $this->args['post_type'];

...

}

In class-mypluging.php, I do this:

foreach($post_types as $post_type)
{
    $args = array(
        'post_type' => $post_type,
    );
    
    $plugin_admin = new MyPlugin_Admin( $this->get_plugin_name(), $this->get_version(), $args );    

$this->loader->add_action("views_edit-{$post_type}", $plugin_admin, 'some_function');   

}

And it works! Is that the correct way to do this?

本文标签: pluginsUsing Class loader in Wordpress boilerplate