OpenPNEのディレクトリ構造と役割
プログラムの流れを説明
- do系page系について
- index.phpでの初期化処理
- openpne_execute関数での処理
- openpne_forward アクション関連の処理
- 入力値のバリデーションについて
- do系page系などプログラムの処理
- page_xxx.php内での処理
- Smartyテンプレートの中身を説明
- do系(type=do)のアクションの処理フロー
OpenPNEのディレクトリ構造と役割
/bin
※※※※※※※以下ムービーの内容※※※※※※※
OpenPNEのディレクトリ構造に関して説明したいと思います。
上のbinから行きたいと思います。
ソースコードはtrac.openpne.jpのtrunk 開発版の最新のコードを見てやろうとおもいます。
でブラウザでここ来てもらうと、binディレクトリとかlibディレクトリとかpublic_htmlとかが並んでいます。
上からいってbinになります。
この、binディレクトリというのが、中で何をやっているかと言うと
中に入っているのは
config.inc.phpとかmail.phpとか、tool_ashiato…と書いてあります。
何のファイルが入っているかというと
通常PHPというのはWEBブラウザからアクセスされて
それをPHPが処理をして、ブラウザに返事をするという形ですが
そうではなくて、たとえばCRONであるとか
LINUXのシステムであるCRONから呼ばれたりとか
メールサーバから呼ばれたりとかといって
ブラウザ以外から呼ばれるプログラムがbinに入っています。
なのでbinという呼び方にしてあります。
まず上から説明すると
config.inc.phpは、これらのPHPがコンフィグを読まなければ行けないので、
大元のconfig.phpとの橋渡しをするために、ここから読みなさいよという書き方
config.phpをrequireしてください、といった作法が入っています。
次のmail.phpですね。
mail.phpが何かというと
これが、携帯の写メール投稿や、プロフィール画像の変更、コミュニティの書き込みへの返事など、そう言った物を扱ってます。
だから、postfixとかsendmailとかqmailとかメールサーバにメールが届いたら
このプログラムにmail.phpに届いたメールを渡すような処理をしています。
その渡されたメールをですね、この標準入力に渡せるので
このプログラムが読みこなす。
全部読んで、process_mailといって、メールのデータを処理にかけます。
こちらにm_process_mailといって、処理系の関数があって
この中で、FROMが誰なのかな?
これはSNSの登録者なのかな?
これはプロフィール画像なのかな?
日記投稿なのかな?
コミュニティの書き込みなのかな?って判断をして
最終的にメールの中身に入っている、メールの中の画像や本文などをOpenPNEの中の日記として書き込んだりしています。
というのがmail.phpの役割です。
postfixとかsendmailとかメールサーバから呼ばれるプログラムです。
この後ツール、とありますが
tool_send_birthday_mailなど
tool_dairy_newsなど
これらはすべてCRONから呼ばれます。
たとえばRSSキャッシュは5分に1回OpenPNEに登録されているindex.rdfとかindex.xmlとか外部のブログを取得するのに使っています。
birthday_mailとかdairy_mailは1日に1回起動して、誕生日7日前とか誕生日当日とかのメールを送ったり、dairy_newsといって、1日に1回ニュースを、あしあとの数とか最新日記の数とかを、送ったりとかする形で入っています。
こちらのCRONは.cronと言うファイルと.phpというファイルが必ず対になって入っているが、通常cronは簡単で、cronファイルはcronを呼ぶのに向いている用に作られているが、直接読んでもかまわない。
binディレクトリはこの辺です。
主にここの役割は、PHPブラウザから呼ばれるPHP以外で、メールサーバであったりCRONであったりから呼ばれるファイルが格納される場所になります。
/lib
※※※※※※※以下ムービーの内容※※※※※※※
続いて、libのディレクトリについての説明に入りたいと思います。
libはOpenPNEディレクトリの直下にあります。
この中のディレクトリに、includeとsmarty_pluginsとあります。
このlibっていうディレクトリが何のためにあるかと言うと、
主に、OpenPNEが利用する外部のライブラリ、
OpenPNEで作られたものではない外部のライブラリをここにまとめておくという形にしています。
一番大きいのがincludeの中なんですけれども。
これを開いてもらうと、いっぱい、
AuthとかCacheとかCalendarとかCrypt、Date、DB、Date、HTTP、kcaptcha・・・・・・と入っています。
ここがライブラリ群、OpenPNEの外にあるライブラリです。
ほとんどがPEARのライブラリを使っています。
なのでここに並んでいるファイル群はほとんどPEARなんですけれども、
中にはSmartyとか、PEARじゃないものも入っています。
とりあえず、このあたりから外部のライブラリを呼んでいます。
たとえば、OpenPNEがデータベースに接続するためには、
PearDBというライブラリを使っています。
OpenPNEがログインをするための認証系は、
Authというライブラリを使っています。
このAuth内のContainerのに含まれる接続形態だったら、
どんなものにも接続、スレーブできます。
スレーブPNE機能と、ここに書いてありますけれど、
OpenPNEだったら、ここに書かれているIMAPとかLDAPとか、
こうしたディレクトリ、こういった認証方法に対応してスレーブPNEをすることができます。
Sambaとか、RADIUSとかもです。
だから、libには、OpenPNEの使う外部のライブラリを同梱して入れてしまっているので、
レンタルサーバーの環境がPEARに対応しているかどうかはあまり考えなくていい。
インストールされているPEARは全く使わないで、
OpenPNEの中に入っているincludeのファイルをなるべく使ってください、という形で、
なるべく動きが違わないようにしています。
それで、もう一個ディレクトリをのぼって次のところに行くと、
smarty_pluginsっていうのがあります。
Smartyっていうのは結構よくできてるテンプレートエンジンなんですけれど、
そのSmartyをもうちょっと改造して、OpenPNEにとって使いやすくしています。
これもOpenPNEとは関係ないライブラリとして置いてあります。
libについてはこれくらいで。
このOpenPNE直下のlibというのが、
OpenPNEプロジェクトとは直接関係ないけれど、OpenPNEが利用しているライブラリです。
間違いやすいのが、webappの下にもlibがあるってことです。
webappの下にあるlibとは違いますので、ちょっと気をつけていただきたい。
webappの下にあるlibは、OpenPNEが作ったOpenPNEで利用するプラグインやライブラリになっています。
libは結構早いですね。こんなもんか。
/public_html
※※※※※※※以下ムービーの内容※※※※※※※
さて、いきましょうか。
trac.openpne.jpでBrowse Sourceを開いてください。
OpenPNE、trunk、と開いていって、このpublic_htmlの続きからやろうと思います。
一番上のディレクトリが、cmd。
cmdのディレクトリには、YouTubeとかkakaku.comとか、tabelogとかいった、
小窓のリストが入っています。
こちらを見るとまず一番上がblog-apart。
これはSo-netさん提供のものだと思います。
簡単にプログラムを見てもらえばわかると思うんですけれど、
このfunction mainというところで、
OpenPNEというか小窓では特徴的です。
これを使って、mainの部分では通常小窓を表現しており、
url2cmdの部分ではurl小窓という形で、
urlを張るだけで自動的に小窓に置き換えられるという形になっています。
OpenPNEでは、小窓というこのyoutubeを引っ張ったりしてくる機能は、
このcmdディレクトリにJavascriptファイルを一個置き、
また管理画面で許可をするだけで、使えるようになっています。
いっぱいありますね、blog-apartとか、blogcruiserとか、flipclip、grouper、youtubeと。
特徴的なのは、url2cmdで使うんですけれども、
ファイル名はurl2cmdで使いたいドメインに「.js」をつけるという規約があります。
なので、たとえば日本のyoutube「jp.youtube.com」に対応したい場合は、
「jp.youtube.com.js」というファイル名にする必要があります。
これが自動的に反応するようにできています。
それで、やはりこのurl2cmdのところも、
url2cmdというものと、main関数の二つでできています。
非常に少ないですね。全部で38行。
38行しかないんですけれど、url小窓とか、
埋め込み型のcmdとかFlashプレーヤーを引っ張ってくることができます。
という形で、結構手軽ににMashUpできるところがおもしろいんじゃないかなと思います。
他特徴的なのはなんでしょうね。
tabelogとかも非常に少ないですね。
これだけ。17行しかないです。
このurl2cmdのif文のところで、入力されたurlを解析して、
tabelogのレストランIDみたいなものを取得して、
それをmain関数に渡します。
main関数の部分ではiframeを作っています。
この部分でiframeを作って、最後こちらで、
Javascriptでdocument.writeをかけているというような仕組みになっています。
このような形で作られています。
このように、おもしろい機能ができるわりには、
わりと行数が少なくて単純で楽しいですよっていうのが、cmdの魅力なのかなと思います。
他にもいっぱいありますね。
ebitvとかgoogle、まぁ、GoogleMapに対応するために結構いろいろ入ってるかなという感じです。
このnetpriceとか、あと、ニコニコ動画なんていうのも実は入っています。
これも13行しかないですね。
cmdに関しては、作りたい人がいたら、こちらに「cmd houto」という検索をかけると、
pne-cmdというページで、youtube小窓を例にとって作り方が記載されています。
こちらのサンプルを見て作ってみたらいいんじゃないかと思います。
※※※※※※※以下ムービーの内容※※※※※※※
3番目の説明は、このpublic_htmlというディレクトリになります。
このpublic_htmlというのは、OpenPNEを呼び出すApache側、webサーバ側が
ここのpublic_htmlの下を基点にして、呼び出すという形になっています。
ですので、ここから下のディレクトリっていうのは、
インターネット上に公開される、ブラウザから直接アクセスされる、
要するにブラウザでこのurlを直打ちされたら呼び出されてしまうということを
気をつけた方がいいなと思います。
ですので、会員の人に見てもらおうと思ったエクセルファイルをここにポーンと置いても、
OpenPNEに入ってない人でも見えてしまうので、
会員データベースのエクセルとかを置かないように注意してください。
このディレクトリが、ブラウザからのrootになるという形です。
ちょっと具体的な例を示すと、例えば、
skin/birthday_f.gifっていうファイルがあるんですけれど、
ここのディレクトリは「www.openpne.jp」と打って、
「/skin/birthday_f.gif」と打つと、こう表示されるという形なので、
webブラウザから直接閲覧できるってことを注意してください。
つまりpublic_html以下っていうのはweb上に公開されます。
逆に言うと公開しないと使えないものたちが入っているということです。
上から説明していきます。
一番上がcmdディレクトリで、これは後で説明しますけれど、
YouTubeとかkakaku.comとか、
OpenPNEの外部から引っ張り込むコンテンツをMashUpするための仕組みで、
Javascriptが全部入っているというディレクトリです。
次がcss。
OpenPNEで、編集をしないで、ダイナミックに変えられるスタイルシートの部分もあるんですけれど、
基本的にOpenPNEで使うスタイルシートはこちらに入っています。
次がflashで、これはひとつしかないんですけれど、
OpenPNEでフレンドリストをFlashで表示するという機能がありまして、
このFlashを入れ替えると、コルクボードにポラロイド写真みたいな表示だったのを、
違うFlashに置き換えることもできます。
ただ現状は1個しかないです。
このFlashのソースコードも公開されています。
これを編集して上げ直すと、違うフレンドリストが作れるので、
ぜひトライしてもらいたいなぁと思っています。
次、flashの下がimgです。
ここはデフォルトでは使わないディレクトリです。
どういうときに使うかというと、
configの設定で、OpenPNEのパフォーマンスを上げるために、
画像の一時ファイルをvarディレクトリに入れるのではなくpublic_html側に公開することで、
ブラウザが直接アクセスできるようになります。
なんでその分、PHPが画像を読んで吐き出し、じゃなくて、
Apacheが直接画像を読めるので、早くなるという形で、
スピードを上げたいときにこのpublic_html/imgの中に画像を置くという形です。
ですからここはデフォルトでは使ってないと思います。
スピードを上げたいときには絶対使うような機能ですね。
それで、あとJavascriptをいろいろ使うので、prototype.jpとか。有名なやつですね。
必要なJavascriptが置いてあります。
あとはmodulesっていって、モジュールごとに画像やファイルを置いておきたいので、
そのために場所を用意してあります。
使ったり使わなかったりという感じですね。
最後がskin。
デフォルトのスキン画像がこちらに入っています。
管理画面で「初期値に戻す」という風にすると、こちらのスキン画像に戻るという形です。
ここを全部そっくり入れ替えると、
デフォルトのスキン画像が交換できるという仕掛けになっています。
その他のファイルについては、次のムービーで説明します。
※※※※※※※以下ムービーの内容※※※※※※※
public_htmlの後半です。
cap.phpというのがあります。
capというのはおそらくCaptchaのことだと思います。
OpenPNEで友人を招待するときに、
ぐちゃぐちゃぐちゃって波打った暗号みたいなのを打たされるんですが、
あれがCaptchaというんですね。
Captchaを生成するものがこちらにあります。
OpnePNEからは独立して動くので、ここに置いてあります。
それで、こちらにもやはりconfig.inc.phpという、
config.phpを探すためのファイルが置いてあります。
このdo_normal.phpとか、ktai_normal.php、ktai_page.php、normal.php、page.phpというファイルは、
後方互換性と言って、OpenPNEの昔のバージョンのために作られています。
今はindex.phpで全部処理するようにしているんですけれど、
昔はdo_normal.phpや、page.phpといって、それぞれ別々のPHPを読んでいたんです。
例えば、通常普通のページを表示するとき、
認証のかかっていないページを表示するときは、normal.php、
認証のかかっているページを表示するときはpage.php、
認証のかかっていないページで、さらに実行系、
日記を書いたりとかっていう実行系のアクションを呼ぶときはdoがつくdo_normal.phpで、
認証がかかっているページで実行系はdo_page.php
という風に分かれていたんですけれど、
2.4か2.6くらいでは、もうindex.phpにまとめてある。
ただそうすると、以前のバージョン使った日記に、
このページ見てよ、この日記見てよといった人がリンク切れになってしまうので、
それを防ぐために以前のPHPが入っているという形です。
これはそのうちなくなってしまうと思います。
それで、download.phpはファイルダウンロード用に使うんじゃないかと思うんですけれども、
OpnePNE2.8からファイルアップロード機能が入りまして、
そのために使われていると思います。
次がimg.php。
画像を呼ぶときだけ、例えばプロフィール画像とか日記の写真とかだけは、
index.phpではなくて特別なimg.phpというのを読んでいます。
これは残るでしょう。
では内部も見ていきましょうか。
この中で今見ておかなきゃいけないもの、一番大きいのはindex.phpですね。
これは、フロントコントローラモデルと言いまして、最近の主流です。
昔は、「フレンドを表示」だったら「show_friend.php」とか
自分のページだったら「index.php」とか、
それぞれの役割ごととかページごとにPHPファイルを分けるということをやってたのですが、
最近の主流はこのフロントコントローラモデルって言って、
全部index.phpに預けてしまう。
一回集めてしまって、そこの中でいろいろやろうという形で、
OpenPNEもこのフロントコントローラモデルというのを採用しています。
index.php開くと、1行しかなくて、
この「openpne_execute()」という、一個大きな関数が呼ばれて、それですべての振り分け、
これは実行系なのかな、これは表示系なのかな、これはなんなのかな、といった形で、
このopenpne_executeが行います。
openpne_executeっていうのはまた後で説明しようと思うんですけれど、
openpne_executeは、/OpenPNE/trunk/webapp/libのcontroller.php、この中にあって、
この下に、indexで呼ばれたら実行されるという形でつながっています。
大事なのはこのpublic_htmlの中のindex.phpが呼ばれて、こ
こからすべてのアクションに誘導されるということです。
public_htmlはこんな感じかなと。
/setup
※※※※※※※以下ムービーの内容※※※※※※※
次はsetupのディレクトリを説明します。
このsetupのディレクトリは通常の動作とはあまり関係がなくて、
OpenPNEを設置するときだけに使うものです。
内容としては、このsql、セットアップするために必要な
データベースのセットアップのsql文が入ってるところと、
あとはHTMLファイル、セットアップの仕方を示したHTMLファイルが入っています。
具体的な設置の仕方みたいなことに関しては、このHTMLの方を見てください。
セットアップのHTMLを見て、設置をしてほしい。
これもわかりにくいというか、素人さんには難しいところなんですけれども。
SetupとUpgrade用っていうのがあって、前のバージョン、
前の安定版の2.6から2.8、2.8から2.10という形での
メジャーバージョンアップ用のUpgradeのガイドも書いてあります。
で、このsqlのディレクトリの中に入りますと、
mysql40とmysql41っていう形で、二つのディレクトリがあります。
mysql40は、MySQL4.0用のセットアップ文が入っていて、
mysql41には4.1用のセットアップ文が入っています。
MySQLは4.0と4.1で結構大きな違いがありまして、
実はMySQL4.1と5.0の方が違いが少ないという。
0.1しか違わないのと0.9違うのに結構すごく。
特に日本語の処理のところで非常に違いがあるので、
OpenPNEでは二つに分けています。
4.0用のディレクトリを見てもらうと、
4.0用で初期のインストール用のディレクトリ、インストール用のSQL、
で、optionっていって、前のバージョンのPNEBizのスケジュールを
インポートしてきたりとかいうのがあるんですけれど、
新規で立ち上げる人にとってはあまりいらないものです。
とにかくinstallだけあればいいと。
で、次にupdateっていうディレクトリがあって、updateっていうのは、そうだな、
まずupdateとupgradeの違いっていうのを説明しないといけないんですけれど、
upgradeっていうのが2.6から2.8、2.8から2.10っていう形で、
大きく上がるものですね。
0.2のバージョンアップ、安定版から安定版へバージョンアップすることを、upgradeとって言います。
普通の利用者はupdateはほとんど使いません。
updateっていうのは、
OpenPNE2.9.1から2.9.2、2.9.2から2.9.3っていう形で、開発版のバージョンを上げるためのディレクトリです。
ですので、安定版を使っている人、使い続けている人にとっては、upgradeだけ見てればいい。
ただ、OpenPNEの最新機能を勉強したいとか、ちょっとずつ最新版を使っていきたい場合には、このupdateっていうディレクトリを見る必要があります。
ということで簡単に言うと、updateを全部やると、upgradeと同じになります。
つまり、upgradeのSQLはupdateの塊でしかありません。
これがupdateとupgradeの違いです。
MySQL4.0用のディレクトリにはinstall、option、update、upgradeってありますし、
MySQL4.1用にもまったく同じものがあります。
違いがあるとすると、installのところのこのcreate_tablesという、
テーブルのデータ構造を作るとき、このあたりで、
MySQL4.0、4.1で多少文法の違いがあるようです。
DEFAULT CHARSETを設定するあたりとかに、どうも違いがあるみたいです。
で、ここのCREATE TABLEのあたりで、データベースのテーブルを作ります。
40個とか50個とかテーブルを作っています。
ここではテーブルの構造しか作っていませんので、
次にinsert_dataというsqlがありまして、
作られた構造に、OpenPNEとしてのデータの初期値を入れます。
たとえばこのあたりだと、OpenPNEのポイントをあげるためのアクション、
つまりどのアクションをしたらOpenPNEのポイントをあげますよ、とか、
APIの設定とか、cmdの設定とか、
主にこうした初期設定値が入っています。
こちらだとコミュニティの初期カテゴリが、地域、グルメ、といった形で入っています。
/var
※※※※※※※以下ムービーの内容※※※※※※※
続いてはvarディレクトリの説明に入ります。
varディレクトリに何を置くかっていうと、
varはvariable?variable fileというのでしょうか、
一時的なファイル、一時的なデータを置いておく場所です。
OpenPNEでは、マスターのデータというか大元のデータはすべてデータベースに置こう、
実体のファイルではなくすべてデータベースに置こうという方針をとっています。
全部のデータをデータベースから読んでいると非常にスピードが遅くなる、ということがありますので、
データベースに一回読んだファイルをこちらのvarフォルダに置いておき、
データベースにあまり読みにいかなくてもいいようにするという形で、スピードを上げることができます。
その一時的なファイル置き場がここで、
だから、実はここのファイルは消しても大丈夫です。
消してしまっても、OpenPNEプログラムは、
本体のデータベースの方に読みに行って、またvarフォルダを作ってくれるので、
ここは定期的に消しても構わないし、バックアップをここは取らなくても大丈夫です。
OpenPNEではconfig.phpとデータベースの本体だけバックアップを取れば
復旧ができるという仕掛けになっています。
上から説明しますと、一番上がfunction_cacheというものを置く場所で、
function_cacheっていうのが関数の結果、functionをcacheするという仕組みです。
たとえばOpenPNEで関数の計算時間が長いものがあるんです。
たとえばランキングを集計するというのは非常に時間がかかります。
しかもランキングは一日に一回だけしか計算しない。
このランキングのデータって、アクセスするとぱっとすぐ出るんですけれど、
実は計算が非常に大変なんです。
その日のうちに誰がどれだけアクセスがあって、というようなのを全部記録しなきゃいけないので、
しかも一日に一回しかやらないでいいから、毎回計算する必要は全くない。
だから一日に一回あらかじめ計算しておいて、このfunction_cacheに置いておこう、
というような使い方として、このfunction_cacheを使っています。
その他にも計算の難しいこと、時間のかかりそうなことは一回計算した結果をここに置いておいて、
二回目はデータベースで計算をしないでそのまま
ファイルを読んで出すというような使い方をしています。
これがfunction_cacheです。
次がimg_cacheといって、OpenPNEに上げられた日記とか、プロフィール画像とか、
そういったものをキャッシュしていく場所です。
このディレクトリを見ると、まずは拡張子別、gif、jpg、pngっていう形で分かれていて、
その下を見ると、今度は高さ・幅、サイズ別に分かれています。
プロフィール写真では180を使うとか、フレンドリストでは76を使うとか、
サイズごとにキャッシュを作って置いておく。
で、生データはh_rawに置くという形で、サイズごとに分けている。
なんでサイズごとに分けているかと言うと、
全部を一箇所に置いてしまうとものすごいファイル数になってしまって、性能が劣化するので、
サイズごとに分けています。
img_cacheというのは、
gifとかjpgとかpngとかをリサイズした結果を、置いておくことになっています。
次がlog。
これはエラーログとかメールの実行ログとかを記録するところです。
次がrss_cache。
これが、日記、外部ブログを取り込んだ結果を置いておきます。
ここを5分に1回とかCRONをかけてキャッシュを置いていくということになります。
で、あとtemplates_cというのがありまして。
これはSmartyで使われるんですけれど、Smartyのテンプレートを一回計算をして、
計算の結果をこちらに一時ファイルとして置いておくという形で使われます。
毎回毎回構文解析とかしているとめんどくさいので、
Smartyがここを使って、構文解析の結果をここに置くという形になっています。
最後がtmpディレクトリといって、ここには画像とか、ファイルアップロードの一時ファイルとか、
日記を投稿して確認画面をやってる途中に、写真を保存しておく場所として、tmpという形で置かれます。
ここに一時画像とか一時ファイルとかが置かれるという場所です。
こんな感じで、varフォルダの説明はいいかな。
※※※※※※※以下ムービーの内容※※※※※※※
ファイルの説明だけじゃなくて、
実際どう使われているかっていうのを説明しようと思います。
OpenPNE.jpを例にして説明しようと思います。
こちらがOpenPNE.jpにログインしたshellの画面になります。
TeraTermを使っています。
で、今、こちら先ほど画像を消してしまったので、
ここのpublic_html/img/gifで、w76h76の画像が置かれるvarフォルダなんですけれども、
ここを見ると何もないんですね。
今キャッシュファイルがないという形、たった今消したんですけれど。
キャッシュファイル作る場合には更新をして、画像を要求してみる。
そうすると、今、画像を見に行って、
このあたり、これとか、これとか、多分gifファイルが使われているんで、
表示ができたってことはキャッシュが作られただろうと。
で、表示をしてみると、案の定ファイルがいっぱい作られているという形です。
二回目以降は、
いちいちデータベースからファイルを読み込んできてリサイズして表示、ということをしないで、
このvarフォルダの中から読んでくれるので、
非常に早く、レンダリング、データを返すことができます。
このvarフォルダっていうのは別にいらないので、
消してしまうこともできます。
それで、こうやって、きれいさっぱり消してしまっても、OpenPNEとしては表示ができると。
その代わり表示がちょっと遅くなりますね。
最初は、今までデータベースに読みに行かないでvarフォルダから読めてたものが、
データベースに一回読みに行って画像を作り直して、表示するという形になるので、
で、また表示すると入っている、という形で。
その他にもvarフォルダっていっぱい入っているんで、
他のも見ていこうかな。
例えばこちらのvarの中だと、function_cache。
ここにcacheがごろごろ転がっている。
ここによくわからないデータがずらーっとあって、
実はこのデータが結構バカにならないんですね。
1.7Mbyte溜まってしまっていると。
かなり、chache 0のcache_00ってファイルの中でも、1.7M溜まっていて、
例えばfunction_cache全体で考えると、
多分、ギガまでいかないけど数百Mbyte単位であるんじゃないかな、と思います。
logディレクトリの中身っていうのは、PHPのエラーが記入されている。
WarningとかNoticeとかいう形で、主に多分、CRONが取れませんでしたっていうエラーが結構出やすいです。
あとrss_cache。
ここもrssの一時データが置かれています。
rssの取ってきたデータが置かれている。
ここも消してしまって全然構わないです。
最後にtemplates_c。
ここには、Smartyのテンプレートファイルの一時データが置かれている。
これも消しちゃって構わないんで、消しちゃう。
消しちゃっても、ここも、OpenPNEが読み込まれると自動的に、
最初の一回目はちょっと遅くなるんですけれども、テンプレートの再生成をして、
こういう形で、テンプレートができあがります。
/webapp
※※※※※※※以下ムービーの内容※※※※※※※
続いて、大物なんですけど、
webappのディレクトリへいこうと思います。
webappっていうのがOpenPNEの根幹になる部分で、
その中でも、libから行きましょう。
webappのlibっていうのは、いっこ上のOpenPNE直下のlibとは別で、
OpenPNEで使われるライブラリが置かれています。
OpenPNEで作った、という方が正しいのかな。
OpenPNEがOpenPNEのために作ったライブラリが置かれています。
その下のmodulesでは、
pcモジュールとかadminモジュール、ktaiモジュールとかいったように、
役割ごとにファイル、モジュールを分けています。
templatesというのにはOpenPNE全体にとって使われるテンプレートが置かれていて、
メールのテンプレートとか、ここは少ないんですけれど、
OpenPNE全体が使うテンプレートを置いています。
validateというのは、妥当性検証といって、
入力値に問題がないかとか、これはメールアドレスかとか、
これは文字数何文字までに当てはまっているかとかいったことを設定するための書式になります。
それに、init.inc、version.php。
init.incは初期設定の値。
このモジュールを使うためとか、このプログラムを動かすための、
初期設定を置いています。
version.phpっていうのは単に、PHPのバージョンを示すための宣言をしているファイルです。
このムービーでは、この中でもlibだけを説明しようと思います。
OpenPNEの、webappの中のlibっていうのは、こちらで分かれています。
db、mail、OpenPNE、smarty_blugins、util……という形です。
dbというのには、OpenPNEの定義された
50ぐらいあるデータベースを読み書きするために使うライブラリ群が入っています。
mailっていうのにはメールを操作するためのライブラリ群が入っています。
OpenPNEっていうのは、OpenPNE本体の中でいろいろ作られている。
携帯のメールを処理したり、データベース処理したり、画像を処理したり、
あとValidatorといって入力の妥当性検証したり。
携帯のUAをチェックしたり、RSSを操作したり、Smartyいじったり、Validationとか……。
結構、OpenPNEがいろいろやらなきゃいけないことを、ライブラリとして置いていると。
で、一番簡単なところ、というか大きいところは、dbっていうディレクトリで、
主にデータベースのテーブルの数だけファイルがあると思ってほしいです。
いや、ちょっと違うか。
action.phpっていうのはactionを操作するためのdbライブラリで、
つまりactionというテーブルを操作するためのファイルです。
これは一個しか関数がない。
で、apiを操作するための関数群ですとか、
あしあとデータベースを操作するための関数群ですとか。
たとえばこれだと、c_member_idからその対象メンバーのあしあとのリストを取得する、
決められた数だけ取得する関数で、ここで呼ぶとあしあとのデータリストまで飛んでく。
で、あしあとを書いたり、読んだり、あしあとのデータベースを読んだり書いたりするものが含まれています。
同じような形で、ここに書いてあるのが主に、特定のテーブル、
バナーテーブルとかブックマークテーブルとか、コミュニティのテーブルとか、
そういったところを操作するための関数文が含まれているということです。
それでもし「このデータベースを操作したい」「このテーブルを操作したい」と思ったら、
そのテーブルに該当する名前のPHPを探したりgrepしたりして、
関数を見つけるといいんじゃないかと思います。
それで、その下がmail。
さっき説明した、binの中のmail.phpでやってるんですけれども、その実体はこの中にあって、
メール投稿であるとか、コミュニティ書き込みであるとかの処理の実体はこちらで引き受けています。
メール投稿関連で新機能を追加したいとかいった場合には、
こちらを見てもらえればいいかなと思います。
※※※※※※※以下ムービーの内容※※※※※※※
次は、webappの、modulesの中身を説明します。
modulesのディレクトリの中は、
admin、api、ktai、pc、setupと、役割ごとに分けています。
これは、必ず厳密に分けなきゃプログラムが動かないというよりは、
開発しやすいように機能概念単位で分けていこうということで、
もう少し細かく割ってもいいのかなと思うんですけれど、
今のところこの5項目に分かれています。
ディレクトリの説明をすると、
adminは、管理画面の、ページと実行系の機能文。
管理画面の機能はこのディレクトリの中に全部含まれています。
apiというディレクトリには、OpenPNEapiといって、
外部との連携をするときのプログラムが入っています。
携帯電話関連の機能は、ktaiというディレクトリに、
pc関連の機能はpcというディレクトリに、
最後、setupには、OpenPNEをセットアップするためのものが入っています。
上から見ていくと、adminなんですけれども。
見て欲しいのが、ここではadminディレクトリ、
というか、modules内のディレクトリを開いてもらうと、
また下に、do、lib、page、templates、validate、auth.inc、init.incとある。
この分け方で、どんな使われ方をしているのかを説明していこうと思います。
doというのは、実行系の関数群、実行系の機能が含まれているディレクトリです。
libというのは、このmodulesだけで使う。
OpenPNEでかつこのmodulesだけしか使わない特別なlibを置く場所として作られています。
これは使わないこともあります。
pageというのは、表示するpage系、ページを表示するために必要なPHPが入っている。
templatesは、その表示をするときに、
デザイン、こういう見た目で表示をしたいというテンプレートが含まれています。
で、validateっていうのは、
各実行系、表示系で、「この文字におさまってなければいけない」とかっていうValidation、
妥当性検証というんですかね、入力値のチェックのために使われます。
auth.incは認証をするために使って、
init.incは初期設定をする。
では、doから見ていきましょうか。
doを開くと、csv_member.phpとか、
delete_c_admin_user.php、
delete_c_banner.php、
delete_c_cmd.php、
delete_c_commu_category.php、という形で、
上はdeleteが多いんですけれども、
実行する、なにかデータベースに影響を及ぼすような機能を入れています。
doっていうのは実行するため、です。
削除を実行せよ、とか。
あと下の方だと、
insertとかがありますね。
メンバーを登録しなさいっていうような、insertの命令が入っていたりとか、
招待メールを送信したりとか、
メッセージを送ったりとか、
なにかupdate、
つまりデータベースを修正したりという形で、
何かしらデータベースに、
追加とか削除とか、変更とかっていう変化を起こすためのページ群が
doということになります。
大体のところではこのフォームに当てはめられています。
削除ボタンとかフォーム入力のsubmitボタンとかに
対応していることが多いです。
doにはこういった、実行系の関数が置かれます。
次にlibなんですけれど、
これは、ここならadminでしか使わないlib、
ここだと非常に少ないです。
adminだけしか使わないデータベースの接続ライブラリが置いてあったりしている。
次が、page。
これが、ページ群ですね。
管理画面の、特定のページを表示するために使われています。
例えば、diary_listとか、edit_c_admin_configとかっていうのは、
それが直接そのままページ名に割り当てられていますんで、
例えば管理画面のあるページを見るとして、
URL内のpage_edit_skin_imageというような形が、
このpageディレクトリ内のedit_skin_image.phpと対応しています。
webapp_biz
webapp_ext
※ムービーは作成中です。
プログラムの流れを説明
do系 page系について
※図示して説明する
index.phpでの初期化処理
public_html/index.phpからどのように遷移をしているか?
ブラウザからはindex.phpが呼ばれる。
その後config.inc.php=>config.phpを呼び出し、設定を行う
init.incを呼び出し、OpenPNEアプリの初期設定を行う
携帯ドメインの決定や、各種ライブラリの呼び出しなどを行う。
初期処理の後
controller.phpのopenpne_execute();を呼び出される。
index.phpでは処理を全く行わない。
実体はcontroller.phpのopenpne_execute()内で行う。
※※※※※※※以下ムービーの内容※※※※※※※
では始めます。
public_htmlの中で、プログラムがどういう動きをしているかという説明に入ります。
ブラウザからアクセス、リクエストが来たら、まず、index.phpが呼ばれる。
その後にこの、config.inc.phpをrequireして、
init.incをrequireしてから、
最後にopenpne_executeが呼ばれる。
index.phpはたったこの3行だけの作業をしています。
では、config.inc.phpで何をしているか。
require_onceについて、
requireとは、ライブラリをロードする、呼んでくるという意味なんですが、
require_onceというのは、一回だけしかロードしないでくれ、
何回でも呼べるけど、いろんな箇所で呼んでも、一回しかrequireしないよ、という命令です。
このconfig.inc.phpがどこにあるかと言うと、
index.phpと同列にあります。
ここで何を呼んでいるかと言うと、
ここでも、二個しか呼んでいない。
これで最終的に、config.php、
OpenPNEをセットアップするときに、
データベースのパスワードであるとか、
そういったものを設定するためのconfig.phpをrequireして、
その設定値を読み込むということになっています。
config.phpは、設定ファイルというイメージですね。
それで、index.phpから、config.phpが呼ばれて、
次にinit.incというのが呼ばれます。
init.incがどこにあるかというと、
WEBAPP_DIRの下、となっていますので、
OpenPNE/trunk/webapp/init.incが呼ばれます。
ここではかなり初期処理をいっぱいやっておりまして、
OpenPNEのバージョン番号を取得したり、
includeする場所、ライブラリの場所を特定したり、
定数を定義したり、
携帯メールのドメインはこれである、ということを決定したり、
あとはSmarty関連。
こういう初期化作業をいっぱいやっています。
要するに、本来だったらconfig.phpに書いてもいいんですけれど、config.phpに書きすぎると、
設定値なのか初期値、初期セットアップなのかわからなくなるので、
config.phpには最小限の設定を書くようにし、
それの初期処理はinit.incでやろうという形で、
各種ライブラリを呼んでいったりとか、
セッションの設定をしたりします。
init.incがロードされたことでどうなるかと言うと、
このPHPプログラムが、すべてのOpenPNEのツールの場所がわかるんです。
このライブラリはここにあるとか、Smartyはここだとか。
そういう初期設定が終わっているので、
OpenPNEのプログラムが、全関数を呼べるようになる。
この二つが成されることによって、
index.phpから、openpne_executeという関数を見つけることができるようになります。
要するに、この二つの処理、
config.phpの呼び出しとinit.incの呼び出しをやっておかないと、
openpne_executeってどこにあるんだよ、ということになってしまう。
この二つをやることで、初期値を読み込んで、初期設定も終わった、という形で、
OpenPNEの全関数がどこにあるか、プログラムがわかるようになり、
このopenpne_executeを呼び出せるようになる。
では次、openpne_executeを見てみましょう。
これがどこにあるかというと、
OpenPNE/trunk/webapp/libの下の、
controller.phpというところにあります。
「初期実行 index.php から呼ばれる」という形で、
index.phpというのは3行しかなかった、ほとんど空っぽでした。
最初の、ブラウザからアクセスされた時の処理というのは、
全部このopenpne_executeの中で行っています。
こういう形で、モジュール名を特定する。
「m=○○」とかいうのがありましたね、
あれをこう、設定するという。
で、ここでちょっとやっているのが、
携帯からアクセスされた場合、UserAgentが携帯だった場合はもう、
強制的に’ktai’にしてしまえ、というような処理が入っていたりします。
openpne_execute関数での処理
openpne_executeの説明
openpne_forwardの説明
モジュール名の特定や、メンテナンスモード時の内部動作について説明する。
モジュール/init.incファイルの設定もある。
typeの特定までを説明する。
※※※※※※※以下ムービーの内容※※※※※※※
続いてまた、openpne_executeの説明です。
ここまで、openpne_executeが呼ばれたら何をするかというと、モジュール名を特定する。
requestのm=pcとか、m=ktaiとかいったモジュール名を特定します。
adminがいない、すなわち、初期設定が完了していなければ、
強制的に’setup’のモジュールにして、初期設定、インストールのモードにもっていってしまいます。
もしくは、携帯からアクセスした場合には、
強制的に’ktai’のモジュールを呼び出します。
こういう形で、決まりごとは決めていってしまう。
それ以外だったら、’pc’のモジュールだよね、という形で、
モジュールの名前を修正するような仕組みになっています。
次にアクション名の取得ですね。
「action=page_○○」とか、「action=do_○○」とかいうのがあると思うんですが、
それを’a’の変数に一回取って、typeとかactionとかを特定していきます。
これによって「m=pc&a=page_」の「a=」の方をきっちり取得するという。
ここまでで、モジュール名をピックアップしたら、
次にopenpne_forwardっていう、モジュールの処理の部分にプログラムのプロセスが移動します。
このopenpne_forwardで、実際のモジュールの処理をやっていくのだけれど、
openpne_forwardっていう関数には、モジュール名が渡される。
で、typeが決まっていって、actionがセットされる。
仮に’pcc’とか変なモジュール名が渡されていたら、
‘モジュールが見つかりません’という形で、
エラーを表示しなさい、という指令を出して終わりにしてしまいます。
そうでなければ、「今モジュールはこれを呼んでいますよ」というグローバル変数に変数を代入して、
今このプログラムではこのモジュールを使おうとしていますよという宣言をします。
で、config.phpの設定値で、使っちゃいけないモジュール、たとえば
「今は時間メンテナンス中だからPCの画面にアクセスされたくない」
とかいうこともできます。
「セットアップはもう使わなくていいからアクセスしないようにしよう」
というように、モジュールを設定で無効にするもできる。
ここに引っかかったら、モジュールが無効で、エラーに飛ばされるということになります。
あとはメンテナンス中の設定になっていたら、やっぱりエラーになるわけです。
「メンテナンスだから表示できません」と。
次に、init、またinit.incが出てくるんだけれど、これは何かというと、
先ほど最初に紹介したinit.incっていうのは、OpenPNEのプログラム全体で利用するinitです。
今回は、特定のモジュールのセットアップをするときに、
初期設定がまた必要だったら、
モジュールのinitも呼べるようにしてある、という形で、
モジュールディレクトリのinit.incをロードせよ、という設定になっています。
つまり、webapp/modules/pc/init.inc、ここをロードできるようにしてある。
ここにはPCモジュールで使う初期設定値を入れてあります。
要するに、OpenPNE全体の初期設定をする場合には最初のinit.inc、
モジュールごとのセットアップをしなきゃいけない場合は、こちらのinit.incを使う
という形です。
で、このように、openpne_executeからきて、
forwardにきまして、
いろいろ読み込んでいると。
モジュールが無効だのなんだのと。
init.incをロードしました。
で、typeを特定する。
requestのtypeがpageかdoか、要するに、
ページを表示するものなのか、何かを実行するdo系なのか、という形で、
それも予期していないものだとしたら、
‘リクエストの種類が正しくありません’という風になる。
これで、全部通過して、OKだったら、
ようやく、どういうアクションのタイプか、
ページを表示しようとしているのかそれとも実行しようとしているのか、
というところまでを特定してあげる。
それで、最後に、
ここから先がaction。
これは、次にしましょうか。
openpne_forward アクション関連の処理
・openpne_forward内のaction関係の処理を説明
・無効値や設定値をフィルターする
・認証関連の処理isSecure()関数についての説明
・OpenPNE_ActionにはあらかじめisSecure(){return true;}でセットされている。
・デフォルトでセキュアページが作成される
・ログインが不要なページを作りたい場合(o_系ページ)はisSecure(){return false;}
関数を定義すれば、認証を必要としないページを作ることが出来る。
※※※※※※※以下ムービーの内容※※※※※※※
続いて、actionから行きたいと思います。
先ほどの、typeとかmoduleと同じように、
まず、初期調査ですね、
値が正しいのかどうかからいきます。
_check_actionでactionの変数を調べて、
本当にactionがOpenPNEの中で定義されているかどうかを調べる。
エラーだったら、
アクションの書式とかが間違っていた場合は
‘アクションの指定が正しくありません’とか、
アクションファイルが入っていない場合は
‘アクションファイルが見つかりません’と。
これは要するに
“{$module}/{$type}/{$action}.php”というのが見つからない場合に、エラーが出てしまうと。
これがどこにあるかちょっと紹介しますと、
$module = pc、$type = page、だと、
modules/pc/pageの中の、
c_event_editとか。
これが、アクション名になるというわけです。
これがなかったら、エラーが出るということ。
$module = pc、$type = page、$action = c_event_edit、というのがなかったら、
見つかりませんよ、という形でエラーが出るという感じです。
それでまぁ、
classを見つけたり、とか、
この辺もまだ初期処理ですね。
で、
ここまでの検疫を通って、検閲されて、
全部大丈夫だということになったら、ようやく、
アクション名にアクションがセットされる。
これによって、モジュール名、タイプ、アクションというのが、
全部設定される。
それで、次にここ、
authと書いてあるのですけれど、
次には’is_secure’というのがきます。
is_secureというのがなにかというと、
そのページをsecureにする必要があるかどうか、
つまり、ログインした人にしか見せないページにするか、
それともログインしてなくても見せるページにするかっていうことがあります。
今回、この時点でもう、アクションページに、
例えば、c_event_editのアクションクラスというのを作っているので、
ここの中では必ず、
is_secureの関数っていうのを含めなければならない、という決まりがあります。
だからここで、アクションクラスをinstans化して・・・・・・
ここで、instansを$action_objという形で作ってるんですね。
それで、この$action_objに必ずisSecure関数、というのがありますので、
このisSecure()を呼んで、
「あなたのページって、ログイン必要なの?必要じゃないの?」というのを聞いて、
もしもログインが必要だったら、
今度はauth.incっていう、認証系のincludeファイルをrequireする、という。
これをrequireすることで、ログインした人しか入れないページを作り出すことができる。
だけど、もしisSecureがfalseだったら、このif文を通過しないので、
認証のチェックをしないでページをレンダリングします。
この辺が、かなりトリッキーで難しいところなんだけれど、
例えば、認証のないページを一枚出してみましょう。
例えばo系、o_public_inviteとかやるとですね、
ここに、
function isSecure()
{
return false;
}
と書いてある。こういう関数が定義されている。
このようにisSecureがfalseになりますよ、と返すと、
先ほどのif文で、この部分がfalseになる。
すると、「secureじゃないよ」という返事が返ってくるということになる。
それで、ログインの必要ないページではfalseが返るんだけれど、
ログインが必要なページ、例えばh_homeとか。
h_homeというのは、実は何も書いていない。
isSecureという関数がないんですよ。
これはおかしい、どうしてか、と言うと、
これはextendsされている。
OpenPNE_actionというライブラリをextendsしていて、
実はそちら側にもう、isSecureはtrueというように初期値でセットされているので、
何も設定しなければ、secureなページになってしまう。
わざわざ、「これはsecureなページじゃないよ」と指定したときに初めて、
ログインが必要じゃないページになるという感じになります。
この辺、結構ハマりやすいかな、と思います。
入力値のバリデーションについて
バリデーションについて
modules/pc/validate/page/h_schedule_edit.ini
ファイルにバリデーションの設定ファイルが記述されている。
設定ファイルでは
・変数の型
・初期値
・必須入力とするか?
等の設定を行うことが出来る。
type=pageのアクションを処理する。
Smartyの初期化を行う。
※※※※※※※以下ムービーの内容※※※※※※※
次はですね。
このisSecure、認証系は通りました、
これはログインが必要なページもしくは必要のないページ、
というところまで特定できたら、次にくるのがバリデーションといって、
リクエストされたページとか、変数が渡された時に、
それが適正な値に入っているかどうかという、
入力値をチェックするところに来ます。
いろいろと初期化作業をして、
common_validateというところが、結構ポイントになるんですけれども、
その前にopenpne_ext_searchとか、
{$module}/validate/{$type}/{$action}.iniを参照してくる。
これを見つけてみましょうか。
webapp/modules/pc/validate/page、と行って、その下にiniファイルがあります。
要するに、このiniファイルが、validaterの設定ファイルということになります。
一番中身の多いのが、h_schedule_edit_confirm.ini。
中を開いてみて、どんなvalidateになっているかというと、
ここにいっぱい、設定値が書いてあります。
schedule_idがintegerじゃなければダメだとか、
要求されているこれがなきゃダメだとか、
最小値は1であるとか。
titleはstringじゃなきゃいけなくて、
初期値は空白にする。
bodyもstringでなければいけない。
例えばこのtitle、stringは、requiredではないので、
もし入力がなければ空欄で初期設定してあげますよという形で、
ページに渡される引数とかが、ちゃんと正しい値におさまっているかどうかを、
こういった別のファイルで管理をしています。
これをプログラムで書いていくと大変なので、こういう書式になっていて、
この書式をいじることで、このページの、渡される変数値のチェックをしている。
結構、変数値のチェックというのは難しくて、
変な値を入れられると、
プログラムが壊れてしまったりとか、
不正をされてしまったりとかいうことがあるので、
このバリデーションというのは結構、きっちりやる必要がある。
人間がプログラムで書くと間違えやすいので、
こういう設定値で管理をするということよくをやっています。
controller.phpのファイルに戻って、
ここで、バリデーションの処理をしている。
$validator->common_validate($files)というのを行う。
common_validateにかけて通過するか、
通過しなかったらバリデーションのエラー
「バリデーション失敗しましたよ」みたいなのを返すことになります。
これでまた関所を突破、
バリデーション、入力値チェックという関所をまた通過しました、
という形で、ようやく次は、type判定になる。
page系の処理だったらこう、do系の処理だったらこう、というかたちで、
ここのswitchではまず、page系の処理、要するに
ページをレンダリングしてくれ、という指示であることを判別したら、
ようやく、ここでテンプレートエンジンのSmartyが出てきます。
ここで初めてSmartyを初期化してやっていくと。
$smarty->assign(‘requests’, $requests);、
先ほどのm=pcとか、変数名、page=○○とかを、ここでassignしています。
で、後はOpenPNE側で渡さなきゃいけないメッセージとかのassign等を表しています。
このmsg、msg1、msg2、msg3というのは、OpenPNEがあらかじめ、
「メッセージを送るのはこういう」やり方にしましょう、という形で、
決められたメッセージの渡し方です。
それで、もしここまでに来るまでで、エラーメッセージ等が設定されていれば、
エラーメッセージもassignしてあげるという形です。
「○○は設定されていません」とかいうようなのを、
設定してあげる仕組みもあります。
で、SSLの処理だったらどうだろうとかがあって、
これは、HTTPSとかたまに変えたりしなくちゃいけないケースもあるのかな。
あと別のページに飛ばしてあげたりとかという処理が、
入ったりしています。
それで、view =& $smarty、
smartyまで来ましたので、この辺りでいったん止めましょう。
do系page系などプログラムの処理
do系page系の説明。
OpenPNEでは個別ページの表示にpage_で始まるアクション(type=page)のアクションを利用する。
ログイン、ログアウト、日記を書くなどは、do_で始まるアクション(type=do)を利用する。
※※※※※※※以下ムービーの内容※※※※※※※
ちょっとここで、
page系とdo系の違いがよくわからないという要望があったので、
page系とdo系の説明をさせていただこうと思います。
僕がよく、page系とdo系、と言うのは、
こちら、OpenPNEのページを表示するときに、
URLに例えばpage_h_homeとかって書いてあるもの、
これがpage系。
ページを表示するために使うアクションタイプを、page系と言っています。
それに対してdo系というものはなにか。
実はdo系というのはほとんど見えません。
do系が見えるケースというのはどこかというと、フォームです。
例えば「友達を誘う」というフォームがある。
ここの「確認画面」というボタンに、doが仕込まれています。
ですから、ソースを開かないと、基本的にdo系は見つかりません。
ここが少しわかりづらいところかと思います。
普通、pageだったらpage_h_inviteという風になるんですけれど、
do系というのは必ずフォームの中に、例えばここに、
do_h_invite_delete_memberというのがあります。
この、先頭にdoと付いているのがdo系関数で、
page系というのはページを表示するために使うものなんですが、
do系というのは、
何かアクションを起こす、例えば日記を書くとか、
友達を招待するとか、ログアウトする、ログインする、とかっていう、
POST FORMを処理するためのものです。
tplに、formタグを作るためにかかれている。
だから、ページからページを表示するためには、単純なpage系のリンクを張ればいい。
ですが、ログアウトするとなると、
このログアウトボタンには、リンクにdo_inc_page_header_logoutとあり、
doでログアウト、つまりそういったアクションをする場合にはdoを使うということです。
ログインボタンもdo。
大体、doが使われるのはフォームが多いですね。
リンクでも、ログアウトのような「処理を実行」する場合にはdoを使います。
OpenPNEでは、アクションを、
ページを表示するものと、
何か実行しようとするものとで、
完全に分けている。
ページはpage、実行系はdoという形にして、
わかりやすく分けています。
これは、フレームワークのやり方によって変わってくる。
例えば、アクションクラスを重要視する場合は、classの塊の中で、
レンダリングの処理があったり、
実行系の処理があったりで使い分けたりするんですけれど、
OpenPNEでは、そこまで高度なやり方はしないで、
「このフォームのページを表示する」ためのpageアクション、
「フレンドを招待する」ためのpageアクション、
「TOPページを表示する」ためのpageアクション、
で、doはフォームの数だけ作るという形に分けています。
これはまぁ、良し悪しですね。
トレンドとしては僕らのやり方ではなくて、
アクションクラスを一つ作って、
そこにページのレンダリングとか、複数の実行系を置いたりするんですけれど、
僕らは、1アクション、
1ページ1ファイル、1実行1ファイル、
という形で、シンプルにしています。
page_xxx.php内での処理
モジュールごとのinit.incを説明
Actionクラスのexecute()では、return ‘success’;をするだけ。
実際には、個別に作成する。h_home.php等の中で、Smartyにアサインする変数群を作成する。
execute()の中では
ログインしているSNSメンバーの特定($u)
フレンドリストの取得、インフォメーション欄文言の取得
最後にsuccessをreturnする。
openpne_forwardではsuccessが返ってくれば、Smarty->ext_displayを使って、対応するテンプレートファイルをレンダリングする。
※※※※※※※以下ムービーの内容※※※※※※※
ここまで来たら、
ようやくこれでSmartyがセットされます。
ページの処理で変数をいろいろassignして、
最後にSmartyをオブジェクトにセットしたという流れになります。
次に、init functionというのを呼びます。
これはモジュールごとのinit.incの中に入っていまして、
modules/pc/init.incの中に、init_pc_pageというfunctionがセットされている。
要するに、PCモジュールで、ページをレンダリングするときに、
先に処理しておかなければならない関数群というのを決めています。
例えばあらかじめ、PCのモジュールでは、Smartyにセットしておかなければいけない変数群がある。
例えば、フレンドの「MY_FRIEND」っていう名前とか。
そういったものをセットします。
あと$is_secureだったらsession_idを生成しなきゃとか。
モジュールごとに初期設定をしなきゃいけない、
モジュールで、このアクションタイプだったら、
Smartyを呼ぶ前にこのセットアップをしておかないと動かない、
といったものを、一括してまとめています。
そういうものを通過しまして、$init_funcを呼んだと。
ようやくここで、action_objのexecuteっていう関数に来ます。
これがどこかっていうと、
webapp/lib/OpenPNEに、Action.phpっていう関数群があるんですが、
この下の方に、function execute()っていうのがあって、
{
return ‘success’;
}
となっているんですけれど、
このままだと、なにもしないでOKと返すだけ。
だからデフォルトでは、return ‘success’と返すだけなんですけれど、
これは、抽象クラスといって、クラスの定義だけなので、
実際の中身はwebapp/modules/pc/pageの中の、例えばh_home。
これがアクションクラスのサブクラス、子クラス。
pc_page_h_homeっていうのが子クラスで、
ここの下にexecuteの中身、あんこが入ります。
それで、ここで何をやるかっていうと、
Smartyテンプレートに渡してあげる前に、
いろいろリストを作ったりしなきゃならない。
要するにフレンドリストは9個、
この人たちのアドレスはなになに、という、
実際の変数を呼んでくる処理っていうのをこのexecuteの中に記述します。
ここは腰を据えてやらないと、難しいっちゃ難しいんですけれど、
ざっと言うと、まず、自分がログインしたIDが何であるか、
ページを見に来た人のIDを$uというところに仕込む。
それで、ナビを取ってきたり、
ナビバーの値を変数でセットしたりとか、
おしらせ欄を取ってきたりとか、
いろいろざーっと、とにかく、なにをやっているかというと、
ここで、h_homeってページをレンダリングするために必要な値を、
どんどん引っこ抜いてきているという。
フレンドはどこだ、最新日記はどこだ、とか。
メッセージはあるのかないのか。
ポイントを取得しましょうか、
紹介文ってきてもらいましょうか、
曜日とろうか、カレンダーとろうか、
お気に入り持ってこようかとかっていうのをざーっとやって、
最後にreturn_successと。
要するに、これで、全部変数にセットして、
「大丈夫だったよ」という風に返してあげる。
そうすると今度、こちらに戻ってくるんですね。
$result = $action_obj->execute($requests);と。
そこに’success’が返ってくるわけですね。
で、’success’だったら、このif文、レンダリングをしましょうとなる。
で、$smartyのdisplayでtplを呼び出す。
次はこの、実際の、{$action}.tplの中身を説明しようかなと思います。
Smartyテンプレートの中身を説明
アクション名・php・テンプレートのファイル名には関連がある。
アクション名が
a=page_h_homeであれば呼び出されるphpはh_home.phpテンプレートはh_home.tpl
と決定される。
OpenPNEではデフォルトのSmartyデリミタを({})に変更している。
テンプレートについてはOpenPNEよりもSmartyのノウハウが必要になる。
OpenPNEをカスタマイズするには、まずSmartyを勉強することになるとおもう。
Smartyの日本語ドキュメントは下記を参照
http://smarty.php.net/manual/ja/
※※※※※※※以下ムービーの内容※※※※※※※
さて、次は。
executeで、returnがsuccessで返ってきました。
要するに、executeやったときにSmartyにいろいろ変数を突っ込んでくれた。
で、最後、success、もうレンダリングしていいよ、と返ってきたら、
ようやくこの$smartyに、display、{$action}.tplっていうのをレンダリングしなさい、という命令が入ってます。
で、例えばこの{$action}.tplでどこのtplが呼ばれるかというと、
modules/pc/templatesっていうディレクトリの中に入っている、
アクション名と同名のtplがレンダリングされます。
それで今回、h_homeが呼ばれた場合には、h_home.tpl。
要するにページ、PHPと、tplっていうのは、全く同名になります。
例えば、ページアクション名がpage_h_homeだった場合には、
PHPはh_home.phpが呼ばれるし、tplは、h_home.tplがレンダリングされます。
ここは、規約ですね。
で、こんな感じで、tplのぐちゃっとしたファイルがある。
まずheaderを呼んで、HTMLタグとかを作るわけです。
htmlとかheadとかbodyとか。
検索画面を出すか、なんてのがあったり。
検索ボックスを出したりとか。
で、本体を出して。
これはHTMLとSmartyテンプレートの拡張タグみたいなものが入り混じっているので、
なかなか見難いです。
だからいくつか特徴を挙げておきます。
まず、普通のHTMLはHTMLで書けばいいんですね。
全く制約なしにHTMLで書けばいい、と。
ただ、HTMLで書くだけでは毎回同じページが出てしまうので、意味がない。
毎回ダイナミックなページを出したい場合には、
このSmartyのタグを使います。
通常、デフォルトのSmartyのタグっていうのは
{}で作るんですけれど、
{}はJavascriptと衝突するんです。
ですからOpenPNEでは、Smartyのデリミタを({})という風にしています。
つまりOpenPNEでは、({})で囲まれた部分をSmartyのタグとして認識するということです。
で、ここだと、
ext_include functionで、inc_header.tplを呼んでください、
という指令です。
こちらの場合はif文、
もしもSERCH_HOMEをDISPLAYしなさいという指令が来たら、
このif文から、if文が閉じているところまで({/if})をレンダリングしましょうね、
という。
ここまでが検索窓です。
管理画面で設定がonにされていればレンダリングされるし、
offにされていればレンダリングされませんよという。
で、あとはひたすらテンプレートと、Smartyのタグとの繰り返し。
だから、誕生日だったらここをレンダリングする。
if文の設定値っていうのは、同名のh_home.phpから渡されています。
ここはもう、ほとんどSmartyの書式なんで、
OpenPNE扱うというよりは、Smartyのマニュアルを読むことが重要です。
どちらかっていうとはじめは、
OpenPNEを勉強するというよりはSmartyをしっかり勉強する方が、
結構大事だったりするんじゃないかと思ったりします。
do系(type=do)のアクションの処理フロー
do系はcontroller.php内で明示的に記述されていないのでフローが追いにくい。
type=pageが指定されてなければ、do系のアクションであると判別されて、executeが呼ばれる。
do系のアクションではreturn “success”が無い。
その代わりに、openpne_redirect()が呼ばれて、別のページにリダイレクトする処理が行われる。
openpne_redirect()関数は、util.php内で定義されている。
リダイレクトにはクライアントリダイレクト方式を使っている。
HTTPプロトコルで
Location:ヘッダを送出することで、ブラウザに対してリダイレクトを依頼する。
先ほど、
page系まではレンダリングの説明をしたので、
ではdo系の方、実行系の方はどうやってやってるかっていうのを、
説明したいと思います。
これ、プログラムの書き方がわかりにくいんですけれど、
page系の方は明示的に、pageだったらこうしなさいという指示が入っている。
だけど、この$action_obj->execute($requests)っていうのは、
page系でもdo系でも両方、ここが実行される。
page系だった場合はreturn”success”が返ってくるから、
successが返ったらレンダリングしましょう、と。
返ってこなかったら何もしないで後処理に回しましょう、
という設計です。
実はこの$action_obj->execute($requests)で、
do系のexecuteも実行されている。
例えば、c_event_invite、
コミュニティでイベントに招待するというdo系の関数なんですが、
やはりここに、function executeがある。
executeでいろいろやるんだけれど、
先ほどのpage系ではreturn_successとありましたが、
ここにはreturnが何もない。
何も変数返ってこないで、
openpne_redirect()という関数、
別のページをレンダリングしなさいよというリダイレクトの処理に入ってしまってる。
つまり、successは戻らないで、リダイレクトしなさいね、
という指示になっている。
で、openpne_redirect()、要するに「実行が終わりました」と。
実行が終わっただけでは何もやらないんです。
ページをレンダリングせず、実行が終わった、というだけ。
じゃあどうやってページを返すのかと言ったら、
openpne_redirect()で別のページに渡してしまおう、と。
この場合はpcモジュールのpage_c_event_invite_endっていうページを飛ばせと。
パラメータにはtarget_c_commu_topic_idを渡しなさい、という指示です。
このopenpne_redirectは、webapp/lib/util/util.phpにあります。
モジュール名とアクション名とパラメータが指定される。
それで、client_redirect_absoluteというのがある。
ここはどういうことをやっているかというと、
doのアクションが来たら、
普通はそこでそのままページを返せばいいのだけれど、
OpenPNEでは一回PCとか携帯にリダイレクトのheaderを返す。
要するに「このページに移ってください」と空のメッセージを返すんです。
で、クライアントリダイレクトをして、Location:ヘッダを出すんです。
要するに、
Locationはどこどこですよ、
ページが変わったからこのページに行ってください、
というのをクライアントのブラウザにいったん返す。
クライアントのブラウザはそれをもらったら、普通に
page系のページに遷移するというような仕掛けになっています。
これをクライアントリダイレクトとよく言います。
要するにdo系が終わったらいったんユーザーに返して、
ユーザーがもう一回なにかアクションをして、
page系に遷移するということです。
わりとこれは、page系と実行系が切り離せるので、楽なやり方です。
ただ、サーバの負荷はちょっとかかりますが。
普通だったらリクエストが来たらそのまま返せばいいのですが、
リクエストして返してもう一回リクエストして
ページを返すという仕組みになっています。