Model Layer in Symfony(PHP Framework)



project_dir/lib/model/にXXX.phpとXXXPeer.phpの2種類のModel Classが作成され、さらにproject_dir/lib/model/om/にBaseXXX.phpとBaseXXXPeer.phpの2種類のBase Data Model Classが作成されますが、Askeet day 10を読んでいて、それぞれの意味がなんだったのかがわからなくなったので、Symfony BookのModel Layerの章を読み直しました。

要点をまとめておきます。
・project_dir/lib/model/om/以下のBase Data Model Classはschema.xmlを変更し、propel-build-modelコマンドの実行時にすべて再生成されるので、カスタマイズする場合はproject_dir/lib/model/以下のModel Classを変更する必要がある。もしBase Data Model Classが変更された場合でも、extendsによりクラスが継承されるので、schema.xmlの変更はそのまま継承される。

・PeerではないXXX.phpはDBのレコードに相当するObject Classで、レコードのカラムや関連レコードを取得することができる。一方、XXXPeer.phpはPeer Classであり、DBテーブルを操作するためのstaticメソッドを含むクラスで、テーブルからレコードを取得する方法を提供し、オブジェクトあるいはオブジェクトの集合をreturn valueとして返す。

Askeet - Symfony

PHPフレームワークであるsymfonyの解説書がWebで公開されていることを以前ここで書きましたが、先日これを読み終わったので、今はaskeetというチュートリアルを読んでいます。完成品は既にオープンソースとして公開され、デモも用意されています。

本論からは脱線しますが、このチュートリアルの副題はsymfony Advent Calendarとなっており、Adventとは日本語で「降臨節」と言うそうです。Wikipediaによると、降臨節とは「イエス・キリストの降誕を待ち望む期間の事」とのことで、このチュートリアルが12/1から12/24までの24日間毎日公開されることを指して、Adventと表現しているようです。

なかなかやることが粋だなぁと思いました。

MT(Movable Type)の人気記事ランキングの表示

人気記事のランキングを表示するためのMT用プラグインがT-MostVisited Pluginとして公開されているのだが、記事ファイル名に記事IDを含んでいる必要があるらしく、私のサイトでは利用できなかった。そこで、Open MagicVox.netさんのサイト記事IDを含まない記事ファイル名でもランキング表示できるスクリプトを公開されていたので、利用させていただきました。
#ぴろりさん、素敵なスクリプトをありがとうございます。

結果は、
My Video Cafe
の右カラムに表示されている通りなのですが、私のサイトでは、カテゴリ単位でランキングを分けたいという要望がありましたので、表示のカスタマイズ以外にも少々改造しました。

スクリプト(hottopic200.php.tmpl)のGetEntryList()で既存の記事エントリのリストを作成しており、その

<MTEntries lastn="999999">

という箇所を、

<MTEntries category="foo OR hoge OR bar" lastn="999999">

<MTEntrieswithsubcategories category="hogehoge" lastn="999999">

に変更することで、fooとhogeとbarというカテゴリに属するエントリのリストや、hogehogeというカテゴリのサブカテゴリ全部のリストを作成します。(サブカテゴリを利用する場合は終了タグの変更も必要です)

次に、MergeCount2EntryList()で上記で作成したエントリリスト内をアクセスログから取得したエントリのURLで検索しているのですが、対象外のカテゴリのエントリURLならば、エントリリストのArrayから見つけられない場合が発生するため、新たにフラグを設定し、エントリが見つからなかった場合は、

$flag = false;
foreach ($entry_list as $index => $value) {
  if (is_string (stristr ($value['EntryPermalink'], $url))) {
  // 中略
  $flag = true;
  }
}
if (!$flag) {
  $nTopEntry++;
  if ($cur_score != $score) {
    $ranking--;
  }
}

$nTopEntryと$rankingを元の値に戻し、次のURLに処理を移します。(やっつけすぎ?)
厳密に言えば、ランキングの同値順位の処理が正しくないのだが、重要性が低いと判断し、私は良しとしました。
具体的には、1位、2位、2位の次は、4位なのですが、デフォルトのスクリプトでは3位になります。
同様に、新たにフラグを設定し、外側のforeach文のreturnの直前に、
if ($same) {
$ranking++;
}
を入れてあげればいいのでしょうが、エレガントでないので、導入は見送り。

それよりはむしろ、そんな細かいことを指摘するユーザはいないと信じたい。

(追記)
上記のコードだと、3つ以上の同順位があると、正しく動作しないので、やはり同順位数をカウントして、順位を繰り下げるようにしないとダメですね。

XOOPSの携帯対応

今運用しているXOOPSサイトのユーザさんから携帯からもアクセスしたいという要望を受け、その方法を模索しています。mixiのコミュニティでも話題になっていましたが、既存のXOOPSを使い続けるという前提では、以下の3つの方法があるようです。
1.xmobileモジュールを使う
2.pc2mスクリプトを使う
3.HACKする

3のHACKするを選択した場合、

a.携帯の場合、テーマとテンプレートをmobile用のテーマとテンプレートに変更する
b.HTML出力を半角カナ&SJISに変換する
c.HTML入力の文字コードをEUC-JPに変換する
d.テンプレートを使用していないモジュールをテンプレート化

等の修正が必要のようだ。

私はまず1のxmobileモジュールを導入し、使用しているモジュールのプラグインを作成しようと考えたが、私のサイトで使用しているComment Anywhereモジュールはフックというトリッキーな仕組みが組み込まれているため、プラグインを作るのが難しそうなので、泣く泣く断念した。

次に2のpc2mスクリプトを導入してみた。Firefox+User Agent SwitcherでXOOPSサイトにアクセスすると、

i)旧Vodafone端末からはパスワードフォームが表示されない(POSTに対応していない端末が存在するため、意図的に禁止されている。ただし、configを変更すれば表示可能であるが、セキュリティリスクを踏まえた上で設定を変更する必要がある)
ii)端末のキャッシュ容量を超えるデータは表示されず、途中で切れた表示となる
iii)Comment Anywhereモジュールが正常に動作しない(コメント投稿ができない)

という結果であった。個人的に利用する分には問題ないのだが、このまま一般ユーザに開放するのは、少々厳しいかもしれない。

携帯からアクセス可能なCMSを構築するにはGeeklog等の携帯に対応したCMSを利用するしか方法はないのだろうか。他に方法があれば、是非ご連絡ください。

PHPフレームワーク

元々Rubyを使っていたせいで、約1年ほど前にRuby on Railsにはまった。しかし、半年くらい前にWebサイトを作るためにPHPの勉強を始め、最近PHPフレームワークの勉強も始めた。Railsに近いこともあって、CakePHPSymfonyに興味をもっているのだが、どちらかするかを決めかねている。また、PHPの産みの親であるZend社のZend Frameworkも気になる。でも、Zend Frameworkはまだまだ完成度が低そうなので、バージョン1.0がリリースされてから勉強した方がいいのではないかと思う。
CakePHPもSymfonyもマニュアル等は充実しているのだが、どうしても手元に書籍が欲しいと思って調べていると、CakePHP Recipesは出版予定だったが最近キャンセルされました。がっかりです。
一方、Symfonyはと言えば、なんとびっくり下記の「The Definitive Guide to symfony」という洋書の内容が全てWebで公開されています。今これを読んでいます。

Amazon ECS4 ListSearch

メールアドレスの入力するだけで、携帯電話からAmazonのWishListを閲覧できるサイトを作成したのだが、Amazon ECS4のListSearchのレスポンスがエラーとなっているのを昨日発見。RESTレスポンスのタグは”True”なのに、なぜかタグに

code:AWS.InternalError
message:リクエストを処理することができません。再度リクエストを実行してください。

が出力される。やむを得ず、メールアドレスの代わりにWistList IDを入力するように変更した。
#WistList IDを調べるのが結構手間だから、本サイトを喜んで使ってくれる人はいるのだろうか?

ローカル環境の構築

WordPressのカスタマイズを試すために、自宅のAT互換機(Cent OS 4.4)にWordPressをインストールしたところ、

Fatal error: Call to undefined function: mb_language() in /var/www/html/blog/wp-config.php on line 2

というエラーが発生し、画面が真っ白に。原因をネットで調べていると、php-mbstringというパッケージがインストールされていないというなんとも初歩的なミスを。

# yum install php-mbstring

# /etc/rc.d/init.d/httpd restart

で、WordPressのインストール画面が無事表示されました。

Webページからテキストの抽出方法(PHP編)

mixiのとあるコミュニティでも発言したのですが、Webページからテキストだけを抜き出す方法です。

1:$content = mb_ereg_replace("\r|\n", "", $content);
2:$content = preg_replace("/(\015\012)|(\015)|(\012)/", "", $content);
3:$content = ereg_replace("/<!--.*\/\/--><!--.*\/\/-->/", "", $content);
4:$content = strip_tags($content);

1と2行目で改行コードを削除して、3でHTMLのコメントを削除して、最後にタグを削除します。もしCSSのスタイル文が含まれている場合には、 styleタグで囲まれたテキストも削除すればOKでしょう。

ブログエントリに関連するブログを表示

ブログのエントリを作成した時のキーワードを拾って、そのキーワードを含む他のブログの一覧を自身のブログのメインページに表示する方法を考えました。

1.自身のブログのRDFを受信・解析する

2.特定のXMLタグからキーワードを拾い(例えばkeywordやtags)、そのキーワードによりTechnorati APIで検索する

3.返答された結果を整形して、ブログにscriptとして埋め込む

試した結果がこれです。右カラムの関連ブログに表示されているのが、Technoratiから返された結果です。ここでは「たらこキューピー」がキーワードとして自動で拾っています。

Amazon ECS4

携帯で簡単に和書を検索できるサイトを作った際に、

携帯ブックサーチ

PEARのServices_Amazonを利用して、Amazon ECS4が返すXMLデータを連想配列に変換し、配列を抜き出すコードを書く際にサンプルリクエストのレスポンスがあると、コーディングが楽になるなぁと思ったので、リンクしておきます。

ItemSearchのサンプルレスポンス