Usando uma classe de plug-in dentro de um modelo

9

Estou escrevendo um plugin para enviar um convite a um amigo que abre um formulário quando um link é clicado. Encapsulei todas as funções da classe seguindo o código fornecido no plug-in Report Broken Video de @toscho. O código relevante está abaixo:

/*
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 */
?>

Não sei como usar essa classe no meu modelo para que eu possa exibir o formulário. Eu sei que preciso instanciar a classe, mas não sei onde colocar o código e como acessar o objeto para que eu possa usá-lo no meu modelo. Eu tenho conhecimento de POO, mas não o usei neste contexto antes e preciso de um pouco de instruções passo a passo.

Muito Obrigado.

navanitachora
fonte

Respostas:

9

A melhor maneira de usar sua classe sem conhecer o objeto é uma ação . Você registra a ação antes que os arquivos do tema para apresentação sejam carregados, o WordPress cuidará do resto.

Código de amostra:

<?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 );
    }
}

Agora você pode ligar para do_action( 'plugin_action_demo', 50 );algum lugar no seu tema ou em outro plug-in e não precisa mais se preocupar com o funcionamento interno da classe.

Se você desativar o plug-in, ainda estará seguro: o WordPress simplesmente ignora ações desconhecidas e do_action()não causará danos. Além disso, outros plugins são capazes de remover ou substituir a ação, então você construiu uma boa mini API com uma add_action().

Você também pode criar um 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 );
    }
}

Agora print_foo()é acessível por:

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

Eu não recomendo o padrão Singleton. Tem algumas desvantagens sérias .

fuxia
fonte
11
Por curiosidade, qual é o propósito de plugin_action_demonos add_action()? Como do_action( 'print_foo', 50 );saber que a ação é plugin_action_demoou é esse nome irrelevante?
Jared
Ok, estava um pouco confuso. :) Obrigado por esclarecer isso.
Jared
Para o registro: declare()requer php 5.3+ :)
kaiser
Obrigado que funciona apenas tem que adicionar alguma validação e eu deveria ser feito. Obrigado @toscho, você me ensinou muito. :-)
navanitachora
@tosco Encontrei sua resposta procurando artigos sobre singletons para plugins do WordPress. Você percebe que está usando um Singleton na sua resposta recomendada, apenas não está aplicando? Imagine um ladrão te chama new Plugin_Action_Demo?? Qualquer pessoa que usar do_action('plugin_action_demo')ativaria duas (2) chamadas Plugin_Action_Demo->print_foo(), não o que você deseja. O furor por singletons ignora que há casos de uso apropriados. Como FYI, @ericmann e eu estamos blogando agora para defender singletons para namespacing de plugins do WordPress, ele em eamann.com e eu em hardcorewp.com.
MikeSchinkel