web-dev-qa-db-ja.com

クラスでregister_activation_hookを使用する

私が知っている多くの人がYoastを使うのを好まないので、私は基本的なSEOの目的のためにプラグインを開発しようとしています。私は文字通りプラグインを始めたばかりで、プラグインをアクティブにしたときにユーザーに表示されるアクティブ化メッセージを作成しています。 OOPと組み込みのWordpress関数の混在に問題があり、どこに問題があるのか​​わかりません。

これを機能させる唯一の方法は、メインファイルのコンストラクタ内に SEO_Plugin_Activation クラスの新しいインスタンスを作成し、そのクラス内でactivatePluginメソッドを呼び出すことです。これは不要だと思います。また、アクティベーションクラスファイルで関数を実行する方法もあまり意味がありません。しかし、それが私が今それを機能させることができる唯一の方法です。

私が行っていることがOOPのテクニックを100%把握していないからなのか、それともWordpress APIを正しく利用していないのか、私にはわかりません。次の順序で3つのコード例を含めました。

  1. メインプラグインファイル
  2. アクティベーション要件を処理するクラスファイル
  3. 私が本当に望んでいたことができるでしょう。

seo.php(メインプラグインファイル)

<?php
/*
... generic plugin info
*/

require_once(dirname(__FILE__) . '/admin/class-plugin-activation.php');

class SEO {
  function __construct() {
    $activate = new SEO_Plugin_Activation();
    $activate->activatePlugin();
  }

}

new SEO();
?>

class-plugin-activation.php

<?php
class SEO_Plugin_Activation {

  function __construct() {
    register_activation_hook(__FILE__ . '../seo.php', array($this, 'activatePlugin'));
    add_action('admin_notices', array($this, 'showSitemapInfo'));
  }

  function activatePlugin() {
    set_transient('show_sitemap_info', true, 5);
  }

  function showSitemapInfo() {
    if(get_transient('show_sitemap_info')) {
      echo '<div class="updated notice is-dismissible">' .
              'Your sitemap files can be found at these following links: ' .
            '</div>';
      delete_transient('show_sitemap_info');
    }
  }

}
?>

seo.php(私が望んでいたこと)

<?php
/*
 ... blah blah blah
*/

require_once(dirname(__FILE__) . '/admin/class-plugin-activation.php');

class SEO {
  function __construct() {
    register_activation_hook(__FILE__, array($this, 'wp_install'));
  }

  function wp_install() {
    $activate = new SEO_Plugin_Activation();
    // Execute some method(s) here that would take care 
    // of all of my plugin activation bootstrapping
  }

}

new SEO();
?>

私は3番目のスクリプトで概説した方法でそれを試みましたが、成功していません。現時点では、メッセージは正しく表示され、エラーメッセージは表示されません。

3
Dan Zuzevich

あなたの質問を読んで、私は問題を見ると思います、そしてそれはあなたがあなたのコードをブートストラップしている方法とそれがブートストラップすることの意味についてのいくらかの混乱と結合したregister_activation_hookの仕組みの誤解に起因すると思います

パート1:register_activation_hook

この関数は2つのパラメーターを取ります。

register_activation_hook(string $ file、callable $ function)

最初のパラメーター$fileはメインのプラグインファイルであり、実行するものを含むファイルではありません。 plugins_urlと同じ方法で使用されるため、__FILE__の値、特にプラグインヘッダーを含むルートプラグインファイルの値が必要です。

2番目のパラメーターは呼び出し可能であり、期待どおりに機能しますが、実際にはadd_actionを内部で使用しているだけです

プラグインがアクティブになると、アクション「activate_PLUGINNAME」フックが呼び出されます。このフックの名前のPLUGINNAMEは、オプションのサブディレクトリを含むプラグインの名前に置き換えられます。たとえば、プラグインがwp-content/plugins/sampleplugin/sample.phpにある場合、このフックの名前は「activate_sampleplugin/sample.php」になります。

パート2:ブートストラップと__FILE__

ここでの基本的な問題は、__FILE__が異なる場所で異なる値を持ち、特定の値が必要なことです。

また、ブートストラップでオブジェクトグラフを組み立てる必要があるという問題もありますが、それはしません。すべてのオブジェクトは、定義されるとすぐに作成されるか、相互に作成されるため、値を渡すことが困難または不可能になります。

例として、次のようなプラグインを作成できます。

plugin.php

<?php
/**
 * Plugin Name: My Plugin
 * Version: 0.1
 */

// loading step
require_once( 'php/app.php' );

// bootstrapping step
$app = new App( __FILE__ );

// execution step
$app->run();

すべてのクラスをphpサブフォルダーで定義し、それらをすべて同じ場所にロードしました。 PHPは私のクラスが何であるか、名前などを知っていますが、まだ何も起きていません。

次に、すべてのオブジェクトを作成し、必要なものを渡します。この場合、Appには__FILE__の値が必要なので、それを渡します。これにより、メモリ内にオブジェクトが作成されますが、作業は行われないことに注意してください。プラグインアプリケーションの準備が整い、アクションを開始できますが、準備段階です。

次のステップは、これらのオブジェクトを一連の単体テストにパイプすることかもしれませんが、ここでそれらを実行します。ブートストラッププロセスを完了し、アプリケーションを実行する準備ができたので、runメソッドをトリガーします。必要なものはすべてコンストラクターに渡されているので、runに何も渡す必要はありません。 runメソッド中に、すべてのフィルターとフックを追加します。プラグインの他のすべての部分が実行されるのは、これらのフック中です。

しかし重要な部分は、定義された構造を持っていることと、定義されたライフサイクルで、構築/ブートストラップ段階で必要なものを渡すことです

7
Tom J Nowell

Tom McFarlinは非常に大規模な プラグイン定型文 (現在はDevin Vinsonによって管理されています)を作成しました。これらはすべてOOPで書かれています。私はいくつかのカスタムプラグインにそれを使用しました、そしてそれが本当にOOPのいくつかの謎に私の目を開いたと言わなければなりません。

1
Gary D

kaiser's answer のように、有効化/無効化/アンインストールのフックをプラグインクラスの外に登録する必要があります。

このプラグインを学習課題として書いているのなら、それはあなたをカバーするはずです。あなたが探しているのがうまくいって、Yoastのような粘着性のある広告で埋め尽くされていないSEOプラグインだけであるならば、私は強くSEOフレームワークを推薦することができます。

1
Chris Cox