伊藤清徳の垂直落下式ムーンサルトプレス

PerlとかPHPとかMySQLとか...がんばっても8割だ。

Category: seezoo cms

Inter-MediatorをCodeigniterから使ってみる

INTER-MediatorというPHPアプリケーションフレームワークがあります。
かなり前から存在は知っていたものの、今回はじめて使ってみました。
普通に使うには、私個人としてメリットがなかったので使って来なかったのですが、
他のフレームワークと一緒に使うと便利なんじゃね?
ってことで、Codeigniterで使ってみることに。
 
え?なんでかって?seezoo cmsのコミッターだからさ!
 


そもそも、INTER-Mediatorってなによ?

 
そもそも、INTER-Mediatorってなによ?ってことなんですが、
従来のPHPやPHPフレームワークでは、
SQLやORMをつかってデータベースのレコードを呼んできて、
 

<table>
<?php foreach( $rows as $row ): ?>
<tr> <td><?php $row['field']; ?></td> </tr> <?php endforeach; ?>
</table>

 
のようなコードを書かなくてはなりませんでした。
(PHPTALをつかうともっとスッキリHTMLのポリシーに近くなりますが)
 
Inter-Mediatorの場合、PHPファイルに規定の書き方で、
呼び出すテーブル・1ページあたりのレコード数などを書き入れ、
そのファイルをjavascriptファイルとして、HTMLから呼び出すだけで、
 

<table>
<tr>
<td class="IM[テーブル名@フィールド名"></td>
</tr>
</table>

 
こんなHTMLを書けば、Javascript制御でclassで指定された
テーブル名/フィールド名のデータを表示してくれます。
また、複数レコードを呼ぶ設定にしている場合は、
テーブルの行数もレコード数分追加してくれます。


定義ファイルの中身

INTER-Mediatorの定義ファイルは
 

<?php
require_once ('INTER-Mediator/INTER-Mediator.php');
IM_Entry(
	//呼び出すレコードの定義
	array(
		array(
			'records' => 1,
			'name' => 'person',
			'key' => 'id',
		),
	),
	//オプション設定
	null,
	//DBへの接続設定
	array('db-class' => 'PDO'),
	//デバッグレベルの設定
	false
);

こんな感じです。詳しくは公式サイトのドキュメントをご覧下さい。
IM_Entry();が、HTMLのクラスセレクタを解析して、
DBのレコード/フィールドを差し込むJavascriptコードを出力してくれる
そんな仕組みになっているようです。
 


Codeignireから使うには?

 
上記の様に、INTER-Mediatorの定義ファイルは実に単純なしくみです。
この定義ファイルを出力するコントローラーをつくれば、
ページの出力がかなり簡単になるのでは?
と思ったわけです。
 
気をつけるポイントとして、
INTER-Mediatorでは、PDOでMySQLなどへの接続を行なっているので、
CodeigniterのDBドライバインスタンスをINTER-Mediatorで使うことはできません。
ただ、CodeigniterでつかっているDBの設定はそのまま引き継ぎたい。
そんなわけで、以下のようなコントローラーを作ってみました。
 

<?php
class im_require extends CI_Controller
{
	public function index()
	{
		//IMをrequire
		require FCPATH.'INTER-Mediator/INTER-Mediator.php';
		
		//データベース設定を呼び出す
		require APPPATH . 'config/database.php';
		$dsn = $db[$active_group];
		
		//第三引数
		$dbset = array();
		$dbset['db-class'] = 'PDO';
		$dbset['dsn'] = 'mysql:dbname=' . $dsn['database'] . ';host=' . $dsn['hostname'];
		$dbset['user'] = $dsn['username'];
		$dbset['password'] = $dsn['password'];
		
		
		IM_Entry(
			array(
					array(
						'records' => 1,
						'paging' => true,
						'name' => 'person'
					)
			),
			null,
			$dbset,
			0
		);
	}
}

 
DB設定ファイルを呼び出して、今アクティブなDB設定を
INTER-MediatorのPDO設定に入れているという簡単なしくみです。
 
あとは、どのテーブルを呼び出すかなどを、
GET/POSTのパラメータなどから呼び出せるようにしたり、
YAMLなどで定義できるようにしておけば、
1つのコントローラーで、複数のINTER-Mediatorの定義を作ることができるようになります。
 


INTER-Mediatorの改造

 
さて、定義ファイルを作成するコントローラーができたわけですが、
これだけでは、ちょっとまずいところがありますので、
INTER-Mediator自体の改造が少し必要です。
GenerateJSCode.phpを改造します。
68行目付近に
 

$pathToMySelf = (isset($scriptPathPrefix) ? $scriptPathPrefix : '')
. $_SERVER['SCRIPT_NAME'] . (isset($scriptPathSufix) ? $scriptPathSufix : '');

 
があります。
この状態ですと、定義ファイルの物理的なパスをJavascript中でXHRのURLとして利用してしまうので、
URIルーティングがあるCodeigniterでは、index.phpが呼ばれてしまい、
正しく動作してくれません。
 

$pathToMySelf = (isset($scriptPathPrefix) ? $scriptPathPrefix : '')

			. $_SERVER['SCRIPT_NAME'] . (isset($scriptPathSufix) ? $scriptPathSufix : '');

if(function_exists('get_instance'))
{
	$ci = get_instance();
	$pathToMySelf = (isset($scriptPathPrefix) ? $scriptPathPrefix : '')
		. '/index.php/' . $ci->uri->uri_string()
		. (isset($scriptPathSufix) ? $scriptPathSufix : '');
}

このように書き換えています。
Codeigniterからの呼び出しでない場合も踏まえて、
コントローラーインスタンスが呼べるかどうかで、振り分けをしています。
 
上記のコードでは、GETパラメーターへの考慮がされていないので、
実務レベルで使うには、そのあたりも考慮した改造が更に必要でしょう。
 


viewファイルの記述は?

viewファイルのへの記述は特に気にするような点はなく、
ここまでで作った定義作成コントローラーをjavascriptとして呼び出して、
bodyにonload="INTERMediator.construct(true);"をつければOKです。
 

<script type="text/javascript" src="http://localhost/index.php/im_require"></script>

  

<body onload="INTERMediator.construct(true);">

 
こんな感じですね。
 


seezoo cmsに入れる?

 
seezoo cmsはCodeigniterベースにできているので、
ここまでで書いたコントローラーを突っ込めばうごいてくれますし、
seezoo cmsには管理者/会員承認機能がそろっているので、
このへんもからめると面白いものができそうです。
 
また、Codeigniter自身のModel(DB)機能を使えば、
Inter-Mediartorではカバーできない複雑な処理も行うこともできますから、
「とても便利系」なライブラリやフレームワークにありがちな、
「あーここまではできないかーorz」という手詰まり感も回避することができます。
 


将来展望

実は、私今年のはじめからseezoo cmsベースで似たようなものを作ろうとしていたのですが、
仕様の練り直しなどで進んでいなかったところがあり、
一気に解決した感じです。
 
CodeigniterにはDB構造を操作するメソッドも揃っているので、
テーブル作成やインデックスの付与などを管理画面からできるようにすれば、
オンライン版FileMakerのようなものができるのでは!?
と思っています。
 
もう少しいじってみよう!
 


P.S.

INTER-Mediatorのコードを覗くと、
プロパティが

var $var = '';

のような、ちょっと古い書き方がされているところがあるようです。
この辺りは改善してもらえるとうれしいなー。

seezoo cms をお名前.comのSDで使う話

どうもseezoo cmsの魔改造野郎イトウキヨノリです。


今日はseezoo cmsをお名前.comの共有ホスティングSDで使った時の話です。

インストールに関しては、特に問題がありません。
DBを作ると「xxxxxxxxxx.cgidb」という謎のホストを指定されますが、
恐る恐るインストールしてみたら、
そこは問題なくインストールできました。
 


が、ハマったのが短縮URLです。
http://domain/index.php/hogehoge/

http://domain/hogehoge/
に短縮する奴ですね。


seezooには予め様々な環境でテストして、
最大公約数的に大丈夫であろうという
mod_rewriteの記述を示してくれます。
これを.htaccessに書き入れてindex.phpと同じ場所にアップすれば、
ほとんどのサーバーでは、
正常に「index.php」を除いたURLで動作してくれます。


が、お名前のSDサーバーではどうやらいくつか問題点があります。

RewriteEngine On
RewriteBase [パス]
RewriteCond $1 !^(index\.php|sitemap.xml|sitemap_ssl.xml|css|js|captcha|uploads|templates|blocks|phpMyAdmin|.+\.gif$|.+\.jpg$|.+\.png$|.+\.js$|.+\.css$|.+\.json$|.+\.ico$|.+\.swf$|.+\.flv$)
RewriteRule ^(.*)$ index.php?__SZREQ__=$1 [QSA,L]

共有ホスティングでPHPがCGIモードで動いている場合は
こんな記述を示してくれます。
CGIモードの場合、PHPのグローバル変数$_SERVER[‘PATH_INFO’]が取得できないことがあり、
その代わりにパスの情報をGETパラメータとしてPHPに渡しています。

また[パス]のところには、
seezooが動いているパスを自動で挿入してくれます。

seezooの場合、ほとんどのサーバーで、
この方法で動きます。


が、お名前.comのSDの場合、このままでは動きません。
まず、「[パス]」の部分、ここは、seezooが適切なパスを取得できないようです。
(サーバーマシンのルートからのフルパスが出力されてしまいます)

どうやら、PHPに渡される環境変数がおかしいようです。
したがって、seezoo側ではどうしようもないですから、
手動で書き換えることになります。

ドキュメントルートでseezooを動かすなら、

RewriteEngine On
RewriteBase /
RewriteCond $1 !^(index\.php|sitemap.xml|sitemap_ssl.xml|css|js|captcha|uploads|templates|blocks|phpMyAdmin|.+\.gif$|.+\.jpg$|.+\.png$|.+\.js$|.+\.css$|.+\.json$|.+\.ico$|.+\.swf$|.+\.flv$)
RewriteRule ^(.*)$ index.php?__SZREQ__=$1 [QSA,L]

このような感じですね。


これでもまだ動かない。なぜ…。
どうもパス解決がseezoo内部でできていない。なぜ…

調べる時間がなかったため、原点に立ち返ることに。
むか~し書いた僕の記事を元に
index.phpの冒頭に

if( isset( $_GET['__SZREQ__'] ) ){
    $_SERVER['PATH_INFO'] = $_GET['__SZREQ__'];
}

と書いたら動いた!

あれー。。。seezooにはこのへんの判定スクリプトも入ってるはずなんだけどなぁ。。。


ちなみに同時的に、seezooの根底で動いているフレームワークである、
Codeigniterをインストールする必要があったのですが、
Codeigniterでも同じ問題が。同じ方法で解決。
どうやらお名前.comのSDはクセモンのようです。

SDでCakeの短縮URLが動かない旨のブログを散見しましたが、
おそらく同じような問題だと思われます。
テストは割愛しますが、Cake使いの方も参考になれば。

SeezooCMS用のwikiブロックを作った理由(簡単テーブル作成)

こちらでSeezooCMS用のWiki記法ブロックを公開しているわけですが、
これを作った理由が、おそらくみなさんの役に立つのではということで、
Tipsを書いておきます。
 
SeezooにはWYSIWYGなHTMLブロックなど必要な機能はひと通り揃っていて、
企業の担当者レベルで非常に更新のしやすいシステムですが、
一個だけ不満が。
それがテーブル作成でした。
 
WYSIWYGなHTMLエディタには、テーブル機能が搭載されておらず、
HTMLコードを直で書かないといけない。
そして、一般担当者レベルでは、表組みはテーブルが一番分かりやすい。
 
ということで、何か簡単にテーブルを書ける方法がないかということで、
作ったのがwiki記法ブロックです。
 
wiki記法ブロックに

||セル1||セル2||
||セル3||セル4||

と書けば、

<table>
<tr><td>セル1</td><td>セル2</td></tr>
<tr><td>セル3</td><td>セル3</td></tr>
</table>

と自動で出力してくれる。
 

||~セル1||セル2||
||~セル3||セル4||

と書けば

<table>
<tr><th>セル1</th><td>セル2</td></tr>
<tr><th>セル3</th><td>セル3</td></tr>
</table>

と自動で出力してくれる。
 
という仕組みです。
 
どうですか?これならHTMLわからない人でもテーブルを簡単に書けます。
 


ただ、ここまでの説明だと、飾りっけのないテーブルになってしまいますので、
本日のバージョンアップで任意のidとclassを振れるようにしていますので、
例えば、テンプレート用CSSやカスタムCSSに

.wikiclass table {
 margin: 0px;
 padding: 0px;
 background-color: #FFFFFF;
    border-spacing:0px;
    border-collapse:collapse;
    empty-cells:show;
    width:100%;
    border-top:1px solid #663300;
    border-left:1px solid #663300;
    background-color: #FFFFFF;
}
.wikiclass table td {
    border-right:1px solid #663300;
    border-bottom:1px solid #663300;
    padding:3px;
    margin:0px;
}
.wikiclass table th {
    background-color: #F6F6F6;
    border-right:1px solid #663300;
    border-bottom:1px solid #663300;
    padding:3px;
    width:30%;
    margin:0px;
}

と書いておき、classに「wikiclass」を設定すれば、装飾のされたテーブルを表示できるようになります。
 
どうですか?地味だけど便利でしょ?
 
ご活用ください。

SeezooCMS用wikiブロックをバージョンアップ

先日作ったSeezooCMS用のWikiコードブロックをバージョンアップしました。
 
・作成したブロックを<div>で囲み、そこに任意のidとclassを付与できるようにしています。
 これにより、CSSやカスタムCSSで、そのブロックに任意のCSSを適用できます。
 
・初版では、wikiブロックにHTMLコードを入れた場合、自動サニタイズされる仕様になっていましたが、
 それを回避しています。<script>などもそのまま出力されてしまいますので、
 セキュリティホールを作らないように注意が必要です。
 
以上が今回のバージョンアップです。
ダウンロードはこちらから

seezoo cmsのwiki記法ブロックを作ってみた。

seezoo cms(http://seezoo.org/)が楽しい。
プログラマ的に言って拡張がかなり楽!!
 
a-blog cms(http://www.a-blogcms.jp/)といい、
名古屋の人が作るツールは楽しい物ばかりだ。
 


昨日、seezooの開発元の音生さん(http://neo-navi.net/)に伺った際に、
色々話を聞かせていただいて、
その内容をもとにseezoo用のブロックを作ってみた。
 
前々からほしいと思っていた、wiki記法ブロックを作った。
パーサーを自分で書くのは大変だったので、
PEARのText_wikiに頼っている。

ダウンロードはこちらからどうぞ。


【インストール方法】

1)まず、PEARのText_wikiをインストールします。
PEARコマンドが使える場合は、
通常通りコマンドでインストールしてください。
 
使えない場合は、

・PEAR(ベースシステム)
http://pear.php.net/package/PEAR/download
をダウンロードして、解凍してできる、
PEAR.phpとPEARディレクトリを
system/application/libraries/ディレクトリに置きます。

・Text_Wiki
http://pear.php.net/package/Text_Wiki/download
をダウンロードして、解凍してできる、
Textディレクトリを同じく
system/application/libraries/ディレクトリに置きます。
 
 
2)ブロックを置く。
先ほど上記にてDLしたWikiブロックを解凍してできる、
kiyowikiディレクトリを、
blocksディレクトリに置きます。
 
3)ブロックを有効にする。
管理画面のブロック管理にいくと、
「インストール可能なブロックのリスト」に、
「Wiki記法ブロック」というのが追加されているので、
それを有効します。

あとは、通常のブロックと同様、
ページ編集画面で「Wiki記法ブロック」を追加して、
表示されるテキストエリアにWiki記法を書けばOKです。
使える記法については、
http://pear.reversefold.com/dokuwiki/text_wiki:samplepage
ここを参考にしてください。


 
ここまで来て気づいた。。。
Text_WikiのインスタンスをいちいちViewで有効にしてる…orz
動くには動くけどスマートじゃないし、色々無駄。。。
そのうちヘルパとして用意したバージョンを公開しますね。
とりあえず、利用される場合は、
完全自己責任の名のもとに使うベータ版として利用してくださいね。
あくまでも、これは私のお勉強のためのものですから!!

あ、そしてもう一個気づいた、wiki記法ブロックにidとclass付けれるようにしたほうがいいな、、、カスタムCSSで自由に操作できるもの。
 


追記:バージョアンアップ 2010/12/29

・作成したブロックを<div>で囲み、そこに任意のidとclassを付与できるようにしています。
 これにより、CSSやカスタムCSSで、そのブロックに任意のCSSを適用できます。
 
・初版では、wikiブロックにHTMLコードを入れた場合、自動サニタイズされる仕様になっていましたが、
 それを回避しています。<script>などもそのまま出力されてしまうので、
 セキュリティホールを作らないようにしてください。

さくらインターネット(スタンダード)にSeezooCMSを入れる。

ちょっと野暮用で(という言い方も変だが)、
さくらインターネット(スタンダード)にSeezooCMSをインストールする必要があった。
 
公式のインストール方法を元に設置まで進んで、
いざインストール設定をと思うと進めない。
???
と思い、/index.phpに直接アクセスしたら、
インストーラーを見ることができたので、
なーんだと思ってインストール完了。
 
さぁ、じゃあ使おうじゃないかと思うと、
ここでさっきの問題が何を意味しているかわかった。
mod_rewriteの動作が変!!!orz
 
最初はmod_rewriteの動作がなのかなと、
.htaccess周りをずっと見ていたのだけれど、
どうもなんか違う。.htaccessの書き方は正常だ。。。
 
というようなことをTwitter嘆いていたら、
@longkey1さんが
・ルーティングあたりに問題がある。
・mod_rewrite後PHPにPATH_INFOが渡されないのが問題かも。
とアドバイスを受ける。
 
!!!
 
初めてCGIモードでPHPを触ったのですが、
CGIモードの場合、PATH_INFO周りの扱いが非常に面倒になるのですね…。
知りませんでした。。。
 
でも共有ホスティングではCGIモードがメインの日本では、
知らなかったでは済まされない事態…@longkey1さんありがとうございます。。。
 


 
私が行った対処方です。
 
まず、seezoo CMSデフォルトのサンプルでは、.htaccessは、

RewriteEngine On

RewriteCond $1 !^(index\.php|sitemap.xml|sitemap_ssl.xml|css|js|captcha|uploads|templates|blocks|phpMyAdmin|.+\.gif$|.+\.jpg$|.+\.png$|.+\.js$|.+\.css$|.+\.json$|.+\.ico$|.+\.swf$|.+\.flv$)
RewriteRule ^(.*)$ index.php/$1 [L]

 
こんな感じですが、これを
 

RewriteEngine On
RewriteBase /
RewriteCond $1 !^(index\.php|sitemap.xml|sitemap_ssl.xml|css|js|captcha|uploads|templates|blocks|phpMyAdmin|.+\.gif$|.+\.jpg$|.+\.png$|.+\.js$|.+\.css$|.+\.json$|.+\.ico$|.+\.swf$|.+\.flv$)
RewriteRule ^(.*)$ index.php?__REQ__=$1 [L]

 
こんな風にします。@_tk84さんの情報によると、さくらの場合は、基本的にRewriteBaseの設定は行った方が良いようです。ありがとう!_tk84さん。
 
次に、/index.phpの冒頭に、次のPHPスクリプトを埋めます。
 

if( isset( $_GET['__REQ__'] ) ){
    $_SERVER['PATH_INFO'] = $_GET['__REQ__'];
}

 
ここまでの流れを説明すると、
URLのパス情報を「__REQ__」というリクエストで送信して、
それを受け取ったindex.phpが、
$_GET[‘__REQ__’]を$_SERVER[‘PATH_INFO’] に代入して、
ルーティングを成功させようという魂胆。
 
 
これでいけるか。と思ったら、まだ変。。。
改めてCodeIgniterのルーティングについて調べる。
すると、CodeIgniterでは、何を基準にルーティングするのかを決める設定があって、
デフォルト状態ではそれが「auto」になっているという話。
それを明確に「PATH_INFO」を基準にせよとすれば、
うまく行くっぽい!
 
/system/application/config/config.php
の次の箇所

$config['uri_protocol']	= "AUTO";

$config['uri_protocol']	= "PATH_INFO";

 
と書き換えた。
 
 
これで成功!めでたしめでたし。
あとはつくるだけ。
 


 
@longkey1さん、@_tk84さん、ありがとうございます!

seezoo cmsをクララオンラインのサーバーにインストールしてみる。

先日のオープンソースカンファレンス名古屋2010(以下OSC)でキックオフとなった、
seezoo cms
 
OSCで担当の方とちょっとだけ意気投合したので、
帰宅後触ってみたらconcreat5っぽいのでいいなぁと思ったので、
ぜひ、開発(主にEC用のプラグインになるかと思いますが)に参加したい!
と思ったら、
私が普段メインで使っているクララオンラインの専用サーバーのPHPは
Ver5.1.6なので、要件をみたしてない(T_T)
 
とTwtterで嘆いたところ、公式アカウント
json_encode()だけどうにかできれば、5.1でも使えるとのこと!
ありがたい事に、公式ブログでも対応方法を書いていただけた。
ただ、私はマルチバイトを簡単に扱えて、なおかつ、staticでも使えるJsphonのが好きなので、
こちらで対応した(後述)。
 


というわけで、クララオンラインのサーバーにインストールする手順。
 
1)seezoo公式からシステムDL

2)json_encode()を擬似的に作成

3)インストーラーがPHPのバージョンチェックをしているので、これをスキップ

4) 通常通りインストール
 


 
こちらの記事によると、
CodeIgniterのヘルパー関数に擬似的なjson_encode()を作りましょう!
ってなってるんですが、恥ずかしながらCodeIgniterは名前は知ってたものの、使ったことがない!!
 
というわけで、お手軽実装のほうで。
 
まず、JSONエンコードするライブラリ「Jsphon」をこちらからダウンロードして、
解凍してできた
・Jsphon.php
・Jsphonディレクトリ
をsystem/application/libraries/に置きます。
 
次に、system/application/helpers/seezoo_helper.phpを開いて、一番下に
 

if ( ! function_exists('json_encode') ){
    
    require_once(APPPATH . 'libraries/Jsphon.php');
    function json_encode($data){
        return Jsphon::encode($data);
    }
}

 
を追記。
これで擬似的にjson_encode関数を作れます。
 
upgrade.phpというものもあります。
こっちを使えば、インクルードするだけで使えそうです。(マルチバイトはどうかな…。未確認)
 


次に、インストーラーのバージョンチェックをスキップします。
 
system/application/controllers/install.phpを開いて
 

$viewdata['php_version'] = version_compare(PHP_VERSION, '5.2.0', '>');

 
とされているところを
 

$viewdata['php_version'] = version_compare(PHP_VERSION, '5.1.0', '>');

 
に変更。

ここまでやったら、あとは、普通にインストーラーを走らせれば、
インストールできました。
 
今日はここまで!
これから使ってみながら、開発にも入り込んでいきます!