FuelPHP Authパッケージ – Simpleauthの使い方

FuelPHPは認証機能を標準で含まれるパッケージAuthで提供しています。
Authには3つのドライバーの実装が含まれています。

  • Simpleauth: 基本パッケージ
  • Ormauth: 基本パッケージのORM対応版
  • Opauth: Facebook、Twitter連携などログイン連携機能を提供

Authパッケージは、機能をAPI形式で利用します。
(Railsでいうところのdeviseではなくsorceryに近い)
そのため、決まりきった定型フォームを用意する必要があり面倒ですが、柔軟にサインアップフローが設計できるという面もあります。

以下、Simpleauthの使い方を確認した際のメモです。

auth パッケージを always_load に設定
注意: configも追加する必要あり

// app/config/config.php
    'always_load'  => array(
        // ...
        'packages'  => array('auth'),
        // ...
        'config'  => array('auth'),
        // ...
    ),

simpleauth用のテーブルを定義

$ oil refine migrate --packages=auth
Performed migrations for package:auth:
001_auth_create_usertables
002_auth_create_grouptables
003_auth_create_roletables
004_auth_create_permissiontables
005_auth_create_authdefaults
006_auth_add_authactions
007_auth_add_permissionsfilter
008_auth_create_providers
009_auth_create_oauth2tables
010_auth_fix_jointables

テスト用コントローラを作成

$ oil generate controller auth login register success_page
    Creating view: /Applications/MAMP/htdocs/fuelphp-simpleauth/fuel/app/views/template.php
    Creating view: /Applications/MAMP/htdocs/fuelphp-simpleauth/fuel/app/views/auth/login.php
    Creating view: /Applications/MAMP/htdocs/fuelphp-simpleauth/fuel/app/views/auth/register.php
    Creating view: /Applications/MAMP/htdocs/fuelphp-simpleauth/fuel/app/views/auth/success_page.php
    Creating controller: /Applications/MAMP/htdocs/fuelphp-simpleauth/fuel/app/classes/controller/auth.php
// fuel/app/classes/controller/auth.php
class Controller_Auth extends Controller_Template
{
    public function before()
    {
        ...
    }

    public function action_login()
    {
        ...
    }

    public function action_success_page()
    {
        ...
    }

    public function action_register()
    {
        ...
    }

    public function action_logout()
    {
        ...
    }
}

ログイン処理は、Simpleauthのドキュメントの はじめに 例 とほぼ同じです。

// fuel/app/classes/controller/auth.php#action_login
    public function action_login()
    {
        $data = array();

        if (Input::post())
        {
            if (Auth::login(Input::post('email'), Input::post('password')))
            {
                Response::redirect('auth/success_page');
            }
            else
            {
                $data['username']    = Input::post('username');
                Session::set_flash('error', 'Wrong username/password combo. Try again');
            }
        }

        $this->template->title = 'Auth » Login';
        $this->template->content = View::forge('auth/login', $data);
    }

Auth::login メソッドを利用してログインを実行します。

// fuel/app/views/auth/login.php
<?php echo Form::open(); ?>
    <div class="control-group">
        <label class="control-label" for="email">Email</label>
        <?php echo Form::input('email', '', array('id'=>'email', 'class'=>'form-control', 'placeholder'=>'Email')); ?>
    </div>
    <div class="control-group">
        <label class="control-label" for="password">Password</label>
        <?php echo Form::password('password', '', array('id'=>'password', 'class'=>'form-control', 'placeholder'=>'Password')); ?>
    </div>
    <div class="control-group">
        <?php echo Form::submit('submit', 'Login', array('class'=>'btn btn-primary')); ?> |
        <?php echo Html::anchor('auth/register', 'Sign up'); ?>
    </div>
<?php echo Form::close(); ?>

Controller_Templateを利用しているので、メッセージはset_flashしています。

ユーザの登録処理は、Auth::create_userを使用します。
第4引数のグループと第5引数の追加情報はここでは使わないので省略しています。

// fuel/app/classes/controller/auth.php#action_register
    public function action_register()
    {
        $data = array();

        if (Input::post())
        {
            Auth::create_user(
                Input::post('username'),
                Input::post('password'),
                Input::post('email')
            );
            Session::set_flash('success', 'You have been successfully registered.');
            Response::redirect('auth/login');
        }
        $this->template->title = 'Auth &raquo; Register';
        $this->template->content = View::forge('auth/register', $data);
    }
// fuel/app/views/auth/register.php"]
<?php echo Form::open(); ?>
    <div class="control-group">
        <label class="control-label" for="email">Email</label>
        <?php echo Form::input('email', '', array('id'=>'email', 'class'=>'form-control', 'placeholder'=>'Email')); ?>
    </div>
    <div class="control-group">
        <label class="control-label" for="username">Username</label>
        <?php echo Form::input('username', '', array('id'=>'username', 'class'=>'form-control', 'placeholder'=>'Username')); ?>
    </div>
    <div class="control-group">
        <label class="control-label" for="password">Password</label>
        <?php echo Form::password('password', '', array('id'=>'password', 'class'=>'form-control', 'placeholder'=>'Password')); ?>
    </div>
    <div class="control-group">
        <?php echo Form::submit('submit', 'Register', array('class'=>'btn btn-primary')); ?> |
        <?php echo Html::anchor('auth/login', 'Login'); ?>
    </div>
<?php echo Form::close(); ?>

ログイン成功後のテストページ

// fuel/app/classes/controller/auth.php#action_success_page"]]
    public function action_success_page()
    {
        $this->template->title = 'Auth &raquo; Success page';
        $this->template->content = View::forge('auth/success_page');
    }
// fuel/app/views/auth/success.php"]
<p>Success page</p>
<p><?php echo Html::anchor('auth/logout', 'Logout'); ?></p>

ログアウト処理

// fuel/app/classes/controller/auth.php#action_logout
    public function action_logout()
    {
        if ( Auth::logout() )
        {
            Response::redirect('auth/login');
        }
        else
        {
            Session::set_flash('error', 'Logout failed.');
            Response::redirect_back('auth/success_page', 'refresh');
        }
    }

認証チェック
ログイン済みかどうかは、Auth::check メソッドを使ってbeforeメソッドでチェックしています。

ここでは、success_page だけをチェック対象としています。

// fuel/app/classes/controller/auth.php#before
    public function before()
    {
        parent::before();

        if ( Request::active()->action === 'success_page' && ! Auth::check())
        {
            Session::set_flash('error', 'You must be logged in.');
            Response::redirect('auth/login');
        }
    }

FuelPHPでファイルアップロード

アップロードフォームのView

<?php echo Form::open(array("class"=>"form-horizontal", "enctype"=>"multipart/form-data")); ?>
  <?php echo Form::file('file'); ?>
  <?php echo Form::submit('submit', 'Upload', array('class' => 'btn btn-primary')); ?>
<?php echo Form::close(); ?>

Controller

public function action_upload($id = null)
{
    $config = array(
        'path' => 'files',
        'new_name' => $file_name,
        'ext_whitelist' => array('jpg', 'jpeg'),
    );
    Upload::process($config);

    if (Upload::is_valid())
    {
        Upload::save();
        $file = Upload::get_files(0);

        Session::set_flash('success', $file['name']." has been uploaded successfully.");
    }
    else
    {
        $error_file = Upload::get_errors(0);
        Session::set_flash('error', $error_file["errors"][0]["message"]);
    }
}

Sublime text 2のphpcsプラグインでFuelPHPのスタイルを設定する

FuelPHP用のphpcsは以下のGithubリポジトリから取得する。
https://github.com/eviweb/fuelphp-phpcs

クローンして Standards/FuelPHP ディレクトリを
Applications/MAMP/bin/php/php5.4.4/lib/php/PHP/CodeSniffer/Standards にコピー
[bash]
$ git clone https://github.com/eviweb/fuelphp-phpcs.git
$ cd fuelphp-phpcs-master/Standards
$ sudo cp -r FuelPHP/ /Applications/MAMP/bin/php/php5.4.4/lib/php/PHP/CodeSniffer/Standards/
[/bash]
PHP Code Snifferプラグインの設定を変更する。

Preferences > Package Settings > PHP Code Sniffer > Settings – User
[text]
"phpcs_additional_args": {
// "–standard": "PEAR",
"–standard": "FuelPHP",
"-n": ""
},
[/text]

FuelPHP プロジェクトを作成後 Bitbucket masterリポジトリに切り替えるには

FuelPHPでプロジェクト作成後 Bitbucketに作成したリポジトリのmasterブランチにpushするまでの手順をまとめておきます。

Bitbucketでリポジトリを作成:
Bitbucket-create-repository

リポジトリが作成されると、作成されたリポジトリのページが表示されます。
Bitbucket-created-repository
[私はこれまでに作ったリポジトリをプッシュします。]をクリックするとpushの手順が表示されます。
bitbucket-3

FuelPHPでプロジェクトを作成した後、この手順に沿って、Bitbucketに作成したHello FuelPHPリポジトリにpushしてみます。

FuelPHPプロジェクトの作成は、Hello FuelPHP を参考に作成してください。

oilコマンドでプロジェクトを作成した後、以下のコマンドで確認すると originfuel.git が指定されています。 [bash]
$ git remote -v
origin git://github.com/fuel/fuel.git (fetch)
origin git://github.com/fuel/fuel.git (push)
[/bash]
そこで、手順の git remote add origin の行は、替わりに remote set-url コマンドを使います。

また、1.7/mastermaster に変更してからpushします(FuelPHPプロジェクトをgit管理するときにすべきこと を実行している場合は、すでにmasterになっています)。

以下、全体の手順です。
[bash]
$ oil create fuelblog

$ cd fuelblog
$ git branch
* 1.7/master
$ git branch master
$ git checkout master
M composer.phar
M docs
Switched to branch ‘master’
$ git remote set-url origin https://hendoh@bitbucket.org/hendoh/fuelblog.git
git push -u origin –all
[/bash]

[ソース]を開くと、プロジェクトのファイルがpushされたことが確認できます。
bitbucket-4

追記
プロジェクトを作成したら、まず FuelPHPプロジェクトをgit管理するときにすべきこと を実行しておいた方が良いようです。

WordPressをBackWPupプラグインを使ってAWS S3に定期バックアップするには

WordPressもAWS S3にバックアップしておこう思ってシェルを書こうと、ぐぐってみたら、バックアップ関連のプラグインがたくさん見つかりました。
そこで、最も使われていそうな BackWPup をインストールして、S3へバックアップを保存するようにセットアップしてみました。

プラグインのインストールは、メニューの [プラグイン]/[新規追加] から キーワード BackWPup で検索して、インストールします。

インストール後、BackWPupメニューが追加されます。
バックアップの設定は Job という単位で管理できるので、まず Job 作成して設定していきます。

メニューの[BackWPup]/[Add New Job]を選択します。

BackWPup-setting

[General]タブの [Job Destination]の[Where should your backup file be stored?]で[Backup to an S3 Service]にチェックを入れると、[To: S3 Service]タブが表示されます。

[To: S3 Service]タブを開いて、AWSのアクセスキーやS3 Backetを設定します。

BackWPup-setting-s3

今回設定した項目を説明します。

S3 Service

Select a S3 service: 指定するBacketを含むリージョンを選択します。

S3 Access Keys

Access Key: AWSのアクセスキーを指定します。
Secret Key: AWSのシークレットキーを指定します。

S3 Bucket

Bucket selection: バックアップを保存するBucketを選択します。アクセスキーを入力すると、選択しているリージョン内に存在するBucketが自動で読み込まれます。

ひとまず、後はデフォルトで [Save changes] をクリック。

バックアップの実行は、メニュー[Jobs]を選択して作成したJobの[Run now]をクリックします。

BackWPup-runnow

S3にバックアップが保存されました。

BackWPup-runnow-s3

最後に定期実行を設定します。

[Start job]で、[with WordPress Cron]を選択して[Save changes]します。
今回は他はデフォルトの日時で実行時間AM3時を選択しました。
BackWPup-schedule

バックアップの確認

手動実行したファイルとは別に 自動実行されたバックアップファイルが追加されています。
BackWPup-wpcron-s3

リストア手順

最後にバックアップの復元手順も確認しておきます。
バックアップの復元は、wordpressが置かれているディレクトリに解凍します。
データベースは、解凍ディレクトリ直下にある <データベース名>.sql を復元対象のデータベースに対して実行します。
sqlは復元後不要なので消しておきます。
[bash]
$ sudo tar xvfz backwpup_9bfb6f_2014-01-11_03-26-46.tar.gz -C /var/www/wordpress
$ cd /var/www/wordpress
$ mysql -uroot wordpress < wordpress.sql
$ rm wordpress.sql
[/bash]

サーバー移行先で権限変更が必要な場合は、展開したファイルに再度権限を付与します。
[bash]
$ sudo chown -R www-data.www-data wordpress/
[/bash]


トラブルシューティング

1. [Job Destination] で、以下のメッセージが表示されている

 Backup to an S3 Service
Missing function "curl_exec".

php-curlを入れてapacheを再起動します。
[bash]
$ sudo apt-get install php-curl
$ sudo service apache2 restart
[/bash]

2. [run now] をクリック後に以下のエラーが発生
BackWPUp-Error
php-xml が必要です。(参照:php: XMLWriter.php がない)
php-xmlをインストールして、Apacheを再起動。
[bash]
# yum install php-xml
# service httpd restart
[/bash]

FuelPHP Composerでライブラリー•パッケージを管理するには

FuelPHP は 1.6 からライブラリーやパッケージの管理に Composer を利用できるようになりました(1.6 リリースノート)。

Composer関連のファイルは、生成したプロジェクト直下にあります。

  • composer.json
  • composer.lock
  • composer.phar

comporser.json を開いてみるとデフォルトで、以下の3つのみ指定があります。

{
    ...
    "require": {
        "php": "<=5.3.3",
        "monolog/monolog": "1.5.*",
      "fuelphp/upload": "2.0.1"
    },
    ...
}

Composerでインストールされたライブラリーは fuel/vendor ディレクトリに展開されます。

fuelphp-composer-fuel-vendor
“FuelPHP Composerでライブラリー•パッケージを管理するには” の続きを読む

FuelPHP PaginationにBootstrapを適用するには

FuelPHPでは、Pagination クラス を利用してページングを実装します。

以下は、Admin Scaffoldで作成したCompanyというモデルを一覧するindexアクション内のページングのコードです。
このページでは、検索条件は指定せず全件を対象としています。

Bootstrapを適用するには、ハイライトされている2行を追加するだけです。
[php highlight=”12,13″]
public function action_index($page = 1)
{
$par_page = 10;
$query = Model_Company::query();

$config = array(
‘pagination_url’ => Uri::base(false).’admin/company/index/’,
‘total_items’ => $query->count(),
‘per_page’ => $par_page,
‘uri_segment’ => count(explode(‘/’, Uri::base())),
‘current_page’ => (int)$page,
‘name’ => ‘bootstrap’,
‘wrapper’ => ‘<ul class="pagination">{pagination}</ul>’,
);
$pagination = Pagination::forge(‘mypagination’, $config);
$data[‘pagination’] = $pagination;

$data[‘companies’] = $query->offset(($page-1)*$par_page)->limit($par_page)->get();


}
[/php]
ビューは、以下のコードを変更する必要はありません。
[php]
<?php echo Pagination::instance(‘mypagination’)->render(); ?>
[/php]

FuelPHPに独自の設定ファイルを追加する

設定ファイルを新たに追加するには、fuel/app/config/に Arrayを返すPHPファイルを置きます。

以下、ページングの件数の共通設定を追加してみた例です。

fuel/app/config/paging.php
[php]
<?php
return array(
‘per_page’ => 20,
);
[/php]

設定の読み込みは Config::load メソッドを呼び出す必要があります。
[php]
Config::load(‘paging’);
[/php]
全体で利用する設定の場合は fuel/app/bootstrap.php に追加してしまって良い気がします。

設定値の読み込みは Config::get メソッドを使います。
[php]
Config::get(‘paging.per_page’)
[/php]

公式ドキュメント: Config Class

Hello FuelPHP

FuelPHPは、PHPのメジャーなMVCフレームワークの一つです。

規約よりも設定というRuby on Rails的なMVCフレームワークとは逆行するコンセプトですが、非常に柔軟にアプリケーションを実装できとても使い勝手の良いフレームワークです。

また機能についても、データベースアクセスにクエリービルダー形式とORMのサポートがあり、ORMは関連も含めて複合キーも使えたりと、他のフレームワークで意外と困ることを難なくこなしてくれます。

ただ、FuelPHPは、MySQLでしかまともに動きません。Postgresqlの場合は、1.7でもシーケンスの扱いなどそれなりに修正が必要となります。
また、PHP系のフレームワークだとどれもそうですがユニットテストのサポートがイマイチなので、その辺りは割り切りがある程度必要そうではあります。

チュートリアル
Fuel Crash Course

セットアップ

公式ドキュメントのインストール方法に掲載されている「コマンドラインからインストール」の手順に従ってプロジェクトを作成します。
[bash]
$ cd /var/www
$ curl get.fuelphp.com/oil | sh
$ oil create blog
[/bash]
oil は、CakePHPの bake、 Railsの rails コマンドに当たります。

Apacheに設定を追加

[text]
<VirtualHost *:80>
ServerName www.blog.net
DocumentRoot /var/www/blog/public
</VirtualHost>
[/text]
/etc/hosts にwww.blog.netとそのIPアドレスを追加します。
[text]
127.0.0.1 www.blog.net
[/text]
http://www.blog.net にアクセスして以下の画面が表示されればセットアップは成功です。
fuelphp_welcome

Scaffold

データベースを作成

[bash]
$ mysql -uroot -p
mysql> CREATE DATABASE blog DEFAULT CHARACTER SET utf8;
[/bash]
fuel/app/config/development/db.phpに作成したデータベースを設定
[php]
return array(
‘default’ => array(
‘connection’ => array(
‘dsn’ => ‘mysql:host=localhost;dbname=blog’,
‘username’ => ‘root’,
‘password’ => ‘root’,
),
),
);
[/php]
参照: PDO_MYSQL DSN

ORMパッケージを有効にする

fuel/app/config/config.phpの257行目からのAlways Load セクションの該当箇所をコメントアウトして設定します。
[php]

/**************************************************************************/
/* Always Load */
/**************************************************************************/
‘always_load’ => array(

‘packages’ => array(
‘orm’,
),

),

[/php]
これで、scafoldを実行する準備が整いました。
scaffoldを実行して、生成されるマイグレーションを実行してデータベースに適用します。
[bash]
$ php oil generate scaffold posts name:string message:text

$ php oil refine migrate
Performed migrations for app:default:
001_create_posts
[/bash]
http://www.blog.net/posts にアクセスすると以下のようなPostの一覧画面が表示されます。
fuel_php_posts