ぷぎがぽぎ このページをアンテナに追加 RSSフィード

2007-09-30

[][][] プラグインで実装できるからコーディングしないんだけど

自身のテーブル内で親子関係(ツリー構造)を表現するときに、こうすると良いよというサンプルが

Managing Hierarchical Data in MySQL(dev.mysql.com)で紹介されています。

ここでツリー構造を取得するSQLが次のように紹介されてます。

SELECT node.name, (COUNT(parent.name) - 1) AS depth
FROM nested_category AS node,
nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.name
ORDER BY node.lft;

単純にこれと同じクエリをPropel(1.2系)で実装するどうなるんだろうと。。

ちなみにbetweenはそのまま指定できないので他の演算子で実装しています。

$c = new Criteria();
## SELECT
$c->clearSelectColumns();
$c->addSelectColumn('node.name');
$c->addAsColumn( 'depth', '(COUNT(parent.name) -1)');
## FROM
$c->addAlias('node', self::TABLE_NAME);
$c->addAlias('parent', self::TABLE_NAME);
## WHERE
$criterion = $c->getNewCriterion('node.lft' , 'node.lft >= parent.lft', Criteria::CUSTOM);
$criterion->addAnd($c->getNewCriterion('parent.lft' , 'node.lft <= parent.rgt', Criteria::CUSTOM));
$c->add($criterion);
## GROUP BY
$c->addGroupByColumn('node.name');
## ORDER BY
$c->addAscendingOrderByColumn('node.lft');

$rs = self::doSelectRS($c);
$rs->setFetchmode( ResultSet::FETCHMODE_ASSOC );

このCriteriaをみて直感で分かる人のほうが少ないような。。と正直感じますが。。

そして、上記を実行した結果発行されたSQLは以下のとおり。

SELECT node.name, (COUNT(parent.name) -1) AS depth 
FROM ec_category node, ec_category parent 
WHERE (node.lft >= parent.lft AND node.lft <= parent.rgt) 
GROUP BY node.name 
ORDER BY node.lft;

ちなみにgetNewCriterionでCriteria::CUSTOMを指定した場合は第1引数って飾りで意味ないのかなって思っていましたが、今回のように、addAliasでテーブルを追加するときに、追加したテーブルのエイリアス名を使用して第1引数を指定しないとFROM句にエイリアスが追加されませんでした。

というわけで、node.lftとparent.leftとエイリアス名を各々で指定しています。

ただ、symfonyではsfPropelActAsNestedSetBehaviorPluginというこれらのツリー構造を実装するためのプラグインが用意されてます。symfony使うならプラグインで追加実装するのが一番のようです。

2007-09-29

[][][]DB Designer4からPropelのスキーマを作成

ウェブアプリケーションのDB設計を行うときに、何かツールを使っていますか?

私はDB Designerというツールを使うことが多いです。

このツールについてはDBDesigner 4 日本語化サイトで詳しく解説されていますし、日本語化のパッケージも配布されていますので必見です。


そして、CakePHPで、このDB Designerと連携するdbdesigner2cakeが紹介されていました。

DB DesignerとCakePHPの連携「dbdesigner2cake」

MySQLを使うのであれば確実に利用すべきではないかと思えるほどです。

では、同じようなことがsymfonyではできないのかというと、DB Designerで作成されたデータXMLからPropelのスキーマ(schema.xml)へ変換してくれるツールが公開されています。

DB Designer 4 TO Propel Schema Converter

このツールを利用すればsymfonyでもDB Designerを最大限に利用することができます。

しかし、上記ツールだと少々融通が利かないところがあります。

たとえば、packageを指定したかったり、テーブルのphpNameを指定したい場合は変換後に修正する必要があったり、日本語のコメントが正しく表示されないので削除したりと。。。

できるものなら、変換したXMLに手を加えなくて済むようにしたいなぁ。。

というわけで、上記サイトを参考に手を加えてみました。

DB DesignerからPropelのschema.xmlを作成

  • packageの指定がデータベースのCommentsで行える
  • phpNameの指定がテーブルのCommentsで行える
  • カラムのコメントは変換しない

はじめてxslを触りましたが、すごいですねぇ。。

2007-09-26

[][] symfonyウェブサイトを効率よく作成する

symfonyはアプリケーション開発としては優れています。でも、アプリケーションではなく、ウェブサイトの作成となると効率が悪くなります。それは以前id:brtRiver:20070921 で話題にしたとおりです。

と、この機能をプラグインとして作ってみました。というだけのお話。

sfBasicCMSPlugin

[][] symfonyは専用サーバーでないとインストールできない?

CakePHPダウンロードしたファイルをアップロードするだけで動くからいい」から導入を決めたという話を聞きました。

確かにそうです。そして、「symfonyでも同じことができるよ」というと「専用サーバーでないと駄目なんでしょ?」と言われました。

いえ。できます。正確に言うと

「専用サーバーであればsymfony自体のバージョン管理、開発がさらに楽になる」

ということです。

あんまりsandbox版のsymfonyの作成は知られていないようです。。

symfonyのsandboxとは? (The Definitive Guide to symfony)

お試しにはもってこいのsandbox版で配布されているsymfonyですが、自身でsandbox版を作ることができます。

つまり、ローカル環境にて作成したアプリケーションをパッケージ化できるのです。

(sf_sandboxならぬ my_sandboxですね)

しかも、

  $ symfony freeze

たったこれだけのコマンドで、symfonyのコアライブラリ類もプロジェクトにコピーしてくれます。

あとは、プロジェクトディレクトリFTPなりでサーバーに転送するだけ。

Linux系のサーバーであれば、アップロード後のパーミッション

  $ ./symfony fix-perms

で解決。

もちろん、デメリットもあります。symfony自身のアップデートの管理がサーバー上で難しいということです。

でも、これはFTPでがっつりとアップロードしたCakePHPでも同じことが言えます。

そこで、symfonyのsandbox版で開発する場合の開発、リリース手順を考えてみました。

初回開発フェーズ

  • (ローカル)pearでsymfonyをインストール
  • (ローカル)開発開始
  • (ローカル)開発完了
  • (ローカル)symfony ccキャッシュ削除(cache,logディレクトリの中身も削除しておいたほうがよいかもですね)
  • (ローカル)symfony freeze でsandbox版にプロジェクトを変更
  • (ローカル)FTPなりでサーバーにアップロード
  • (サーバー)symfony fix-perms でパーミッション修正
  • (サーバー)symfony clear-controllers で製品環境以外のコントローラーを削除

で、運用開始。

追加開発フェーズ

  • (ローカル)symfony unfreeze でsandbox版から通常版に戻す
  • (ローカル)追加開発開始
  • (ローカル)追加開発終了
  • (ローカル)FTPで開発分の差分をアップロード
  • (サーバー)symfony fix-perms
  • (サーバー)symfony cc

で、開発終了

運用フェーズ(symfonyのバージョンアップ対応)

  • (ローカル)pear upgrade symfony/symfony でsymfonyをアップグレード
  • (ローカル)symfony unfreeze でアップグレードしたsymfonyをプロジェクトにコピー
  • (ローカル)FTPでlibディレクトリのsymfonyとdataディレクトリのsymfonyをアップロード
  • (サーバー)symfony cc
  • (サーバー)symfony -V でアップグレードされたのを確認。。

で、バージョンアップ完了

1.0系のバージョンアップであればバグFIXが中心のためこのような対応でも問題は起こりにくいはずです。(絶対とはいえませんが)

もちろん、アップロード中にアクセスされたら困るとか(設定ファイルで制御できるのですが)配慮すべき手順はありますが、こんな感じでできますよーということが伝わればいいかなと。

どうも、symfonyは敷居が高いように思われますが、意外と低いんですというお話。

問題は他のフレームワークに比べてオーバーヘッドが。。。とかですが、それはキャッシュ機能なりを(ry

2007-09-24

[][] 確認画面があるアドミンジェネレータ

symfonyのアドミンジェネレータはとても便利です。設定ファイルでも制御できるしコードを上書きすることもできるしと慣れると非常に便利です。

しかし、確認画面という概念を持ち合わせていない設計のため、確認画面が必要な場合はテンプレートを用意し、確認画面用にアクションを定義する必要があります。

ref:AdminGeneratorに確認画面を追加する(symfonyで開発日記)

でも、毎回コーディングするのは大変です。

それに、symfonyは拡張性にすぐれているので、自前のジェネレータで対応できるかも。

ということで、ほそぼそとプラグインを作ってみました。

インストール方法、使用方法については以下でどうぞ。

確認画面があるアドミンジェネレータ

今日一日で作ったので不具合あるかもしれません。気づいた点がある場合は報告いただけると幸いです。

2007-09-21

[][] symfonyで静的ページ中心のウェブサイトを運用したい

正直、「symfony使わないのが一番じゃない?」って声も聞こえそうなタイトルになっていますが。。。

そういう落ちではなく、やりたいことは次のこと

  • symfonyで開発したアプリケーションに静的なページを追加したい
  • symfonyのレイアウトキャッシュコンポーネント、パーシャル。。。などをテンプレートで使いたい
    • メニューやパンくずでパーシャルを、ニュース記事一覧でコンポーネントを使いたいんだ!
  • indexSuccess.phpというファイル名はアプリケーション開発のときだけにしたい。。
    • index.htmlとかsample.htmlのようにしたいよ!
  • テンプレートも階層構造にしたい
    • /html/company/develop/index.htmlみたいな

大変かなと思ったら意外と簡単な方法でできることに気づいたのでメモ。詳しいことと実装は以下でどうぞ。

これにsmartyプラグインを組み合わせるとデザイナさんでも管理できるだろうし、テンプレートのディレクトリを一箇所にまとめられたりと何かと便利な予感。

2007-09-20

2007-09-08

[][]symfony キャンプ 2007

どうもキャンプといわれると「ビリーズブートキャンプ」しか思い浮かばないのですが、(それはさておき)symfonyを開発・メンテナンスしているSensioがSymfonyCampというイベントを開催し、そのときに行ったsymfonyの今後についてのプレゼン資料が公開されています。

http://www.symfony-project.com/blog/2007/09/07/symfony-camp

新しい機能もさておき、どのようなリファクタリングを行っていくかの説明が興味深いですね。

・既にフォーラムなどで議論されていたシングルトン問題(シングルトンはsfContextだけにする)について

・各オブジェクトの依存性を低くするために用意するsfEventDispatcherの説明

ちょっとしたデザインパターン入門のような内容です。

資料の中ではsfUserオブジェクトのcultureが変更された場合に自動的にsfI18Nの指定したコールバック(listenToChangeCultureEvent)が呼び出されるというイベントドリブンな手続きについて説明がされています。

// sfUser
$event = new sfEvent($this, 'user.change_culture', array('culture' => $culture));
$dispatcher->notify($event);
// sfI18N
$callback = array($this, 'listenToChangeCultureEvent');
$dispatcher->connect('user.change_culture', $callback);

同じデザインパターンの実装例としてPEARのEvent_Dispatcherがあります。このパッケージを使って開発したことがあるのですが、結構お勧めです。既に作成したオブジェクトに新しい機能を実装する場合にお互いの存在を気にしないで済みますからね。

2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2012 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2013 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2014 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2015 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2016 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |