OSDN Git Service

3a3b738190c2687d97db7a3af2ed8e274f010565
[ethna/ethna.git] / class / Plugin / Generator / Project.php
1 <?php
2 // vim: foldmethod=marker
3 /**
4  *  Project.php
5  *
6  *  @author     Masaki Fujimoto <fujimoto@php.net>
7  *  @license    http://www.opensource.org/licenses/bsd-license.php The BSD License
8  *  @package    Ethna
9  *  @version    $Id$
10  */
11
12 // {{{ Ethna_Plugin_Generator_Project
13 /**
14  *  スケルトン生成クラス
15  *
16  *  @author     Masaki Fujimoto <fujimoto@php.net>
17  *  @access     public
18  *  @package    Ethna
19  */
20 class Ethna_Plugin_Generator_Project extends Ethna_Plugin_Generator
21 {
22     /**
23      *  プロジェクトスケルトンを生成する
24      *
25      *  @access public
26      *  @param  string  $id         プロジェクトID
27      *  @param  string  $basedir    プロジェクトベースディレクトリ
28      *  @param  string  $skeldir    スケルトンディレクトリ。これが指定されると、そこにある
29      *                              ファイルが優先される。また、ETHNA_HOME/skel にないもの
30      *                              も追加してコピーする 
31      *  @param  string  $locale     ロケール名
32      *                              (ロケール名は、ll_cc の形式。ll = 言語コード cc = 国コード)
33      *  @param  string  $encoding   プロジェクトで使用するエンコーディング 
34      *  @return bool    true:成功   Ethna_Error:失敗
35      */
36     function generate($id, $basedir, $skeldir, $locale, $encoding)
37     {
38         $dir_list = array(
39             array("app", 0755),
40             array("app/action", 0755),
41             array("app/action_cli", 0755),
42             array("app/action_xmlrpc", 0755),
43             array("app/filter", 0755),
44             array("app/plugin", 0755),
45             array("app/plugin/Filter", 0755),
46             array("app/plugin/Validator", 0755),
47             array("app/plugin/Smarty", 0755),
48             array("app/view", 0755),
49             array("app/test", 0755),
50             array("bin", 0755),
51             array("etc", 0755),
52             array("lib", 0755),
53             array("locale", 0755),
54             array("locale/$locale", 0755),
55             array("locale/$locale/LC_MESSAGES", 0755),
56             array("log", 0777),
57             array("schema", 0755),
58             array("skel", 0755),
59             array("template", 0755),
60             array("template/$locale", 0755),
61             array("tmp", 0777),
62             array("www", 0755),
63             array("www/css", 0755),
64             array("www/js", 0755),
65         );
66
67         // double check.
68         $id = strtolower($id);
69         $r = Ethna_Controller::checkAppId($id);
70         if (Ethna::isError($r)) {
71             return $r;
72         }
73
74         $basedir = sprintf("%s/%s", $basedir, $id);
75
76         // ディレクトリ作成
77         if (is_dir($basedir) == false) {
78             // confirm
79             printf("creating directory ($basedir) [y/n]: ");
80             flush();
81             $fp = fopen("php://stdin", "r");
82             $r = trim(fgets($fp, 128));
83             fclose($fp);
84             if (strtolower($r) != 'y') {
85                 return Ethna::raiseError('aborted by user');
86             }
87
88             if (mkdir($basedir, 0775) == false) {
89                 return Ethna::raiseError('directory creation failed');
90             }
91         }
92         foreach ($dir_list as $dir) {
93             $mode = $dir[1];
94             $dir = $dir[0];
95             $target = "$basedir/$dir";
96             if (is_dir($target)) {
97                 printf("%s already exists -> skipping...\n", $target);
98                 continue;
99             }
100             if (mkdir($target, $mode) == false) {
101                 return Ethna::raiseError('directory creation failed');
102             } else {
103                 printf("project sub directory created [%s]\n", $target);
104             }
105             if (chmod($target, $mode) == false) {
106                 return Ethna::raiseError('chmod failed');
107             }
108         }
109
110         // スケルトンファイル作成
111         $macro['ethna_version'] = ETHNA_VERSION;
112         $macro['application_id'] = strtoupper($id);
113         $macro['project_id'] = ucfirst($id);
114         $macro['project_prefix'] = $id;
115         $macro['basedir'] = realpath($basedir);
116         $macro['locale'] = $locale;
117         $macro['client_enc'] = $encoding;
118
119         $macro['action_class'] = '{$action_class}';
120         $macro['action_form'] = '{$action_form}';
121         $macro['action_name'] = '{$action_name}';
122         $macro['action_path'] = '{$action_path}';
123         $macro['forward_name'] = '{$forward_name}';
124         $macro['view_name'] = '{$view_name}';
125         $macro['view_path'] = '{$view_path}';
126
127         $user_macro = $this->_getUserMacro();
128         $default_macro = $macro;
129         $macro = array_merge($macro, $user_macro);
130
131         //  select locale file.
132         $locale_file = (file_exists(ETHNA_BASE . "/skel/locale/$locale/ethna_sysmsg.ini"))
133                      ? "locale/$locale/ethna_sysmsg.ini"
134                      : 'locale/ethna_sysmsg.default.ini';
135
136         $realfile_maps = array(
137             $locale_file    => "$basedir/locale/$locale/LC_MESSAGES/ethna_sysmsg.ini",
138             "www.index.php" => "$basedir/www/index.php",
139             "www.info.php"  => "$basedir/www/info.php",
140             "www.unittest.php" => "$basedir/www/unittest.php",
141             "www.xmlrpc.php" => "$basedir/www/xmlrpc.php",
142             "www.css.ethna.css" => "$basedir/www/css/ethna.css",
143             "dot.ethna" => "$basedir/.ethna",
144             "app.controller.php" => sprintf("$basedir/app/%s_Controller.php", $macro['project_id']),
145             "app.error.php" => sprintf("$basedir/app/%s_Error.php", $macro['project_id']),
146             "app.actionclass.php" => sprintf("$basedir/app/%s_ActionClass.php", $macro['project_id']),
147             "app.actionform.php" => sprintf("$basedir/app/%s_ActionForm.php", $macro['project_id']),
148             "app.viewclass.php" => sprintf("$basedir/app/%s_ViewClass.php", $macro['project_id']),
149             "app.action.default.php" => "$basedir/app/action/Index.php",
150             "app.plugin.filter.default.php" => sprintf("$basedir/app/plugin/Filter/%s_Plugin_Filter_ExecutionTime.php", $macro['project_id']),
151             "app.view.default.php" => "$basedir/app/view/Index.php",
152             "app.unittest.php" => sprintf("$basedir/app/%s_UnitTestManager.php", $macro['project_id']),
153             "app.url_handler.php" => sprintf("$basedir/app/%s_UrlHandler.php", $macro['project_id']),
154             "etc.ini.php" => sprintf("$basedir/etc/%s-ini.php", $macro['project_prefix']),
155             "template.index.tpl" => sprintf("$basedir/template/$locale/index.tpl"),
156         );
157
158         $skelfile_maps = array(
159             "skel.action.php" => sprintf("$basedir/skel/skel.action.php"),
160             "skel.action_cli.php" => sprintf("$basedir/skel/skel.action_cli.php"),
161             "skel.action_test.php" => sprintf("$basedir/skel/skel.action_test.php"),
162             "skel.app_object.php" => sprintf("$basedir/skel/skel.app_object.php"),
163             "skel.entry_www.php" => sprintf("$basedir/skel/skel.entry_www.php"),
164             "skel.entry_cli.php" => sprintf("$basedir/skel/skel.entry_cli.php"),
165             "skel.view.php" => sprintf("$basedir/skel/skel.view.php"),
166             "skel.template.tpl" => sprintf("$basedir/skel/skel.template.tpl"),
167             "skel.view_test.php" => sprintf("$basedir/skel/skel.view_test.php"),
168         );
169
170         //    also copy user defined skel file.
171         if (!empty($skeldir)) {
172             $handle = opendir($skeldir);
173             while (($file = readdir($handle)) !== false) {
174                 if (is_dir(realpath("$skeldir/$file"))) {
175                     continue;
176                 }
177                 if (array_key_exists($file, $skelfile_maps) == false) {
178                     $skelfile_maps[$file] = sprintf("$basedir/skel/$file");
179                 }
180             }
181         }
182
183         $real_r = $this->_generate($realfile_maps, $macro, $skeldir);
184         if (Ethna::isError($real_r)) {
185             return $real_r;
186         }
187
188         //  skelファイルにはエンコーディングマクロは適用しない
189         //  skel.template.tpl は、add-[view|template]時に適用させるため。
190         unset($default_macro['client_enc']);
191         $skel_r = $this->_generate($skelfile_maps, $default_macro, $skeldir);
192         if (Ethna::isError($skel_r)) {
193             return $skel_r;
194         }
195
196         return true;
197     }
198
199     /**
200      *  実際のプロジェクトスケルトンを生成処理を行う
201      *
202      *  @access private 
203      *  @param  string  $maps       スケルトン名と生成されるファイルの配列 
204      *  @param  string  $macro      適用マクロ 
205      *  @param  string  $skeldir    スケルトンディレクトリ。これが指定されると、そこにある
206      *                              ファイルが優先される。また、ETHNA_HOME/skel にないもの
207      *                              も追加してコピーする 
208      *  @return bool     true:成功  Ethna_Error:失敗
209      */
210  
211     function _generate($maps, $macro, $skeldir)
212     {
213         foreach ($maps as $skel => $realfile) {
214             if (!empty($skeldir) && file_exists("$skeldir/$skel")) {
215                 $skel = "$skeldir/$skel";
216             }
217             if ($this->_generateFile($skel, $realfile, $macro) == false) {
218                 return Ethna::raiseError("generating files failed");
219             }
220         }
221         return true;
222     }
223 }
224 // }}}
225
226 ?>