Idea1

Top > PluginDev > Class > Idea1

(似非)シングルトン版

Table of Contents

クラス化

1つのインスタンスを global 変数として使いまわします。 そのため、インスタンス変数の初期化をするために init() 関数を使用します。

概略

class PluginXxx {
  var $...                /* define()していた設定用定数やグローバル変数など */
  var $...                /* インスタンス変数 */
  function PluginXxx()  { /* plugin_xxx_init()    */ }
  function init()       { /* インスタンスの初期化 */ }
  function action()     { /* plugin_xxx_action()  */ }
  function convert()    { /* plugin_xxx_convert() */ }
  function inline()     { /* plugin_xxx_inline()  */ }

詳細

<?php
class PluginXxx
{
    // define()していた設定用定数やグローバル変数など
    var $conf;
    // インスタンス変数
    var $var;
    function PluginXxx()
    {
        // plugin_xxx_init()
        // define()していた設定用定数やグローバル変数などの初期化
    }
    function init()
    {
        // インスタンス変数の初期化
    }
    function convert()
    {
        // function_xxx_convert()
    }
    function inline()
    {
        // function_xxx_inline()
    }
    function action()
    {
        // function_xxx_action()
    }
}

function plugin_xxx_init()
{
    global $plugin_xxx;
    $plugin_xxx = new PluginXxx();
}
function plugin_xxx_convert()
{
    global $plugin_xxx;
    if (method_exists($plugin_xxx, 'init')) $plugin_xxx->init();
    $args = func_get_args();
    return call_user_func_array(array(&$plugin_xxx, 'convert'), $args);
}
function plugin_xxx_inline()
{
    global $plugin_xxx;
    if (method_exists($plugin_xxx, 'init')) $plugin_xxx->init();
    $args = func_get_args();
    return call_user_func_array(array(&$plugin_xxx, 'inline'), $args);
}
function plugin_xxx_action()
{
    global $plugin_xxx;
    if (method_exists($plugin_xxx, 'init')) $plugin_xxx->init();
    return $plugin_xxx->action();
}
?>

ユーザ設定(Plus!)

Pukiwiki Plus! にあるユーザ設定機能をどのように使えるかについて考えます。 PukiWiki Plus! には、プラグインファイルが読み込まれる直前に、init/プラグイン名.ini.php というファイルを読み込む、という機能があり、これをプラグインの初期値設定用に使用できます。プラグインアップデートの際にプラグインファイルを再度書き換えせずに済むので親切です。

init/プラグイン名.ini.php 中の設定が勝るようにするために、plugin_xxx_init 関数に

function plugin_xxx_init()
{
    global $plugin_xxx;
    if (! isset($plugin_xxx)) {
        $plugin_xxx = new PluginXxx();
    }
}

のように ! isset の if 文を追加しておきます。

init/xxx.ini.php では以下のように初期設定を行えます。

<?php
exist_plugin('xxx'); // require_once
global $plugin_xxx;
$plugin_xxx = new PluginXxx();
$plugin_xxx->conf = '......';
?>

もしくは

exist_plugin('xxx'); // require_once
class PluginXxxUser extends PluginXxx
{
    function PluginXxxUser()
    {
        parent::PluginXxx();
        $this->conf = '.....';
    }
}
global $plugin_xxx;
$plugin_xxx = new PluginXxxUser();

関数のオーバーライドまでも可能です。

ちなみにPukiWiki 本家のほうでもこの機能に対応するには、プラグインファイルの先頭に

if (! defined('INIT_DIR')) // if not Plus!
    if (file_exists(DATA_HOME . 'init/xxx.ini.php'))
        include_once(DATA_HOME . 'init/xxx.ini.php');

を追加しておけば可能です。

UnitTest について考える

UnitTestForPlugins参照。

UnitTest を行う場合は、関数実行後や、プラグイン実行後のインスタンス変数の値を参照したいものです。 インスタンスがグローバル変数として使われるので、init() されるまでは(次回のプラグイン実行までは)値を参照することができます。

まとめ

統合してみると次のようなコードになります。

<?php
if (! defined('INIT_DIR')) // if not Plus!
    if (file_exists(DATA_HOME . 'init/xxx.ini.php'))
        include_once(DATA_HOME . 'init/xxx.ini.php');

class PluginXxx
{
    // define()していた設定用定数やグローバル変数など
    var $conf;
    // インスタンス変数
    var $var;
    function PluginXxx()
    {
        // plugin_xxx_init()
        // define()していた設定用定数やグローバル変数などの初期化
    }
    function init()
    {
        // インスタンス変数の初期化
    }
    function convert()
    {
        // function_xxx_convert()
    }
    function inline()
    {
        // function_xxx_inline()
    }
    function action()
    {
        // function_xxx_action()
    }
}

function plugin_xxx_init()
{
    global $plugin_xxx;
    if (! isset($plugin_xxx)) {
        $plugin_xxx = new PluginXxx();
    }
}
function plugin_xxx_convert()
{
    global $plugin_xxx;
    if (method_exists($plugin_xxx, 'init')) $plugin_xxx->init();
    $args = func_get_args();
    return call_user_func_array(array(&$plugin_xxx, 'convert'), $args);
}
function plugin_xxx_inline()
{
    global $plugin_xxx;
    if (method_exists($plugin_xxx, 'init')) $plugin_xxx->init();
    $args = func_get_args();
    return call_user_func_array(array(&$plugin_xxx, 'inline'), $args);
}
function plugin_xxx_action()
{
    global $plugin_xxx;
    if (method_exists($plugin_xxx, 'init')) $plugin_xxx->init();
    return $plugin_xxx->action();
}