Verwenden einer Plugin-Klasse in einer Vorlage

9

Ich schreibe ein Plugin, um eine Einladung an einen Freund zu senden, die ein Formular öffnet, wenn auf einen Link geklickt wird. Ich habe alle Funktionen in der Klasse gekapselt, indem ich dem Code gefolgt bin, der im Plugin "Report Broken Video" von @toscho angegeben ist. Der relevante Code ist unten:

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

Ich weiß nicht, wie ich diese Klasse in meiner Vorlage verwenden soll, damit ich das Formular anzeigen kann. Ich weiß, dass ich die Klasse instanziieren muss, bin mir aber nicht sicher, wo ich den Code ablegen soll und wie ich auf das Objekt zugreifen soll, damit ich es in meiner Vorlage verwenden kann. Ich habe Kenntnisse über OOP, habe es aber noch nie in diesem Zusammenhang verwendet und benötige ein wenig Schritt-für-Schritt-Anleitung.

Danke vielmals.

navanitachora
quelle

Antworten:

9

Der beste Weg, Ihre Klasse zu verwenden, ohne das Objekt zu kennen, ist eine Aktion . Sie registrieren die Aktion, bevor die Themendateien für die Präsentation geladen werden. Den Rest erledigt WordPress.

Beispielcode:

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

Jetzt können Sie do_action( 'plugin_action_demo', 50 );irgendwo in Ihrem Thema oder in einem anderen Plugin anrufen und müssen sich nicht mehr um das Innenleben der Klasse kümmern.

Wenn Sie das Plugin deaktivieren, sind Sie immer noch sicher: WordPress ignoriert nur unbekannte Aktionen und das do_action()wird keinen Schaden anrichten. Außerdem können andere Plugins die Aktion entfernen oder ersetzen, sodass Sie eine schöne Mini-API mit einer erstellt haben add_action().

Sie können auch einen Singleton erstellen:

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

Jetzt print_foo()ist erreichbar per:

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

Ich empfehle das Singleton-Muster nicht. Es hat einige schwerwiegende Nachteile .

Fuxia
quelle
1
Was ist aus Neugier der Zweck von plugin_action_demoin add_action()? Woher weiß man do_action( 'print_foo', 50 );, dass die Aktion plugin_action_demoirrelevant ist oder ist?
Jared
Ok, war ein bisschen verwirrt. :) Danke, dass du das geklärt hast.
Jared
Für die Aufzeichnung: declare()erfordert PHP 5.3+ :)
Kaiser
Danke, dass funktioniert, muss nur eine Validierung hinzugefügt werden und ich sollte fertig sein. Danke @toscho, du hast mir viel beigebracht. :-)
navanitachora
@tosco Ich habe Ihre Antwort gefunden und nach Artikeln über Singletons für WordPress-Plugins gesucht. Sie erkennen , Sie sind in Ihrer empfohlene Antwort ein Singleton verwenden, können Sie erzwingen es einfach nicht? Stellen Sie sich vor, ein Themer ruft an new Plugin_Action_Demo? Jeder Benutzer do_action('plugin_action_demo')würde zwei (2) Anrufe auslösen Plugin_Action_Demo->print_foo(), nicht das, was Sie wollen. Die Aufregung über Singletons ignoriert, dass es geeignete Anwendungsfälle gibt. Als FYI bloggen sowohl @ericmann als auch ich jetzt, um Singletons für den WordPress-Plugin-Namespace zu befürworten, er bei eamann.com und ich bei hardcorewp.com.
MikeSchinkel