11

This is my first wordpress plugin and I'm running a lot of trouble making it work, it almost work fine but I don't find a way to accomplish this specific thing.

Basically I've my custom setting page for my plugin, it saves all with no trouble at all, but the question its, how can I can my other button (inside the same setting page) to trigger, in this case, a sync action.

Because my plugin after configured it trigger another action that create/update records on a table, but the first time I need to run a sync to create/update the records from the old posts of the wordpress.

Edit:

Plugin source code on wsd-parse-api.

3
  • Can you post your code please?
    – s_ha_dum
    Commented Jan 9, 2013 at 19:09
  • is not really necesary, because its a bit complex now (separated in many files, etc). But the toscho answer was exactly that I want. Regards
    – norman784
    Commented Jan 9, 2013 at 19:13
  • added github repo of the plugin!
    – norman784
    Commented Jan 9, 2013 at 19:52

1 Answer 1

19

You need a second form with admin_url('admin-post.php') as form action. Then you can hook into admin_post_custom_action to execute your action.

Sample code:

add_action( 'admin_post_wpse_79898', 'wpse_79898_test' );

function wpse_79898_test() {
    if ( isset ( $_GET['test'] ) )
        echo esc_html( $_GET['test'] );

    die( __FUNCTION__ );
}

In your settings page:

<form action="<?php echo admin_url( 'admin-post.php' ); ?>">
<input type="hidden" name="action" value="wpse_79898">
<input type="text" name="test" value="">
<?php submit_button( 'Send' ); ?>
</form>

Update

Here is a rather extended example. It shows:

  • basic security actions (nonces, escaping),
  • how to register and to use the callback,
  • how to redirect back to the original page, this works even for network activated plugins,
  • how to show a custom message based on a white list of allowed values.

The example I have used here – updating an option – should not be used for plugins activated for on site only. For network activated plugins though this is quite useful, because there is no options API for those.

I should add comments, but I am too lazy. :) I will write a blog post about this, and update the answer later with a link.

<?php
/* Plugin Name: admin-post demo */

add_action( 'wp_loaded', array ( WPSE_79898_Admin_Post_Demo::get_instance(), 'register' ) );

class WPSE_79898_Admin_Post_Demo
{
    /**
     * Plugin instance.
     *
     * @see get_instance()
     * @type object
     */
    protected static $instance = NULL;

    protected $action     = 'wpse_79898';
    protected $option_name     = 'wpse_79898';
    protected $page_id = NULL;

    /**
     * Access this plugin’s working instance
     *
     * @wp-hook wp_loaded
     * @return  object of this class
     */
    public static function get_instance()
    {
        NULL === self::$instance and self::$instance = new self;
        return self::$instance;
    }

    public function register()
    {
        add_action( 'admin_menu', array ( $this, 'add_menu' ) );
        add_action( "admin_post_$this->action", array ( $this, 'admin_post' ) );
    }

    public function add_menu()
    {
        $page_id = add_options_page(
            'Admin Post Demo',
            'Admin Post Demo',
            'manage_options',
            'admin-post-demo',
            array ( $this, 'render_options_page' )
        );

        add_action( "load-$page_id", array ( $this, 'parse_message' ) );
    }

    public function parse_message()
    {
        if ( ! isset ( $_GET['msg'] ) )
            return;

        $text = FALSE;

        if ( 'updated' === $_GET['msg'] )
            $this->msg_text = 'Updated!';

        if ( 'deleted' === $_GET['msg'] )
            $this->msg_text = 'Deleted!';

        if ( $this->msg_text )
            add_action( 'admin_notices', array ( $this, 'render_msg' ) );
    }

    public function render_msg()
    {
        echo '<div class="' . esc_attr( $_GET['msg'] ) . '"><p>'
            . $this->msg_text . '</p></div>';
    }

    public function render_options_page()
    {
        $option = esc_attr( stripslashes( get_option( $this->option_name ) ) );
        $redirect = urlencode( remove_query_arg( 'msg', $_SERVER['REQUEST_URI'] ) );
        $redirect = urlencode( $_SERVER['REQUEST_URI'] );

        ?><h1><?php echo $GLOBALS['title']; ?></h1>
        <form action="<?php echo admin_url( 'admin-post.php' ); ?>" method="POST">
            <input type="hidden" name="action" value="<?php echo $this->action; ?>">
            <?php wp_nonce_field( $this->action, $this->option_name . '_nonce', FALSE ); ?>
            <input type="hidden" name="_wp_http_referer" value="<?php echo $redirect; ?>">

            <label for="<?php echo $this->option_name; ?>">Enter some text:</label>
            <input type="text" name="<?php echo $this->option_name;
                ?>" id="<?php echo $this->option_name;
                ?>" value="<?php echo $option; ?>">
            <?php submit_button( 'Send' ); ?>
        </form>
        <?php
    }

    public function admin_post()
    {
        if ( ! wp_verify_nonce( $_POST[ $this->option_name . '_nonce' ], $this->action ) )
            die( 'Invalid nonce.' . var_export( $_POST, true ) );

        if ( isset ( $_POST[ $this->option_name ] ) )
        {
            update_option( $this->option_name, $_POST[ $this->option_name ] );
            $msg = 'updated';
        }
        else
        {
            delete_option( $this->option_name );
            $msg = 'deleted';
        }

        if ( ! isset ( $_POST['_wp_http_referer'] ) )
            die( 'Missing target.' );

        $url = add_query_arg( 'msg', $msg, urldecode( $_POST['_wp_http_referer'] ) );

        wp_safe_redirect( $url );
        exit;
    }
}
5
  • 1
    nice, now I need to rewrite my plugin! xD and use OOP. Thanks
    – norman784
    Commented Jan 9, 2013 at 21:28
  • 2
    I'm ready for the blog post. Commented Jun 8, 2020 at 22:07
  • add_action is supposed to be passed a function that takes one argument by default. Yours takes zero arguments. Does wordpress pass an argument to your function that you're disregarding? What argument is it passing? Commented Jun 8, 2020 at 22:19
  • @LimitedAtonementThere is no such requirement regarding arguments.
    – fuxia
    Commented Jun 9, 2020 at 4:08
  • Very helpful answer. Thank you! Commented May 6, 2021 at 21:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.