Usar una clase de complemento dentro de una plantilla

9

Estoy escribiendo un complemento para enviar una invitación a un amigo que abre un formulario cuando se hace clic en un enlace. Encapsulé todas las funciones en clase siguiendo el código proporcionado en el complemento Informar de video roto por @toscho. El código relevante está debajo:

/*
Plugin Name: Send Invitation
Plugin URI: http://w3boutique.net
Description: Emails a the link of the current page to a friend
Author: Nandakumar Chandrasekhar
Version: 0.1
Author URI: http://w3boutique.net/about-nanda.html
License: GPL2
*/

// include() or require() any necessary files here

// Settings and/or Configuration Details go here
define('SEND_INVITATION_MIN_WORDPRESS_VERSION', '3.1.1');

define('SEND_INVITATION_PLUGIN_URL', plugins_url('', __FILE__));

add_action( 'init', array( 'SendInvitation', 'nc_sendinvitation_init' ) );

class SendInvitation {

    protected $nonce_name = 'nc_sendinvitation';
    protected $post_url = '';

    public static function nc_sendinvitation_init() {
        new self;
    }

    public function __construct() {
        add_action( 'init', array(&$this, 'nc_sendinvitation_head' ));
        add_action( 'init', array(&$this,  'nc_sendinvitation_check_wordpress_version' ));
       add_action( 'init', array(&$this, 'nc_sendinvitation_form_action' ));
       //$this->post_url = $this->nc_sendinvitation_get_post_url();
   }

   public function nc_sendinvitation_head() {
       wp_enqueue_script( 'jquery' );
       wp_enqueue_script( 'send_invitation_js',
        plugins_url( 'js/send-invitation.js', __FILE__ ),
        array( 'jquery' ) );

       wp_enqueue_style( 'send_invitation_css',
        plugins_url( 'css/send-invitation.css', __FILE__ ) );
   }

   public function nc_sendinvitation_check_wordpress_version() {
       global $wp_version;

       $exit_msg = 'Send Invitation requires version '
    . SEND_INVITATION_MIN_WORDPRESS_VERSION
    . 'or newer <a href="http://codex.wordpress.org/Upgrading_WordPress">Please
update!</a>';

       if ( version_compare( $wp_version, SEND_INVITATION_MIN_WORDPRESS_VERSION, '<') )
       {
            exit( $exit_msg );
       }
   }

   public function nc_sendinvitation_form_action() {

        $action = '';
        if ( $_SERVER['REQUEST_METHOD'] != 'POST' )
        {
             $action = $this->nc_sendinvitation_get_form();
        }
        else if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
            $action = $this->nc_sendinvitation_handle_submit();
        }
        return $action;
   }

   public function nc_sendinvitation_get_form() {
       // Start the output buffer, prevents content being output directly into
       // script, instead it is stored in a buffer which can then be flushed
       // to allow the include file to be stored in a variable
       // See http://www.codingforums.com/showthread.php?t=124537
       ob_start();
       include('send-invitation-form.php');
       $send_invitation_link = ob_get_clean();

       return $send_invitation_link;
   }

   public function nc_sendinvitation_handle_submit() {
         if ( isset( $_POST['form_type'] ) && ( $_POST['form_type'] == 'nc_sendinvitation' ) ) {
            $to = '[email protected]';
            $subject = 'Invitation to SwanLotus';
            $message = 'Navanitachora invites you to take a look at this link';
            wp_mail($to, $subject, $message);
            $result = 'Email was sent successfully';
    }
    else {
        $result = $this->nc_sendinvitation_get_form();
    }
    return $result;
}

public function nc_sendinvitation_get_post_url() {
    global $post;
    $blog_id = get_option('page_for_posts');
    $post_id = '';
    if (is_home($blog_id)) {
        $post_id = $blog_id;
    } else {
        $post_id = $post->ID;
    }

    return get_permalink($post_id);
}
}
/* End of File */
?>

No sé cómo usar esta clase en mi plantilla para poder mostrar el formulario. Sé que necesito crear una instancia de la clase, pero no estoy seguro de dónde colocar el código y cómo acceder al objeto para poder usarlo en mi plantilla. Tengo conocimiento de OOP pero no lo he usado en este contexto antes y necesito un poco de instrucción paso a paso.

Muchas gracias.

navanitachora
fuente

Respuestas:

9

La mejor manera de usar su clase sin conocer el objeto es una acción . Registra la acción antes de que se carguen los archivos de tema para la presentación, WordPress se encargará del resto.

Código de muestra:

<?php # -*- coding: utf-8 -*-
/**
 * Plugin Name: Plugin Action Demo
 */
add_action( 'init', array ( 'Plugin_Action_Demo', 'init' ) );

class Plugin_Action_Demo
{
    /**
     * Creates a new instance.
     *
     * @wp-hook init
     * @see    __construct()
     * @return void
     */
    public static function init()
    {
        new self;
    }

    /**
     * Register the action. May do more magic things.
     */
    public function __construct()
    {
        add_action( 'plugin_action_demo', array ( $this, 'print_foo' ), 10, 1 );
    }

    /**
     * Prints 'foo' multiple $times.
     *
     * Usage:
     *    <code>do_action( 'plugin_action_demo', 50 );</code>
     *
     * @wp-hook plugin_action_demo
     * @param int $times
     * @return void
     */
    public function print_foo( $times = 1 )
    {
        print str_repeat( ' foo ', (int) $times );
    }
}

Ahora puede llamar a do_action( 'plugin_action_demo', 50 );algún lugar de su tema o en otro complemento, y ya no tiene que preocuparse por el funcionamiento interno de la clase.

Si desactiva el complemento, todavía está a salvo: WordPress simplemente ignora las acciones desconocidas y do_action()no hará daño. Además, otros complementos pueden eliminar o reemplazar la acción, por lo que ha creado una mini API agradable con una add_action().

También podrías construir un singleton:

<?php # -*- coding: utf-8 -*-
/**
 * Plugin Name: Plugin Singleton Demo
 */
class Plugin_Singleton_Demo
{
    protected static $instance = NULL;

    /**
     * Creates a new instance if there isn't one.
     *
     * @wp-hook init
     * @return object
     */
    public static function get_instance()
    {

        NULL === self::$instance and self::$instance = new self;
        return self::$instance;
    }

    /**
     * Not accessible from the outside.
     */
    protected function __construct() {}

    /**
     * Prints 'foo' multiple $times.
     *
     * @param int $times
     * @return void
     */
    public function print_foo( $times = 1 )
    {
        echo str_repeat( ' foo ', (int) $times );
    }
}

Ahora print_foo()es accesible por:

Plugin_Singleton_Demo::get_instance()->print_foo();

No recomiendo el patrón Singleton. Tiene algunos inconvenientes serios .

fuxia
fuente
1
Por curiosidad, ¿cuál es el propósito de plugin_action_demoen add_action()? ¿Cómo do_action( 'print_foo', 50 );sabe que la acción es plugin_action_demoo es irrelevante ese nombre?
Jared
Ok, estaba un poco confundido. :) Gracias por aclarar eso.
Jared
Para el registro: declare()requiere php 5.3+ :)
kaiser
Gracias que funciona solo tengo que agregar algo de validación y ya debería haber terminado. Gracias @toscho, me has enseñado mucho. :-)
navanitachora
@tosco Encontró su respuesta buscando artículos sobre singletons para plugins de WordPress. ¿Te das cuenta de que estás usando un Singleton en tu respuesta recomendada, simplemente no lo estás aplicando? Imagina un themer llama new Plugin_Action_Demo?? Cualquiera que lo use do_action('plugin_action_demo')activaría dos (2) llamadas a Plugin_Action_Demo->print_foo(), no lo que desea. El furor sobre los singletons ignora que hay casos de uso apropiados. Como FYI, @ericmann y yo estamos blogueando ahora para defender los singletons para el espacio de nombres de plugins de WordPress, él en eamann.com y yo en hardcorewp.com.
MikeSchinkel