2008年5月19日(月曜日)

symfony+sfModalBoxPluginで簡単ダイアログ

カテゴリー: - sato @ 12時32分52秒

satoです。
今回はsymfonyフレームワークで、簡単にダイアログボックス的なものを表示してみます。
sfModalBoxPluginを利用します。

・sfModalBoxPluginのインストール
sfPrototypePluginが必要なので、先にインストールします。

$ symfony plugin-install http:⁄⁄plugins.symfony-project.com/sfPrototypePlugin
$ symfony plugin-install http:⁄⁄plugins.symfony-project.com/sfModalBoxPlugin

細かい設定は特に必要ありません。

・ダイアログ側作成
まず、ダイアログとして表示したいactionを作成します。
apps/frontend/modules/dialogtest/actions/actions.class.php

  public function executeDialog()
  {
  }

apps/frontend/modules/dialogtest/templates/dialogSuccess.php

<p>hello dialog box</p>
<p><a href="#" onclick="Modalbox.hide();return false;">close</a></p>

・呼び出し元作成
apps/frontend/modules/dialogtest/actions/actions.class.php

  public function executeTest()
  {
  }

apps/frontend/modules/dialogtest/templates/testSuccess.php

<?php use_helper('ModalBox') ?>
<?php echo m_link_to('show dialog', 'dialogtest/dialog') ?>

・実行
dialogtest/testをブラウザで表示すると、

このような画面になります。ここで「show dialog」をクリックすると

このような画面になります。「close」をクリックすると元の画面に戻ります。

例えばselectタグでは多すぎるような項目を選択させる際に、ダイアログを出して選択させて、選択結果をJavaScriptで元の画面に挿入するようにすると、操作性が上がると思います。
デザインの都合上、管理画面などに利用するのが向いていると思います。
actionがそのままダイアログとして利用できるのは便利だと思うので、是非試してみてください。

ModalBoxの詳しい説明は、ModalBox | Wildbitをご覧下さい。sfModalBoxPluginについてはsfModalBoxPlugin - symfony - Tracをご覧下さい。


2008年4月14日(月曜日)

Propelを単体で使う

カテゴリー: - sato @ 18時09分58秒

PHP5専用のO/RマッパーにPropelというものがあります。
PHPのフレームワーク「symfony」の標準のO/Rマッパーとして有名ですが、単体で使っている人はあまり見かけない気がします。
今回は単体で使う方法を軽く説明しようと思います。

1.インストール
PEARコマンドでインストールするのが簡単です。

# pear channel-discover pear.phpdb.org
# pear install phpdb/propel_generator
# pear install phpdb/propel_runtime

なお、phingが必要なので、入っていない場合は事前に

# pear install channel://pear.phing.info/phing

で入れておいてください。
ログを記録する場合はLogが必要なので、

# pear install Log

で入れておいてください。(今回は不要です)
執筆時点でのPropelの安定バージョンは1.2です。

2.テーブル定義
PropelではXMLでテーブル構造を定義します。これにより、リレーションを含めたPHPオブジェクトが全て自動で生成されます。
今回は仮にbookmarkという簡単なアプリケーションにします(実際にアプリケーションは作成しません)。bookmarkというフォルダを作り、以下のファイルを作成します。
schema.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<database name="bookmark" defaultIdMethod="native">

<table name="bookmark" description="bookmark"> <column name="id" type="integer" primaryKey="true" autoIncrement="true" required="true" description="bookmark id"/> <column name="title" type="varchar" size="255" required="true" description="bookmark title"/> <column name="url" type="varchar" size="255" required="true" description="bookmark url"/> </table>

</database>

3.基本設定
ビルドに関する設定は以下のファイルで設定します。
build.properties

propel.project = bookmark
propel.database = mysql
propel.database.url = mysql://root@localhost/bookmark

また、これとは別に、実際のアプリケーションからの接続時の設定は以下のファイルを使用します。
runtime-conf.xml

<?xml version="1.0" encoding="UTF-8"?>
<config>
 <propel>
  <datasources default="bookmark">
   <datasource id="bookmark">
    <adapter>mysql</adapter>
    <connection>
     <phptype>mysql</phptype>
     <database>bookmark</database>
     <hostspec>localhost</hostspec>
     <username>root</username>
     <password></password>
    </connection>
   </datasource>
  </datasources>
 </propel>
</config>

このような仕様になっているのは、Propel自体がgeneratorとruntimeで分離しているからだと思われます。

ファイルを作成したら、mysqlでbookmarkという名前のデータベースを作成しておいてください。

4.オブジェクト作成

bookmarkフォルダで以下のコマンドを実行します。

% propel-gen .

するとbookmarkフォルダ以下に多数のファイルが生成されます。
実際にデータベースに投入するSQLファイルは、build/sql/schema.sqlになります。そのままmysqlに投げてもいいですが、

% propel-gen . insert-sql

でもデータベースに投入できます。(実際に行っていることは手動での挿入と同じだと思います)

propel-genの際に、

Execution of target "convert-props" failed for the following reason: /usr/share/pear/data/propel_generator/build-propel.xml:534:12: Cannot write parsed template: Unable to parse template ./templates/conf/Control.tpl: It is not safe to rely on the system's timezone settings. Please use the date.timezone setting, the TZ environment variable or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'Asia/Tokyo' for 'JST/9.0/no DST' instead
[phingcall] /usr/share/pear/data/propel_generator/build-propel.xml:534:12: Cannot write parsed template: Unable to parse template ./templates/conf/Control.tpl: It is not safe to rely on the system's timezone settings. Please use the date.timezone setting, the TZ environment variable or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'Asia/Tokyo' for 'JST/9.0/no DST' instead

のようなエラーが出た場合は、

% export TZ=Asia/Tokyo

としてください。

5.実際に使う

index.php

<?php

require_once('propel/Propel.php');

// $dir = dirname(__FILE__); // ルートフォルダであればこれでも取得できます $dir = '/path/to/bookmark'; set_include_path($dir.'/build/classes' . PATH_SEPARATOR . get_include_path());

Propel::init($dir.'/build/conf/bookmark-conf.php');

これが初期化部分になります。$dirは適宜変更してください。

require_once('bookmark/Bookmark.php');

使用するテーブルに対応するファイルを読み込みます。

この後に実際のコードを記述していきます。

・データを追加/保存する

$bookmark = new Bookmark();
$bookmark->setUrl('http://ryus.co.jp/');
$bookmark->setTitle('XOOPS Webサイト/イントラサイト制作、XOOPS モジュール開発/カスタマイズを専門に行っています。 - XOOPS専門-株式会社RYUS');
$bookmark->save();

これでINSERTになります。DBから取得したデータであればUPDATEになります。両者を特に気にする必要はありません。

・データを読み込む

$bookmark = BookmarkPeer::retrieveByPk(1);
$url = $bookmark->getUrl();
$title = $bookmark->getTitle();
echo $url,$title,PHP_EOL;

読み込み系は"テーブル名Peer"クラスで行います。
retrieveByPkは、主キーからデータを取得します。
# 表示が化ける可能性があるので、適当な文字コードで表示してください。

・複数データ取得

$bookmarks = BookmarkPeer::doSelect(new Criteria());
foreach($bookmarks as $bookmark) {
  $url = $bookmark->getUrl();
  $title = $bookmark->getTitle();
  echo $url,$title,PHP_EOL;
}

doSelectは条件付きで複数レコード取得します。引数のCriteriaは条件を指定するクラスなのですが、今回は無指定なので単にnewしたものをそのまま渡しています。
条件を指定する例としては、

$c = new Criteria();
$c->add(BookmarkPeer::URL, 'http://ryus.co.jp/');
$bookmarks = BookmarkPeer::doSelect($c);

のような感じになります。Criteriaの条件設定は細かいところまで手が届くようになっています。

6.まとめ
詳しくは公式のドキュメントが充実しているので、そちらを参照してください。
次期バージョンであるPropel1.3(symfony1.1で載る予定)ではcreoleからPDOになり、更なる機能強化が期待できます。
PHPのO/Rマッパーは他にもS2Dao.PHP5Doctrineなど多数あるので、好みのものを利用するのがいいと思います。


2008年4月7日(月曜日)

Smartyのテンプレートの文字列内変数を拡張する

カテゴリー: - sato @ 17時20分49秒

satoです。
XOOPSでは、テンプレートエンジンにSmartyを使うことになります。
このSmartyは便利なのですが、若干使いづらい部分もあったりまします。

まず前提として、Smartyの文字列定数中に変数を混ぜたい場合、バッククォート(`)で囲むとそれが変数として解釈されるようになっています。
例えば、

{"私は`$name`です。"}

として、$nameに"sato"という文字列がassignされていると、

私はsatoです。

と表示されます。

しかし、このバッククォート内にメンバ関数を指定すると、解釈がうまくいかないようです。

例えば、

私は{$my->show('name')}です。

みたいなものは可能なのですが、

{"私は`$my->show('name')`です"}

とすると、

私は`Object id #2->show('name')`です。

のように、$myの部分だけ変数として解釈され、それ以外は普通の文字列として出力されてしまいます。
通常、こういう場合は、

{assign var=name value=$my->show('name')}
{"私は`$name`です"}

のように1段階assignを追加することになり、若干手間がかかります。
今回はこれの簡易的な対応方法を試してみました。

Smartyのassignされた変数というのは、実際にそのスコープに存在するものではなく、Smartyクラスの_tpl_varsメンバ変数に格納されています。このため、テンプレート側で記述した変数は、Smartyの構文解析を通してSmartyクラスのメンバ変数になるように置換処理が入ります。具体的には生成されたテンプレートキャッシュを見ればわかると思います。
そのため、Smartyでは正規表現を利用して構文解析を行っているのですが、この正規表現に手を入れることで、上記の対応が可能になります。

バッククォート内を解釈しているのは、Smarty_Compiler#_expand_quoted_textで、変数の解析をしている正規表現は_obj_ext_regexpに格納されています。
このため、Smarty_Compilerに手を入れればいいのですが、Smarty_CompilerはSmarty#_compile_sourceで生成され、すぐ破棄されるので、途中からアクセスすることはできません。Smarty_Compiler.class.phpを直接書き換えればいいという話もありますが、それでは汚くなってしまいます。
幸い、Smartyクラスが生成するSmarty_Compilerクラスは別のものに変更ができるようになっています。Smartyクラスのcompiler_fileとcompiler_classにそれぞれ読み込むファイルとクラス名が格納されているので、それを自前のものに変更します。

具体的にやってみます。
以下のファイルを作成します。パス等は適宜変更してください。
MySmartyCompiler.class.php


	

require 'Smarty-2.6.19/libs/Smarty_Compiler.class.php';

class MySmartyCompiler extends Smarty_Compiler { function MySmartyCompiler() { parent::Smarty_Compiler();

$this->_obj_ext_regexp = str_replace(’(?:[$?[w.]+])*’, ‘(?:[($?[w.]+)])*(?:(($?[w"’.]+)))*’, $this->_obj_ext_regexp); } }

呼び出し側を作成します。
index.php


	

require 'Smarty-2.6.19/libs/Smarty.class.php';

class myClass {

function show($var) { return 'sato'; }

}

$smarty = new Smarty(); $smarty->compiler_file = ‘MySmartyCompiler.class.php’; $smarty->compiler_class = ‘MySmartyCompiler’;

$smarty->template_dir = ‘templates’; $smarty->compile_dir = ‘templates_c’; $smarty->config_dir = ‘config’; $smarty->cache_dir = ‘cache’; $smarty->plugins_dir = ‘plugins’;

$smarty->assign(’my’, new myClass()); $smarty->display(’index.tpl’);

テンプレートを作成します。
templates/index.tpl

<html>
<body>

{"私は`$my->show('name')`です。"}

</body> </html>

実行すると、

私はsatoです。

のように正常に表示されているのが確認できると思います。
全てのパターンでテストを行っているわけではないので、不具合があったらコメント欄等でよろしくお願いします。

XOOPSからこれを利用する場合は、各RenderSystem内に存在するSmartyオブジェクトを取得して書き換える必要があります。
モジュールの場合は通常はLegacy_RenderSystemなので、

    $root =& XCube_Root::getSingleton();
    $renderSystem = $root->mContext->mModule->getRenderSystem();
    $renderSystem->mXoopsTpl->compiler_file = 'MySmartyCompiler.class.php';
    $renderSystem->mXoopsTpl->compiler_class = 'MySmartyCompiler';

のような感じで対応が可能です。(表示処理の実行前に記述してください)
管理画面はLegacy_AdminRenderSystemなので、mXoopsTplではなくmSmartyを参照することになります。

しかしこの方法でも、

{"私は`$pattern[$foo->bar()]`です"}

のようなパターンには対応できません。このパターンに対応するには_expand_quoted_text自体を大幅に改変する必要がありそうです。興味のある方は挑戦してみてください。


2008年1月18日(金曜日)

シングルサインオンについて考えてみる

カテゴリー: - gusagi @ 17時50分02秒

gusagiです。
しばらく前から、XOOPS Cube関連のコミュニティでもLDAP認証や、TypeKey認証などのサインオン系機能について、ちょくちょくと書き込みが出ている気がします。
シングルサインオン自体には興味があったので、ちょっと調べてみたところこういう記事を拝見しました。
HTTPまたはSOAPを基本としていて、OpenIDやLDAPにも対応しているとのことなので、時間を作って弄ってみようかと思います。
XOOPS Cubeにも応用できるかどうか、それ以前に自分に使いこなせるのか不安ではありますが、やってみないことには何も始まらないので、まずは試してみようと思います。
この結果は、後日の記事にも書くつもりですので、気長にお待ち頂けますと幸いです^^;


2007年11月5日(月曜日)

軽量PHPフレームワークちいたん

カテゴリー: - Ryuji @ 18時51分34秒

いたれりつくせりの重量級フレームワークが多い中、総ファイルサイズ38kバイトという超軽量のPHPフレームワークがあることを先日知りました。

ちいたん

作成動機にすごく同意してしまいます。
引用:

ちなみに私は普段CakePHPを使用していますが、それを使用するほど大きなプロジェクトではなく、でも多少手のかかる物の場合に使えるフレームワークがほしい… そんなときに使えるフレームワークを目指して作成しました。

cubsonでのモジュール開発に慣れてしまうと、ちょっとしたものでも、一から作る気にはなれない。
でも、XOOPS Cubeを入れるほどでも無い。

そんなときに、XOOPS Cubeのモジュールとして開発するのか?
それとも、一からコツコツと書くのか?

これ、けっこう悩みます。

そんな、どっちでいこうかなぁと悩むようなプログラムを作成するときに、自分が使い慣れているフレームワークの軽量版があれば確かに便利だと思います。

ただ、今度は、どこまでその軽量版で開発して、どっからメインのフレームワークで開発するのか、その使い分けに悩みそうな気もしますが(^^;

それでも、ちょっとしたことにサクッと使える軽量フレームワークという考え方はいいなぁと思います。


12 queries. 0.031 sec.
Powered by WordPress Module based on WordPress ME & WordPress

〒104-0061 東京都中央区銀座1丁目3番3号 G1ビル7階
お問い合わせ TEL 03-3524-8860

Copyright(c) 2012 RYUS.All Rights Reserved.