Activar acción personalizada cuando se presiona el botón de configuración

9 ene 2013, 20:21:39
Vistas: 39.7K
Votos: 11

Este es mi primer plugin de WordPress y estoy teniendo muchos problemas para hacerlo funcionar. Casi funciona bien, pero no encuentro la manera de lograr esta cosa específica.

Básicamente, tengo mi página de configuración personalizada para mi plugin, guarda todo sin ningún problema, pero la pregunta es, ¿cómo puedo hacer que mi otro botón (dentro de la misma página de configuración) active, en este caso, una acción de sincronización?

Porque mi plugin, después de configurarlo, activa otra acción que crea/actualiza registros en una tabla, pero la primera vez necesito ejecutar una sincronización para crear/actualizar los registros de las entradas antiguas de WordPress.

Editar:

Código fuente del plugin en wsd-parse-api.

3
Comentarios

¿Puedes compartir tu código por favor?

s_ha_dum s_ha_dum
9 ene 2013 21:09:17

No es realmente necesario, porque ahora es un poco complejo (separado en muchos archivos, etc). Pero la respuesta de toscho era exactamente lo que necesitaba. Saludos

norman784 norman784
9 ene 2013 21:13:46

¡He añadido el repositorio de GitHub del plugin!

norman784 norman784
9 ene 2013 21:52:32
Todas las respuestas a la pregunta 1
5
19

Necesitas un segundo form con admin_url('admin-post.php') como acción del formulario. Luego puedes engancharte a admin_post_custom_action para ejecutar tu acción.

Código de ejemplo:

add_action( 'admin_post_wpse_79898', 'wpse_79898_test' );

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

    die( __FUNCTION__ );
}

En tu página de configuración:

<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( 'Enviar' ); ?>
</form>

Actualización

Aquí hay un ejemplo bastante extendido. Muestra:

  • acciones básicas de seguridad (nonces, escaping),
  • cómo registrar y usar el callback,
  • cómo redirigir de vuelta a la página original, esto funciona incluso para plugins activados en red,
  • cómo mostrar un mensaje personalizado basado en una lista blanca de valores permitidos.

El ejemplo que he usado aquí – actualizar una opción – no debería usarse para plugins activados solo en un sitio. Para plugins activados en red, sin embargo, esto es bastante útil, porque no hay una API de opciones para esos.

Debería añadir comentarios, pero soy demasiado vago. :) Escribiré un artículo en el blog sobre esto, y actualizaré la respuesta más tarde con un enlace.

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

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

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

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

    /**
     * Accede a la instancia de trabajo de este plugin
     *
     * @wp-hook wp_loaded
     * @return  object de esta clase
     */
    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(
            'Demo Admin Post',
            'Demo Admin Post',
            '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 = '¡Actualizado!';

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

        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; ?>">Ingresa algún texto:</label>
            <input type="text" name="<?php echo $this->option_name;
                ?>" id="<?php echo $this->option_name;
                ?>" value="<?php echo $option; ?>">
            <?php submit_button( 'Enviar' ); ?>
        </form>
        <?php
    }

    public function admin_post()
    {
        if ( ! wp_verify_nonce( $_POST[ $this->option_name . '_nonce' ], $this->action ) )
            die( 'Nonce inválido.' . 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( 'Falta el objetivo.' );

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

        wp_safe_redirect( $url );
        exit;
    }
}
9 ene 2013 20:29:32
Comentarios

¡Genial, ahora necesito reescribir mi plugin! xD y usar POO. Gracias

norman784 norman784
9 ene 2013 23:28:26

Estoy listo para el post del blog.

lmat - Reinstate Monica lmat - Reinstate Monica
9 jun 2020 01:07:44

add_action debería recibir una función que acepte un argumento por defecto. La tuya no acepta argumentos. ¿WordPress le está pasando algún argumento a tu función que estás ignorando? ¿Qué argumento está pasando?

lmat - Reinstate Monica lmat - Reinstate Monica
9 jun 2020 01:19:20

@LimitedAtonementNo existe tal requisito con respecto a los argumentos.

fuxia fuxia
9 jun 2020 07:08:27

¡Respuesta muy útil. ¡Gracias!

AidanCurran AidanCurran
7 may 2021 00:53:22