KCAPTCHA + Ethna

EthnaKCAPTCHAを使うというお話。
KCAPTCHAは、よく会員登録サイト等である「ぐにゃ」っと曲がった文字列で画像認証するやつを作るためのPHPクラスライブラリ。PHP+GDで画像を作成してくれます。
例えば、

<img src="sample.php">

の様にして認証用画像を取得。sample.phpの中身はこんな感じ。

<?php
include('kcaptcha.php');

if(isset($_REQUEST[session_name()])){
   session_start();
}

$captcha = new KCAPTCHA();

if($_REQUEST[session_name()]){
   $_SESSION['captcha_keystring'] = $captcha->getKeyString();
}
?>

上のソースはサンプルのまま。
コンストラクタでヘッダ込みの画像データが吐かれるのでimgタグに画像が表示される。と。
表示の後、認証するためには画像に表示されている文字列を画面遷移後も保持しておく必要があるのでこのサンプルでは$_SESSION['captcha_keystring']に保持されているのだけど、ethnaの場合、Ethna_Sessionクラスでセッションが管理されるのでセッションIDが異なるので保持されない。
ということで、Ethnaのアクションクラスを作成

ethna add-action captcha

これで作成される app/action/Captcha.php の perform() 内に上記を真似て次の様な処理を書いておく。

<?php
include('kcaptcha.php');

//(中略)

function perform(){
   if(!$this->session->isStart()){
      $this->session->start();
   }

   $captcha = new KCAPTCHA();
   $this->session->set("captcha_keystring", $captcha->getKeyString());

   return 'captcha';
}
?>

これで、Smartyテンプレート内で

<img src="?action_captcha=true"><br>

何ぞと書けば無事表示。且つ、Ethna_Sessionにも表示した文字列が保持されているので、次のアクションでActionFormで取得した値とセッションの値とを比較すればよい。
なんと便利なライブラリだろう。作者の方に感謝。


…あとでキレイにまとめる。


ずっと愚直にサンプル通りやって、なんでうまくいかないんだろうと悩んでいたのだが、今朝バスに乗った瞬間、気づいたので駅までに着く間の10分でプログラムを書き上げた。
今日、一番集中力が出たのはあの時間だけだったかもしれない。