2012年7月28日土曜日

BEAR.Sundayでコンタクトフォームでも作ってみる

BEAR.Sundayをインストールしたので、
簡単なコンタクトフォームでも作ってみることにした。
何しろtwigすら使ったこと無いので、何もかもが手作業・・・

そして、コードが見にくいですね。すいません。
bloggerがmarkdownに対応してほしい。

Contact.phpを作る



sandbox/Resource/Page/Contact.phpとして以下を作成。

<?phpnamespace sandbox\Resource\Page;
use BEAR\Framework\Resource\AbstractPage as Page;
class Contact extends Page{
    public $body = [];
    public function onGet()
    {
        $this->body[ 'message' ] = 'Please fill in the form.';
        return $this;
    }
}

これが「リソースオブジェクト」になる。
namespaceとファイルの場所を一致させる。違うと何かエラーが出た。
ちなみに、これだけだと何も表示されない。
内容は$this->bodyに入る。そしてonGetメソードの最後のreturn $thisで、内容とともに全ての情報をフレームワークに返している。


テンプレートファイルを作成


sandbox/Resource/Page/Contact.tplとして以下を作成。


<!DOCTYPE html>
<html lang="en">
<body>
<h1>Contact Me</h1>

<p>{$message}</p>
</body>
</html>
アクセスすると「Contact Me」と「Please fill in the form」と表示された。

リソースオブジェクトのクラス名からテンプレートファイルを決定(言うなれば拡張子をtplに変えてる)、テンプレートファイルから表示しているようです。

contact  フォームを作る


次はコンタクトフォームを作ってみる。
以下のformをbody内に書き込んでみた。

<form action="/contact" method="POST">
    <input name="X-HTTP-Method-Override" type="hidden" value="POST" />
    <div class="control-group">
        <div class="controls">
            <input type="text" id="title" name="title" >
            <p class="help-inline"></p>
        </div>
        <div class="controls">
            <textarea type="text" id="body" name="body" rows="8"></textarea>
            <p class="help-inline"></p>
        </div>
    </div>
    <input type="submit" value="Submit">
</form>
大事なのは隠しタグでHTTPメソードをPOSTにしてるところ。
SubmitするとonPostメソードが無いと怒られるので、次のメソードをContact.phpに追加してみた。

    public function onPost()
    {
        $this->body[ 'message' ] = 'You have tried to contact me.';
        return $this;
    }
まさにHTTPメソードがオブジェクトのメソード名に一対一に対応しているのがよくわかります。アクセスすると、メッセージが「コンタクトしてくれたね」みたいな感じになったので動いてますね。結構、簡単です。

フォームの内容を受け取る


onPostの引数に「$title」と「$body」を追加。
    public function onPost( $title, $body )
すると、フォームの内容を受け取れました。

簡単すぎる。
どうやって動いてるのだろう?

本来なら、フォームを受け取ったら、データをモデルに渡して処理を行ってもらうのが正しいと思います。Blogのサンプルコードを見ると、次のようにして処理を受け渡せるようです。
$this->resource->post
        ->uri('app://self/blog/contact')
        ->withQuery(['title' => $title, 'body' => $body])
        ->eager->request();
この場合、Resource/App/Contact.phpクラスを作り、その中で実際の処理を行うことになります。

今回はサンプルですし、メールを出すだけなので、ここではPageのクラス内で処理してしまいます。mail_jp( $mailto, $title, $body );とか書くだけですし。(サンプルなので実際にメールを送信はしません。)

Page内で処理を行うべきか?
行うべきではないですが、まぁいいか、と思う場合はありますよね?

エラー処理をPageとTemplateに加える


フォームと言えばエラー処理。
必須項目の処理を加えました。
エラー表示も他のテンプレートを参考にして修正。

結果:

sandbox/Resource/Page/Contact.php:
<?php
namespace sandbox\Resource\Page;
use BEAR\Framework\Resource\AbstractPage as Page;
class Contact extends Page
{
    public $body = [
        'title' => '',
        'body'  => '',
        'error' => [ 'title' => '', 'body' => '' ],
    ];
    /**
     * @return Contact
     */
    public function onGet()
    {
        $this->body[ 'message' ] = 'Please fill in the contact form.';
        return $this;
    }
    /**
     * @param $title
     * @param $body
     * @return Contact
     */
    public function onPost( $title, $body )
    {
        $this->body[ 'message' ] = 'You have tried to contact me.';
        $this->body[ 'title' ]   = $title;
        $this->body[ 'body' ]    = $body;
     
        if( !$title ) $this->body[ 'error' ][ 'title' ] = 'missing title';
        if( !$body  ) $this->body[ 'error' ][ 'body'  ] = 'missing message body';
     
        if( $title && $body ) {
            // mail_jp( $mail_to, $title, $body );
        }
        return $this;
    }
}


sandbox/Resource/Page/Contact.tpl:

<!DOCTYPE html>
<html lang="en">
<body>
<h1>Contact Me</h1>
<p>{$message}</p>
<form action="/contact" method="POST">
    <input name="X-HTTP-Method-Override" type="hidden" value="POST" />
    <div class="control-group {if $error.title}error{/if}">
        <div class="controls">
            <input type="text" id="title" name="title" value="{$title}">
            <p class="help-inline">{$error.title}</p>
        </div>
    </div>
    <div class="control-group {if $error.body}error{/if}">
        <div class="controls">
            <textarea type="text" id="body" name="body" rows="8">{$body}</textarea>
            <p class="help-inline">{$error.body}</p>
        </div>
    </div>
    <input type="submit" value="Submit">
</form>
</body>
</html>

これでエラー処理が出来ました。


もっとも、メール送信が出来た場合の処理が不十分です。

送信できた場合、今のままだと同じテンプレートを読み込んでしまいます。新たにコントロール変数を追加して、表示内容を変えてもいいのですが、間違った対応方法な気がします。

別に「送信完了、ありがとう」ページを作って、そこに飛ばすのが一番簡単でしょう。

あるいはPageオブジェクト内で、処理の結果により読み込むテンプレートを変更できるとよいのですが。今のところ可能なのかどうか、どうやるのか、さらにはそれが正しい処理なのか、分かりません。

2012年7月23日月曜日

MacにPHP5.4をインストール

PHP5.4を使いたくなった。
最初はVirtualPCインストールしてUbuntuでLAMP環境作ったが、動くのはいいが開発には今ひとつな感じ。

homebrewを使ってインストール


まずは、本体のMac OS X Lionにhomebrewを使ってインストールすることにした。参考にしたのは「Mac OS X Lion: Homebrew, PHP54, MySQL and PEAR」で、ほぼ書いてある通り。


brew tap josegonzalez/php
brew update
brew install php54


多少、あれが無い、これが無いと言われた。
が正確には、あれが無いのでこうしろ、という親切なメッセージなので英語さえ理解できれば簡単に対応できそう。

さ、動いた。
phpinfoを見ると・・・インストールされてない。

pear絡みでエラーが出てるようだ。
Xcodeを4.3.3にアップデートしろと書いてあるので、アップデートしようとしたら・・・何もしてくれない。

仕方が無い。

Macで一番簡単にPHP5.4をインストールする方法


を試してみた。
書いてある通りにcurlをコピペして待つこと5分ぐらいか。
何も応答がなくなったので、心配になったが、ちゃんとインストールしてくれた。
localhostで確認したらphp5.4.5になっていた。


2012年7月21日土曜日

BEAR.Sundayミートアップ#0でLTしました

BEAR.Sunday meetup#0 (2012年7月19日開催)で
LTしてきました。

タイトルは
「Cena-DTA:リソース指向データ転送プロトコル」



Cena-DTAとは2009年の後半から考え始めて、2010年の春頃から開発を始めた技術です。一応、動くところまで持ってきましたが、開発方針で行き詰まってしまい、この一年ほど開発が止まってました。

BEAR.Sundayのmeetup#0に参加すること決めてから何かひらめく物が無いか考えてました。適当なキーワードを散りばめたツイートを書いたり…

そんなとき、LTしませんか?というツイートが!


即、応募しました。
何となく感じてたことを言葉にするいい機会です。

BEAR.Sundayとは関係ない話なのですが、
「気にしないで」という@koriymの言葉に励まされてLTしてきました。

珍しい内容だと思うので、何かの参考になればと思います。

リソース指向とURI


個人的には、
BEAR.Sundayは、全てをURIで表している、という話が面白かったです。

URIというのは間違った理解かも知れません。
ページも含めて、全てを表現するディレクトリ風階層構造、とでもいうのでしょうか。パッと見、URIのような記述

一方Cena-DTAは、ばっさりURIを切り落としてます。
少なくとも細かなリソースごとにURIを用意することはしてません。

これはアプリケーションのモデルが違うからかもしれません。
何しろ「クライアントデバイス上にしか存在してないデータもリソースとして考える」という無茶ぶりで理屈を構築してみたもので。


ともあれ、いまだ興奮冷めやらぬmeetupでした。

2012年7月17日火曜日

UbuntuでJavaが走らない(Error: could not open `/usr/lib/jvm/java-6-sun-1.6.0.26/jre/lib/amd64/jvm.cfg')

Ubuntuで快適に仕事していたが、
突然PhpStormが動かなくなった。

直接端末からPHPStormを起動したらJavaのエラーメッセージが出た。

Error: could not open `/usr/lib/jvm/java-6-sun-1.6.0.26/jre/lib/amd64/jvm.cfg'

そこで、端末から
java -version

と打ってみたら同じエラーが出た。
Javaのインストールエラーだ。

適当に修正



ちょっとググったが、ぴったりのがなかったので、
適当にcdしながら追いかけてみた。
cd /usr/lib/jvm/java-6-sun/jre/lib/amd64

何のことはない、上記のファイルはリンクになっていた。
jvm.cfg -> /etc/java-6-sun/jvm.cfg
リンク先を見ると、java-6-sunというディレクトリがない。
代わりに「java-sun」というのがある。

そこで
sudo ln -s /etc/java-sun/jvm.cfg .

としたら治った。

ググるより、自分で解決したほうが早そうな、珍しいパターンでした。

壊れた原因は・・・


思いつくのは、さくらインターネットさんでVPSを借りた。
Ubuntuをインストールするには、VNCクライアントが必要で、それを動かすためにJREをインストールした覚えがある。それで壊れたのか。

些細な原因ですが、いちいち面倒だな。
その点、WindowsやMac/OS Xとかは、きちんとしてそう。
その代わり有償だし色々と不自由だけど。