そんなにGeekじゃないエンジニアブログ

WordPressプラグイン開発!スニペットから始めるカンタン開発・処理のフック~アンインストール時の処理まで

calendar

こんにちは。でんすけ(@notgeek_densuke)です。

WordPressのプラグイン開発。実践編です。
導入辺はこちら。

WordPressプラグイン開発!初心者からでも始められる、開発基礎知識編

今回は、簡単なプラグインの例を使って、実際に処理を書いてみます。

スポンサーリンク

WordPressプラグインを作って動かしてみる

では、さっそく作って動かしましょう!

コードのスニペットを、githubで公開しています。
こちら

  1. githubリポジトリからソースをダウンロード、「plugin-snippets」フォルダを取り出す
  2. WordPressのインストールフォルダの「wp-content/plugins」フォルダの中にアップロード
  3. 管理画面から「プラグイン」→「インストール済みプラグイン」で、「plugin name」というプラグインがあるので、それを有効化

すると、管理画面の「ツール」の中に「プラグイン名」というメニューが出来上がります。

プラグインが動いた!

WordPressプラグイン処理の入口

まずは、どこから処理が始まっているか、というところから。

WordPressのプラグインの基本的な流れとしては、

・コンストラクタにアクションフック、フィルターフックを書く
 ↓
・フック関数の中で処理を書いていく

という流れになります。

phpのソースの一部だけ抜粋してみます。

if( !class_exists('prefix_my_class') ){
    class prefix_my_class{
        /*****
        コンストラクタ。読み込み時にフックしたい処理をここに書いておく
        Constructor. Write the process you want to hook on loading here.
        *****/
        function __construct() {
            add_action( 'plugins_loaded', array( $this , 'plugin_init' ) );
            add_action( 'admin_menu', array( $this , 'add_menu' ) );
            add_action( 'admin_init', array( $this , 'setting_init' ) );
            if(function_exists('register_uninstall_hook')) {
                register_uninstall_hook (__FILE__, array(get_class($this),'do_uninstall') );
            }
        }
    }
    new prefix_my_class();
}

まず、new densuke_my_class();が実行されます。

これで、自作のクラス「prefix_my_class」がインスタンス化されることで、コンストラクタ「__construct()」が実行されます。

で、このコンストラクタの中に、フックしたい処理を書いているわけですね。

フックしたい関数がクラスの中に定義されている場合は、

add_action( 'plugins_loaded', array( $this , 'plugin_init' ) );

のように、array(インスタンス, 関数名)という形で書かないといけません。

翻訳ファイルを使って多言語化

WordPressは世界中で使われているツールです。
なので、英語で記述するのが基本です。

でも日本人だからね。日本語でやりたいよね。

初めから日本だけをターゲットにして、他の国は知らねぇ、というスタンスで行くのであれば、いろんな説明やらなんやらを日本語で書いても構いません。
が、せっかくグローバルにオープンなツールなんだから、英語にしたい。
じゃぁ両方やっちゃおうぜ!
という場合に必要なのが、この翻訳ファイルというやつです。

詳細はこちらの記事も参考にしていただきつつ。

[WordPressプラグイン開発]翻訳ファイル.poファイル、.moファイルで多言語化したプラグインを作ろう

実際に今回のスニペットでやってるのは、こういう処理です。

private $lang;

function __construct() {
    add_action( 'plugins_loaded', array( $this , 'plugin_init' ) );
}

/*****
plugins_loadedにフックした処理。翻訳ファイルを読むのはここがよさそう。
Process that hooked to "plugins_loaded". It looks good here to read the translation file.
*****/
function plugin_init(){
    $this->load_lang_strings();
}

/*****
翻訳ファイルの読み込み
read the translation file.
*****/
private function load_lang_strings(){
    load_plugin_textdomain( self::LANG_SLUG, false, basename( dirname( __FILE__ ) ) . self::LANG_PATH );
    $this->lang['plugin_name'] = __('my plugins name', self::LANG_SLUG);
    $this->lang['setting_page'] = __('setting page', self::LANG_SLUG);
}

load_plugin_textdomain( スラッグ, false, ファイルパス );
で、言語ファイル(*.moファイル)を読みにいきます。

.moファイルとは、*.poファイルをコンパイルしたもの。
*.poファイルの中身はこんな感じです。

# Copyright (C) 2018 WordPress
# This file is distributed under the same license as the WordPress package.
msgid ""
msgstr ""
"Project-Id-Version: MyProject v.1.0.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-06-06 09:48+0900\n"
"PO-Revision-Date: 2018-06-06 09:48+0900\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Last-Translator: your name <mailaddress>\n"
"Language-Team: your team name <mailaddress>\n"
"Language: ja\n"

msgid "my plugins name"
msgstr "プラグイン名"

msgid "setting page"
msgstr "設定画面"

このpoファイルで、
“my plugins name”という文字列が来たら、
“プラグイン名”という文字列に置き換える、
ということを定義します。

これをpoeditなどのツールでコンパイルすることで、moファイルを作ることができます。
poeditのSourceForgeページはこちら

で、以下の関数で言語の置き換えをやります。
__(‘my plugins name’, スラッグ);

これで、WordPressの現在の言語設定に応じたpoファイルから文字列を読み出してくれます。
ファイルがなければ、’my plugins name’がそのまま返ってきます。

設定メニュー画面を作成する

プラグインによっては、ユーザーに何か設定をしてもらって、その設定値によって処理を変えたい、ということがあるかと思います。

まずは、ユーザーに値を設定してもらう「画面」を作成しましょう。
こういう画面です。

画面を作るソースがこちら。

function __construct() {
    add_action( 'admin_menu', array( $this , 'add_menu' ) );
}

/*****
admin_menuにフックした処理。設定画面へのリンクをメニューに追加する
Process that hooked to "admin_menu". Add a link to the setting view to the menu.
*****/
function add_menu(){
    $page = add_management_page( $this->lang['plugin_name'], $this->lang['plugin_name'], 'manage_options', self::MENU_SLUG, array($this,'show_menu') );

    // 設定画面でのみ読み込むCSSファイル
    // css file that read only at setting view.
    add_action( 'admin_print_styles-' . $page, array( $this , 'enque_setting_style' ) );
}

/*****
設定画面のみ有効にするCSSファイルを読み込み
css file that read only at setting view.
*****/
function enque_setting_style(){
    wp_enqueue_style( self::SETTINGSTYLE_SLUG , plugins_url(self::SETTINGSTYLE_PATH , __FILE__));
}

/*****
設定画面のHTMLを作成、表示する関数
*****/
function show_menu(){
    ?>
        <!-- 設定画面のHTMLを書く -->
        <h2><?php echo $this->lang['plugin_name'] . " " . $this->lang['setting_page']; ?></h2>
    <?php
}

管理画面左側のメニューに、設定画面へのリンクを作成するには、
「admin_menu」アクションフックを使います。

そこで呼び出されたコールバック関数の中で
add_management_page()を使えば、「ツール」メニューの中に、自前のリンクを作ることができます。

そして、add_management_page()からコールバックされる関数の中で、設定画面のHTMLを出力する処理を書けば完成です。

公式サイトで詳細を知りたい方は、こちら。
管理メニュー追加に関する公式Wiki

設定画面から、オプションをDBに保存する

で、設定画面でユーザーに入力してもらったデータをDBに保存して、その値をいろいろと使いまわす、ということをやりたい。

WordPressに保存する設定値をオプションと呼びますが、そのオプションをDBに保存する処理はこんな感じ。

private static $option_grp = 'prefix_my_option_grp';
private static $option_param = [
    //お好みのキー => DBに保存されるオプション名
    //any key name => Option name stored in DB
    'hoge' => 'prefix_my_option_name_hoge',
    'moge' => 'prefix_my_option_name_moge'
];

function __construct() {
    add_action( 'admin_init', array( $this , 'setting_init' ) );
}

/*****
admin_initにフックする処理
Process that hooked to "admin_init".
*****/
function setting_init(){
    foreach( self::$option_param as $key => $val ){
        register_setting( self::$option_grp, $val );
    }
}

function show_menu(){
    ?>
        <h2><?php echo $this->lang['plugin_name'] . " " . $this->lang['setting_page']; ?></h2>
        <form method="post" action="options.php">
            <?php settings_fields( self::$option_grp ); ?>
            <?php do_settings_sections( self::$option_grp ); ?>
            <hr>

            <!-- ここに好きなform部品を追加する -->
            <!-- Please add any form parts here -->
            <input type="text" name="<?php echo self::$option_param['hoge']; ?>" value="<?php echo esc_attr(get_option( self::$option_param['hoge'] , "" )); ?>">

            <?php submit_button(); ?>
        </form>
    <?php
}

まず、admin_initにフックしたsetting_init()内で、register_settingを実行します。

これは、各オプションの名前と、オプションのグループ名を決めておいて、それをWordPressに「覚えといてね!」という処理です。

$option_paramを連想配列にしているので、’hoge’というのは、ただの配列のキーです。大事なのはその中身。’prefix_my_option_name_hoge’というオプション名がWordPressに記憶しておいてもらえます。

で、設定画面のHTMLを書く中で、

<form method="post" action="options.php">
<?php settings_fields( self::$option_grp ); ?>
<?php do_settings_sections( self::$option_grp ); ?>
</form>

とすることで、さっきの$option_grp名で記憶したオプションを使うよ!という宣言をします。

そして、form部品として

<input type="text" name="<?php echo self::$option_param['hoge']; ?>" value="<?php echo esc_attr(get_option( self::$option_param['hoge'] , "" )); ?>">

のように、inputのname属性にオプション名を付けておくと、そこに入力された値が、「オプション名 = 値」の形でDBに書き込まれるようになります。

最後に

<?php submit_button(); ?>

を付けておくと、「設定を保存」ボタンが設置できます。

DBに記録されたオプションは、get_option()関数でオプション名を指定して取得できます。

アンインストール時の削除処理

残念なことではありますが、このプラグインは使わない!もうアンインストールする!とユーザーに判断されてしまうこともあります。

先ほどのオプション、なにもしないとDBに残ったままになってしまいます。
オプション名にプレフィックスを付けるなどして唯一っぽい名前にしておけば、残っていたところで悪さをすることはないと思いますが、それでもやっぱりデータ容量を食ったりして、なんとなく気持ち悪い。

なので、アンインストール時にちゃんと削除処理をしておきましょう。

function __construct() {
    if(function_exists('register_uninstall_hook')) {
        register_uninstall_hook (__FILE__, array(get_class($this),'do_uninstall') );
    }
}

/*****
アンインストール時にoption値をDBから削除する関数
*****/
static function do_uninstall(){
    foreach( self::$option_param as $key => $val ){
        unregister_setting( self::$option_grp, $val );
        delete_option($val);
    }
}

register_uninstall_hook()で、アンインストール時の処理をフックできます。

ちなみに、クラス内にアンインストール処理を書く場合、フックする関数はstaticじゃないと動作しないようです。
もしくは、クラス内ではなくグローバルな関数として定義するか。

さりげなくオプショングループ名とオプション($option_grp、$option_param)をstatic宣言していたのも、static関数の中で使いたかったからです。

いずれにせよ、これでアンインストール時の処理もできました。
めでたしめでたし。

まとめ

ということで、スニペットを使ってWordPressプラグインの処理の枠組みを書いてみました。

あとは、お好みのフックを使って、お好みの処理を書いていくだけです。
自分なりに便利なプラグインを作ってみてください!

それではまたー。

参考サイト:WordPressCodex「プラグインの作成」

この記事をシェアする

コメント

コメントはありません。

down コメントを残す




CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください