Standing on the Shoulder of Linus

Home / 2013 / 12月 / 10 / FuelPHP イベント機能を使ってアプリケーションをカスタマイズする

FuelPHP イベント機能を使ってアプリケーションをカスタマイズする

FuelPHP advent Calendar 2013の10日目です。昨日はAspectMockでFuelPHPのアプリを100%テスト可能にする(@kenji_s)でした。

今日は、「イベント機能を使ってアプリケーションをカスタマイズする」です。

イベントとは何か

イベントとは、FuelPHPコアを書き換えることなく、独自の処理を差し込むことができる仕組みです。

  • FuelPHPの処理の途中に、トリガー(ここを通ったときに、追加処理を実行する場所)がいくつか用意されている
  • トリガー名を指定して、独自の処理を追加する
  • 独自の処理が追加されたトリガーのところで、独自の処理が実行される

という仕組みです。WordPressを使っている方であれば、「WordPressのアクションフックに似ている」と思うかもしれません。

アプリケーションの処理の流れ: 青丸がトリガー
アプリケーションの処理の流れ

イベントを実行: 処理途中の各トリガーの所では、登録されているイベントがあれば実行する
イベントを実行

コードは点線部分で分離されている: アプリケーション自体のコードに手を入れずに、機能追加/変更する
コードは点線部分で分離されている

独自の処理を追加する

2通りの方法が用意されています。

  1. app/config/event.phpに追加する方法
  2. Event::registerを使う方法

1.は、app/configにevent.phpに書く方法です。詳細はEvent クラス(FuelPHP1.7)をごらんください。

2. は、registerメソッドを使う方法です。今回はこちらを使います。Event クラス(FuelPHP1.7)では、user_loginにClass::method処理を追加する例が掲載されています。

Event::register('user_login', 'Class::method');

bootstrap.phpに書けば、トリガーにフックできます。

トリガーにフックしてみる

では、実際にトリガーにフックしてみましょう。ここでは、Novius OSにフックする例を紹介します。Novius OSは、FuelPHPベースのCMSで、jQuery UI、Wijmoを使った使い易いインターフェースが特徴です。Novius OS Chiba2のイベント一覧にあるadmin.loginFailを使い、ログイン失敗をログに記録します。

/**
 * Copyright (c) 2013 Fumito MIZUNO
 * License: MIT 
 * http://opensource.org/licenses/mit-license.php
 */
Event::register('admin.loginFail', 'warning_on_loginfail');

function warning_on_loginfail()
{
    $message = 'Login Fail.';
    $message .= '  Email: ' . Input::post('email');
    $message .= '  Password: ' . Input::post('password');
    $message .= '  IP: ' . Input::ip();
    Log::warning($message);
}

Novius OSは、メールアドレスとパスワードでユーザー認証するので、ログイン失敗時にそれらを記録します。これらはFuelPHPのInputクラスを利用します。引数無しでInput::post()を実行すると$_POSTを全部取ってきて配列で返すので、丸ごと記録したければFormat::forge(Input::post())->to_serialized()としてもいいでしょう。またアクセス元のIPアドレスも記録し、ログ記録にはFuelPHPのLogクラスを利用します。ログ記録の内部処理はMonologライブラリ(MITライセンス)が行っています。

ログインに失敗すると、ログファイルに

WARNING - 2013-12-09 09:15:23 --> Login Fail. Email: email@example.com Password: p@ssw0rd IP: 127.0.0.1

のように記録されます。

デフォルトで用意されているイベント

Event クラス(FuelPHP1.7)によると、デフォルトで用意されているイベントは、app_created、request_created、request_started、controller_started、controller_finished、response_created、request_finished、shutdownです。これらのトリガーに処理を追加することができます。

アプリケーションにトリガーを用意する

コアに用意されているトリガーを使うだけではなく、アプリケーションにもトリガーを用意することができます。アプリケーションの処理の流れ: 青丸がトリガーの、青丸を作る作業です。コード中の適当な箇所に、Event::trigger(トリガー名)と書けばOKです。

Novius OS のログイン部分のコード(novius-os/framework/classes/controller/admin/login.ctrl.php)を見てみると、ログイン成功時にadmin.loginSuccessイベント、ログイン失敗時にadmin.loginFailイベント、が用意されています。

/**
 * NOVIUS OS - Web OS for digital communication
 *
 * @copyright  2011 Novius
 * @license    GNU Affero General Public License v3 or (at your option) any later version
 *             http://www.gnu.org/licenses/agpl-3.0.html
 * @link http://www.novius-os.org
 */

namespace Nos;

class Controller_Admin_Login extends Controller
{
// 途中省略
    protected function post_login()
    {
        if (NosAuth::login($_POST['email'], $_POST['password'], (bool) Input::post('remember_me', false))) {
            if (Event::has_events('user_login')) {
                Log::deprecated('Event "user_login" is deprecated, use "admin.loginSuccess" instead.', 'Chiba.2');
                Event::trigger('user_login');
            }
            Event::trigger('admin.loginSuccess');
            return true;
        }
        Event::trigger('admin.loginFail');
        return __('These details won’t get you in. Are you sure you’ve typed the correct email address and password? Please try again.');
    }
}

どういうときに役に立つのか

アプリケーションを全て自分で作っている場合は、わざわざイベントトリガーを用意するメリットはあまりないかもしれません。トリガーを使わずに書いても良いでしょう。トリガーが威力を発揮するのは、パッケージやアプリケーションをオープンソースで公開する場合だと思います。

Novius OSのログイン失敗時のログを取りたい場合、上述のpost_loginメソッドを直接書き換えるというやり方でも、ログ機能を追加することはできます。でもこの方法だと、元のアプリケーション(Novius OS)のアップデート時に書き直しすることになります。

では、イベントを活用した場合はどうでしょう。Novius OSではトリガーが用意されています。カスタマイズしたい人は、トリガーにフックするコードを自作し、bootstrap.phpに記述します。この方法だと、アプリケーションのコードに手を入れることなく、処理を追加することができます。自分で追加した部分は元のアプリケーションのコードから分離でき、アップデートが楽になります。

もちろん、イベントを使ってカスタマイズするには、トリガーが設定されていなければなりません。なので、パッケージやアプリケーションを公開して、他の人にも使ってもらいたい、という場合には、イベントトリガーを設定しておくと良いでしょう。

まとめ

イベントを使うことで、フレームワークやアプリケーションのコードに手を入れることなく、処理を追加することができます。オープンソースで公開するアプリケーションには、イベントのトリガーを用意しておくと、カスタマイズしやすくなります。

明日は、「FuelPHP をもっと Composer で使う」(chatii0079)です。お楽しみに。

関連

Posted in fuelphp | Tagged Novius-OS, フレームワーク
← ユーザー毎の閲覧記録をローカルストレージに記録し、訪問状況に応じてnewを表示する 電子書籍99円セールの結果 →

アーカイブ

人気の投稿とページ

  • キンドル本を印刷する(PDFに変換する)方法
  • 名古屋駅から国際センターまでの道のり(徒歩)
  • AGPL ライセンス(GPLとは似ているが違いもある)
  • 6年使ったイーモバイル(Y!mobile)を解約手続。店頭でSIM返却
  • JP-Secure SiteGuard WP Pluginは不正ログイン防止に役立つか

プロフィール

水野史土:月70万PVホームページ制作会社のレスキューワーク株式会社で、PHPソフトウェアのサポートを行っている。concrete5コミュニティリーダー、Novius OSコアコード貢献者でもある。 詳しくは管理者詳細参照。
大好評WordPress書籍「WordPressユーザーのためのPHP入門 はじめから、ていねいに。」サポートページ

Copyright © 2015 Standing on the Shoulder of Linus.