ちょっと話題の記事

WordPressプラグインをクラス定義する方法

2012.05.31

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

WordPress プラグインをクラスで定義する方法を紹介します。

WordPressにない機能が欲しい場合や既存の機能を変更したい場合に、WordPressのコアプログラムに手を入れずにそれらを実現する方法の一つとして、ご存知の通りWordPress プラグインがあります。

WordPress プラグインを使いこなせば、簡単な表示内容の加工だけでなく、不動産管理、予約管理、ショッピングカートなど様々な機能をWordPressに付加することができます。

WordPress プラグインの作成から利用するまでの流れは非常に簡単で、wp-content/plugins/ディレクトリに標準プラグイン情報(単にPHPのコメント)を記載したPHPファイルを作成するだけで管理画面から使用できるようになります。

関数ベースのSampleプラグイン

<?php
/*
Plugin Name: Sample
Plugin URI:http://.......
Description: 有効化しても何もしないサンプルプラグイン
Version: (プラグインのバージョン番号。例: 1.0)
Author: (プラグイン作者の名前)
Author URI: (プラグイン作者の URI)
License: (ライセンス名の「スラッグ」 例: GPL2)
*/

// アクションフックやフィルターフックなどを定義していくだけ・・・
function custom_content($text) { ... }
add_filter('the_content', 'custom_content');
?>

上記サンプルのように、作成したファイルにアクションフックやフィルターフックに登録する関数を定義していくだけでWordPressに機能を追加できます。

ここまでは大抵の書籍で紹介されていますが、WordPress プラグインの機能が大規模になるほど当然定義する関数が増えるわけですが、プラグインの規模が大きくなるにつれ、関数で定義していくのは辛いものがあります。

そこで今回は、WordPress プラグインをクラスで定義する方法をご紹介します。

WordPress プラグインをクラスとして定義した場合、add_actionやadd_filterで呼び出す処理を設定する場合、以下のようになります。

// 関数をadd_filterを使用してフィルターフックに登録する場合
add_filter('the_content', '関数名');

// インスタンスメソッドをadd_filterを使用してフィルターフックに登録する場合
add_filter('the_content', array(&$this, 'メソッド名'));

上記のようにWordPressプラグインでも、PHPの標準関数であるarray_maparray_walkにインスタンスメソッドを使用するのと同じ方法でadd_actionやadd_filterにインスタンスメソッドを登録することができます。

以下に、クラス定義を用いたWordPressプラグインのサンプルを記載します。

クラスで定義したSampleプラグイン

<?php

/**
 Plugin Name: Sample
 Plugin URI: http://classmethod.jp
 Description: クラス定義した何もしないSampleプラグイン
 Version: 1.0
 Author: Yuki Hiral
 Author URI: http://classmethod.jp
 */

// グローバル変数にPlugin_Sampleインスタンスを生成するだけ
$samplePlugin = new Plugin_Sample();

/**
 * プラグイン本体
 *
 */
class Plugin_Sample
{
    /**
     * コンストラクタ
     *
     * ウィジェットの初期化、WPフック・ショートタグなどの登録を行う。
     */
    public function __construct()
    {
        // プラグインが有効化されたときに実行されるメソッドを登録
        if (function_exists('register_activation_hook'))
        {
            register_activation_hook(__FILE__, array(&$this, 'activationHook'));
        }

        // プラグインが停止されたときに実行されるメソッドを登録
        if (function_exists('register_deactivation_hook'))
        {
            register_deactivation_hook(__FILE__, array(&$this, 'deactivationHook'));
        }

        // プラグインがアンインストールされたときに実行されるメソッドを登録
        if (function_exists('register_uninstall_hook'))
        {
            register_uninstall_hook(__FILE__, array(&$this, 'uninstallHook'));
        }

        // ウィジェットの初期化
        $this->initWidgets();

        // アクションフックの設定
        add_action('init', array(&$this, 'initActionHook'));

        // フィルターフックの設定
        add_filter('the_content', array(&$this, 'theContentFilterHook'));

        // ショートコードの設定
        add_shortcode('sample', array(&$this, 'sampleShortCode'));
    }

    /**
     * プラグインが有効化されたときに実行されるメソッド
     *
     * @return void
     */
    public function activationHook()
    {
        // 初回有効時のみ、初期化処理を行いたい場合は、オプション値にフラグをセットするなどすればよい
        if (! get_option('hello_world_plugin_installed'))
        {
            // オプション値の登録など・・・

            // インストール済みフラグをセット
            update_option('hello_world_plugin_installed', 1);
        }
    }

    /**
     * プラグインが停止されたときに実行されるメソッドx
     *
     * @return void
     */
    public function deactivationHook()
    {
        // プラグインが停止されたときの処理・・・
    }

    /**
     * プラグインが削除(アンインストール)されたときに実行されるメソッド
     *
     * unisntall.phpがある場合、unisntall.phpが優先的に実行されるので注意
     *
     * @return void
     */
    public function uninstallHook()
    {
        // オプション値の削除など・・・

        // インストール済みフラグを削除する
        delete_option('hello_world_plugin_installed');
    }

    /**
     * ウィジェットの登録
     *
     * @return void
     */
    public function initWidgets()
    {
        // ウィジェットの登録・・・
        // require_once __DIR__ . '/widgets/Sample.php';
        // add_action('widgets_init', create_function('', 'return register_widget("My_Widget_Sample");'));
    }

    /**
     * initアクションフック
     *
     * @return void
     */
    public function initActionHook()
    {
        // initアクションの処理・・・
    }

    /**
     * the_contentフィルターフック
     *
     *
     * @param string $content 変更前のコンテンツ
     * @return string 変更後のコンテンツ
     */
    public function theContentFilterHook($content)
    {
        // the_contentフィルターフックの処理・・・
        return $content;
    }

    /**
     * ショートコードの定義
     *
     * @param array $atts ショートコードの属性
     */
    public function sampleShortCode($atts)
    {
        extract(shortcode_atts(array(
            'foo' => 'something',
            'bar' => 'something else',
        ), $atts));

        // ショートタグの処理・・・

        return sprintf('foo = %s, bar = %s', $foo, $bar);
    }
}

?>

もちろん機能ごとにクラス定義を分けたり、アクションフックやフィルターフックなどの用途によってクラス定義を分けることも可能です。

意外と紹介されていないので、参考までに!