Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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.

share|improve this question
    
Can you post your code please? –  s_ha_dum Jan 9 '13 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 Jan 9 '13 at 19:13
    
added github repo of the plugin! –  norman784 Jan 9 '13 at 19:52
add comment

1 Answer

up vote 3 down vote accepted

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;
    }
}
share|improve this answer
1  
it works, now how I redirect it back to the same setting page and there is a function to display a flash message just like the one that shows after save... –  norman784 Jan 9 '13 at 19:12
1  
@norman784 See my update. –  toscho Jan 9 '13 at 21:01
1  
nice, now I need to rewrite my plugin! xD and use OOP. Thanks –  norman784 Jan 9 '13 at 21:28
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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