Ethnaを業務で使うために(2) ディレクトリ構造の変更
「Ethnaを業務で使うために(1) 雛形の準備 - maru.cc@はてな」の続きです。
前回は、大枠の設置をしたので、今回は少し進めて、ディレクトリ構造の整理を行います。
大きく分けて次の3つの作業を行います。
- AppManagerの作成されるディレクトリの場所を変更
- AppObjectの作成されるディレクトリの場所を変更
- テスト関連のファイルが作成されるディレクトリの変更
※シェルコマンドは、特に明記していなければ、プロジェクトのルート(ethna.shの置いてあるディレクトリ)で発行したものとします。
$ cd /path/to/common/ $ ls app bin etc ethna.sh htdocs htdocs.ssl lib locale log schema skel template test tmp
AppManager、AppObjectの作成されるディレクトリの場所を変更
これから、アプリを作成する上で、AppManagerは必須になってくるクラスファイルです。
AppManagerには、DB操作を含めたビジネスロジックを記述することになります。
AppObjectは、使いにくいと評判(?)で、使わない場合には、この作業は必要ありませが、AppManagerとほぼ同じ作業なのでまとめて書きます。
AppManagerや、AppObjectのファイルは、デフォルトでは、app以下に作成されるようになっています。
例)
$ sh ethna.sh add-app-manager test file generated [/path/to/common/lib/Ethna/skel/skel.app_manager.php -> /path/to/common/app/Mm_TestManager.php] app-manager script(s) successfully created [/path/to/common/app/Mm_TestManager.php]
これだと、AppManagerが増えてきたときに、Common_Controller.phpなどに混ざり、作業がしにくくなってしまいます。
ですので、app/manager/ ディレクトリを新規に作成し、そちらに AppManagerを全て置くようにしてみます。
AppObjcetについては、app/manager/object に置くようにします。
※このファイルは確認なので消しておいてください。
Generator_AppManagerの拡張
今後、作成されるファイルを全て、手動で動かしてもいいのですが、それだと移動漏れや、いちいち作業が発生するのは、めんどくさいので、Generatorを拡張します。
pluginディレクトリ内に、Generatorディレクトリを作成します。
$ mkdir app/plugin/Generator
app/plugin/Generator内に以下のファイルを作成します。
Common_Plugin_Generator_AppManager.php
<?php // vim: foldmethod=marker /** * Common_Plugin_Generator_AppManager.php * * @author * @license http://www.opensource.org/licenses/bsd-license.php The BSD License * @package Ethna * @version $Id: $ */ // {{{ Common_Plugin_Generator_AppManager /** * スケルトン生成クラス * * @author * @access public * @package Ethna */ class Common_Plugin_Generator_AppManager extends Ethna_Plugin_Generator { /** * アプリケーションマネージャのスケルトンを生成する * * @access public * @param string $manager_name アプリケーションマネージ名 * @return bool true:成功 false:失敗 */ function generate($manager_name, $skelton = null) { $manager_id = preg_replace('/_(.)/e', "strtoupper('\$1')", ucfirst($manager_name)); $app_dir = $this->ctl->getDirectory('manager'); $app_path = ucfirst($this->ctl->getAppId()) . '_' . $manager_id .'Manager.php'; $macro = array(); $macro['project_id'] = $this->ctl->getAppId(); $macro['app_path'] = $app_path; $macro['app_manager'] = ucfirst($this->ctl->getAppId()) . '_' . $manager_id; $user_macro = $this->_getUserMacro(); $macro = array_merge($macro, $user_macro); $path = "$app_dir/$app_path"; Ethna_Util::mkdir(dirname($path), 0755); if (file_exists($path)) { printf("file [%s] already exists -> skip\n", $path); } else if ($this->_generateFile("skel.app_manager.php", $path, $macro) == false) { printf("[warning] file creation failed [%s]\n", $path); } else { printf("app-manager script(s) successfully created [%s]\n", $path); } } } // }}} ?>
Generator_AppObjectの拡張
こちらも、AppManagerと同様に app/plugin/Generator内にファイルを作成します。
Common_Plugin_Generator_AppObject.php
<?php // vim: foldmethod=marker /** * Common_Plugin_Generator_AppObject.php * * @author * @license http://www.opensource.org/licenses/bsd-license.php The BSD License * @package Ethna * @version $Id: $ */ // {{{ Common_Plugin_Generator_AppObject /** * スケルトン生成クラス * * @author * @access public * @package Ethna */ class Common_Plugin_Generator_AppObject extends Ethna_Plugin_Generator { /** * アプリケーションオブジェクトのスケルトンを生成する * * @access public * @param string $table_name テーブル名 * @return bool true:成功 false:失敗 */ function generate($table_name) { $table_id = preg_replace('/_(.)/e', "strtoupper('\$1')", ucfirst($table_name)); $app_dir = $this->ctl->getDirectory('object'); $app_path = ucfirst($this->ctl->getAppId()) . '_' . $table_id .'.php'; $macro = array(); $macro['project_id'] = $this->ctl->getAppId(); $macro['app_path'] = $app_path; $macro['app_object'] = ucfirst($this->ctl->getAppId()) . '_' . $table_id; $user_macro = $this->_getUserMacro(); $macro = array_merge($macro, $user_macro); $path = "$app_dir/$app_path"; Ethna_Util::mkdir(dirname($path), 0755); if (file_exists($path)) { printf("file [%s] already exists -> skip\n", $path); } else if ($this->_generateFile("skel.app_object.php", $path, $macro) == false) { printf("[warning] file creation failed [%s]\n", $path); } else { printf("app-object script(s) successfully created [%s]\n", $path); } } } // }}} ?>
Common_Controllerの修正
上記をしただけでは、自動が自動で読み込まれないので、app/Common_Controller.php に追記を行います。
新規作成した app/manager、app/manager/object 内も検索してもらえるように、include_pathの変更を行います。
また、デフォルト設定よりも lib内などを先に読み込むように修正を同時に行います。
app/Common_Controller.php 16行目あたり
修正前
/** include_pathの設定(アプリケーションディレクトリを追加) */ $app = BASE . "/app"; $lib = BASE . "/lib"; ini_set('include_path', ini_get('include_path') . PATH_SEPARATOR . implode(PATH_SEPARATOR, array($app, $lib)));
修正後
/** include_pathの設定(アプリケーションディレクトリを追加) */ $app = BASE . "/app"; $lib = BASE . "/lib"; $manager = $app . "/manager"; $object = $app . "/manager/object"; ini_set('include_path', implode(PATH_SEPARATOR, array($app, $lib, $manager, $object)) . PATH_SEPARATOR . ini_get('include_path'));
アプリケーションディレクトリに追記を行います。
app/Common_Controller.php 90行目あたり
修正前
/** * @var array アプリケーションディレクトリ */ var $directory = array( 'action' => 'app/action', 'action_cli' => 'app/action_cli', (略) 'tmp' => 'tmp', 'view' => 'app/view', 'www' => 'www', );
修正後
/** * @var array アプリケーションディレクトリ */ var $directory = array( 'action' => 'app/action', 'action_cli' => 'app/action_cli', (略) 'tmp' => 'tmp', 'view' => 'app/view', 'www' => 'www', 'manager' => 'app/manager', 'object' => 'app/manager/object', );
ためしに動かしてみる
これで app/manager/ 内に新規作成時にも作ってくれるようになります。
例)
$ sh ethna.sh add-app-manager test file generated [/path/to/common/lib/Ethna/skel/skel.app_manager.php -> /path/to/common/app/manager/Mm_TestManager.php] app-manager script(s) successfully created [/path/to/common/app/manager/Mm_TestManager.php]
AppObjectも同様です。
$ sh ethna.sh add-app-object test file generated [/path/to/common/skel/skel.app_object.php -> /path/to/common/app/manager/object/Mm_Test.php] app-object script(s) successfully created [/path/to/common/app/manager/object/Mm_Test.php]
※このファイルは確認なので消しておいてください。
ついでにスケルトンの変更
AppObjectを使う場合、AppObjectは、テーブルと1対になりますが、AppManagerはビジネスロジック単位なので、テーブルと1対にならない場合があります。
なので、AppObjectを使う場合でも、AppManagerとは別に考えて作成した方がいいです。
Ethna2.3.1のデフォルトで作成される AppObjectのスケルトンファイルには、AppManagerを内包した形になっているので、実際に作業するときには邪魔になってしまう場合が多いので、そちらも修正してしまいます。
以下のファイルから、AppManagerの記述を削除します。
skel/skel.app_object.php
修正前
<?php /** * {$app_path} * * @author {$author} * @package Common * @version $Id: skel.app_object.php,v 1.3 2006/11/06 14:31:24 cocoitiban Exp $ */ /** * {$app_object}Manager * * @author {$author} * @access public * @package Common */ class {$app_object}Manager extends Ethna_AppManager { } /** * {$app_object} * * @author {$author} * @access public * @package Common */ class {$app_object} extends Ethna_AppObject { /** * プロパティの表示名を取得する * * @access public */ function getName($key) { return $this->get($key); } } ?>
修正後
<?php /** * {$app_path} * * @author {$author} * @package Common * @version $Id: skel.app_object.php,v 1.3 2006/11/06 14:31:24 cocoitiban Exp $ */ /** * {$app_object} * * @author {$author} * @access public * @package Common */ class {$app_object} extends Ethna_AppObject { /** * プロパティの表示名を取得する * * @access public */ function getName($key) { return $this->get($key); } } ?>
AppManagerのスケルトンファイルが自動で、作成されていないので、コピーしておきます。
$ cp lib/Ethna/skel/skel.app_manager.php skel/
次回
テスト関連のディレクトリ変更について書きます。
「Ethnaを業務で使うために(3) テスト関連のディレクトリ構造の変更 - maru.cc@はてな」