OSDN Git Service

- followed ini file name changes.
[ethna/ethna.git] / class / Ethna_InfoManager.php
1 <?php
2 // vim: foldmethod=marker
3 /**
4  *  Ethna_InfoManager.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_InfoManager
13 /**
14  *  Ethnaマネージャクラス
15  *
16  *  @author     Masaki Fujimoto <fujimoto@php.net>
17  *  @access     public
18  *  @package    Ethna
19  */
20 class Ethna_InfoManager extends Ethna_AppManager
21 {
22     /**#@+
23      *  @access private
24      */
25     
26     /** @var    object  Ethna_Controller    コントローラオブジェクト */
27     var $ctl;
28
29     /** @var    object  Ethna_ClassFactory  クラスファクトリオブジェクト */
30     var $class_factory;
31
32     /** @var    array   アクションスクリプト解析結果キャッシュファイル */
33     var $cache_class_list_file;
34
35     /** @var    array   アクションスクリプト解析結果キャッシュ */
36     var $cache_class_list;
37
38     /** @var    array   [属性]DBタイプ一覧 */
39     var $db_type_list = array(
40         DB_TYPE_RW      => array('name' => 'DB_TYPE_RW'),
41         DB_TYPE_RO      => array('name' => 'DB_TYPE_RO'),
42         DB_TYPE_MISC    => array('name' => 'DB_TYPE_MISC'),
43     );
44
45     /** @var    array   [属性]フォーム型一覧 */
46     var $form_type_list;
47  
48     /** @var    array   [属性]変数型一覧 */
49     var $var_type_list;
50
51     /**#@-*/
52
53     /**
54      *  Ethna_InfoManagerのコンストラクタ
55      *
56      *  @access public
57      *  @param  object  Ethna_Backend   &$backend   Ethna_Backendオブジェクト
58      */
59     function Ethna_InfoManager(&$backend)
60     {
61         $this->form_type_list = array(
62                                     FORM_TYPE_TEXT => array('name' => _et('TextBox')),
63                                     FORM_TYPE_PASSWORD  => array('name' => _et('Password')),
64                                     FORM_TYPE_TEXTAREA  => array('name' => _et('TextArea')),
65                                     FORM_TYPE_SELECT    => array('name' => _et('SelectBox')),
66                                     FORM_TYPE_RADIO     => array('name' => _et('RadioButton')),
67                                     FORM_TYPE_CHECKBOX  => array('name' => _et('CheckBox')),
68                                     FORM_TYPE_SUBMIT    => array('name' => _et('SubmitButton')),
69                                     FORM_TYPE_FILE      => array('name' => _et('File')),
70                                 );
71
72         $this->var_type_list = array(
73                                     VAR_TYPE_INT        => array('name' => _et('Integer')),
74                                     VAR_TYPE_FLOAT      => array('name' => _et('Float')),
75                                     VAR_TYPE_STRING     => array('name' => _et('String')),
76                                     VAR_TYPE_DATETIME   => array('name' => _et('Datetime')),
77                                     VAR_TYPE_BOOLEAN    => array('name' => _et('Boolean')),
78                                     VAR_TYPE_FILE       => array('name' => _et('File')),
79                                );
80
81         parent::Ethna_AppManager($backend);
82         $this->ctl =& Ethna_Controller::getInstance();
83         $this->class_factory =& $this->ctl->getClassFactory();
84
85         // アクションスクリプト解析結果キャッシュ取得
86         $this->cache_class_list_file = sprintf('%s/ethna_info_class_list',
87                                                $this->ctl->getDirectory('tmp')
88                                        );
89         if (file_exists($this->cache_class_list_file)
90          && filesize($this->cache_class_list_file) > 0) {
91             $fp = fopen($this->cache_class_list_file, 'r');
92             $s = fread($fp, filesize($this->cache_class_list_file));
93             fclose($fp);
94             $this->cache_class_list = unserialize($s);
95         }
96     }
97
98     /**
99      *  定義済みアクション一覧を取得する
100      *
101      *  @access public
102      *  @return array   アクション一覧
103      */
104     function getActionList()
105     {
106         $r = array();
107
108         // アクションスクリプトを解析する
109         $class_list = $this->_analyzeActionList();
110
111         // アクション定義エントリ一覧
112         list($manifest_action_list, $manifest_class_list) = $this->_getActionList_Manifest($class_list);
113
114         // アクション定義省略エントリ一覧
115         $implicit_action_list = $this->_getActionList_Implicit($class_list, $manifest_action_list, $manifest_class_list);
116
117         $r = array_merge($manifest_action_list, $implicit_action_list);
118         ksort($r);
119
120         // アクション定義情報補完
121         $r = $this->_addActionList($r);
122
123         return $r;
124     }
125
126     /**
127      *  定義済み遷移先一覧を取得する
128      *
129      *  @access public
130      *  @return array   遷移先一覧
131      */
132     function getForwardList()
133     {
134         $r = array();
135
136         // テンプレート/ビュースクリプトを解析する
137         $forward_list = $this->_analyzeForwardList();
138
139         // ビュー定義エントリ一覧
140         $manifest_forward_list = $this->_getForwardList_Manifest();
141
142         // ビュー定義省略エントリ一覧
143         $implicit_forward_list = $this->_getForwardList_Implicit($forward_list, $manifest_forward_list);
144
145         $r = $manifest_forward_list + $implicit_forward_list;
146         ksort($r);
147
148         return $r;
149     }
150
151     /**
152      *  ディレクトリ以下のアクションスクリプトを解析する
153      *
154      *  @access private
155      *  @param  string  $action_dir     解析対象のディレクトリ
156      *  @return array   アクションクラス定義一覧
157      */
158     function _analyzeActionList($action_dir = null)
159     {
160         $r = array();
161         $cache_update = false;
162
163         if (is_null($action_dir)) {
164             $cache_update = true;
165             $action_dir = $this->ctl->getActiondir();
166         }
167         $prefix_len = strlen($this->ctl->getActiondir());
168
169         $child_dir_list = array();
170
171         $dh = opendir($action_dir);
172         if ($dh == false) {
173             return;
174         }
175
176         $ext = $this->ctl->getExt('php');
177         while (($file = readdir($dh)) !== false) {
178             if ($file == "." || $file == "..") {
179                 continue;
180             }
181             $file = $action_dir . $file;
182
183             if (is_dir($file)) {
184                 $child_dir_list[] = $file;
185                 continue;
186             }
187
188             if (preg_match("/\.$ext\$/", $file) == 0) {
189                 continue;
190             }
191
192             $key = substr($file, $prefix_len);
193             
194             // キャッシュチェック
195             include_once $file;
196             if ($this->cache_class_list[$key]['.mtime'] >= filemtime($file)) {
197                 $class_list = $this->cache_class_list[$key];
198             } else {
199                 $class_list = $this->_analyzeActionScript($file);
200             }
201             if (is_null($class_list) == false) {
202                 $r[$key] = $class_list;
203             }
204         }
205
206         closedir($dh);
207
208         foreach ($child_dir_list as $child_dir) {
209             $tmp = $this->_analyzeActionList($child_dir . "/");
210             $r = array_merge($r, $tmp);
211         }
212
213         if ($cache_update) {
214             // キャッシュファイル更新
215             $fp = fopen($this->cache_class_list_file, 'w');
216             fwrite($fp, serialize($r));
217             fclose($fp);
218         }
219
220         return $r;
221     }
222
223     /**
224      *  アクションスクリプトを解析する
225      *
226      *  @access private
227      *  @param  string  $script ファイル名
228      *  @return array   アクションクラス定義一覧
229      */
230     function _analyzeActionScript($script)
231     {
232         $class_list = array();
233         $class_list['.mtime'] = filemtime($script);
234
235         $source = "";
236         $fp = fopen($script, 'r');
237         if ($fp == false) {
238             return null;
239         }
240         while (feof($fp) == false) {
241             $source .= fgets($fp, 8192);
242         }
243         fclose($fp);
244
245         // トークンに分割してクラス定義情報を取得
246         $token_list = token_get_all($source);
247         $state = 'T_OUT';
248         $nest = 0;
249         $method_nest = 0;
250         $current = null;
251         for ($i = 0; $i < count($token_list); $i++) {
252             $token = $token_list[$i];
253
254             if (is_string($token)) {
255                 if ($token == '{') {
256                     $nest++;
257                 } else if ($token == '}') {
258                     $nest--;
259                     if ($state == 'T_PREPARE' || $state == 'T_PERFORM') {
260                         if ($nest == $method_nest) {
261                             $state = 'T_ACTION_CLASS';
262                         }
263                     } else if ($nest == 0) {
264                         $state = 'T_OUT';
265                     }
266                 }
267                 continue;
268             }
269
270             if ($token[0] == T_CLASS) {
271                 // クラス定義開始
272                 $i += 2;
273                 $class_name = $token_list[$i][1];       // should be T_STRING
274                 if ($this->_isSubclassOf($class_name, 'Ethna_ActionClass')) {
275                     $state = 'T_ACTION_CLASS';
276                     $current = $class_name;
277                     $class_list[$current] = array('type' => 'action_class');
278                 } else if ($this->_isSubclassOf($class_name, 'Ethna_ActionForm')) {
279                     $state = 'T_ACTION_FORM';
280                     $current = $class_name;
281                     $class_list[$current] = array('type' => 'action_form');
282                 }
283                 $nest = 0;  // for safe
284             } else if ($token[0] == T_COMMENT && strncmp($token[1], "/**", 3) == 0 && is_array($token_list[$i+2]) && $token_list[$i+2][0] == T_CLASS) {
285                 // DocComment for class
286             } else if ($state == 'T_ACTION_CLASS' && $token[0] == T_FUNCTION) {
287                 $i += 2;
288                 $method_name = $token_list[$i][1];
289                 if (strcasecmp($method_name, 'prepare') == 0) {
290                     $state = 'T_PREPARE';
291                     $method_nest = $nest;
292                 } else if (strcasecmp($method_name, 'perform') == 0) {
293                     $state = 'T_PERFORM';
294                     $method_nest = $nest;
295                 }
296             } else if (($state == 'T_PREPARE' || $state == 'T_PERFORM') && $token[0] == T_RETURN) {
297                 $s = "";
298                 $n = 1;
299                 while ($token_list[$i+$n] !== ";") {
300                     $s .= is_string($token_list[$i+$n]) ? $token_list[$i+$n] : $token_list[$i+$n][1];
301                     $n++;
302                 }
303                 $key = $state == 'T_PREPARE' ? 'prepare' : 'perform';
304                 $class_list[$current]['return'][$key][] = $s;
305             }
306         }
307
308         if (count($class_list) == 0) {
309             return null;
310         }
311         return $class_list;
312     }
313
314     /**
315      *  指定されたクラス名を継承しているかどうかを返す
316      *
317      *  @access private
318      *  @param  string  $class_name     チェック対象のクラス名
319      *  @param  string  $parent_name    親クラス名
320      *  @return bool    true:継承している false:いない
321      */
322     function _isSubclassOf($class_name, $parent_name)
323     {
324         while ($tmp = get_parent_class($class_name)) {
325             if (strcasecmp($tmp, $parent_name) == 0) {
326                 return true;
327             }
328             $class_name = $tmp;
329         }
330         return false;
331     }
332
333     /**
334      *  コントローラに明示的に定義されているアクション一覧を取得する
335      *
336      *  @access private
337      *  @param  array   定義されているクラス一覧
338      *  @return array   array(アクション一覧, クラス一覧)
339      */
340     function _getActionList_Manifest($class_list)
341     {
342         $manifest_action_list = array();
343         $manifest_class_list = array();
344         foreach ($this->ctl->action as $action_name => $action) {
345             if ($action_name == '__ethna_info__') {
346                 continue;
347             }
348             $action = $this->ctl->_getAction($action_name);
349
350             $elt = array();
351             // _analyzeActionList()で取得したクラス定義データから対応関係を取得
352             foreach ($class_list as $file => $elts) {
353                 foreach ($elts as $class_name => $def) {
354                     if ($def['type'] == 'action_class' && strcasecmp($class_name, $action['class_name']) == 0) {
355                         $elt['action_class'] = $class_name;
356                         $elt['action_class_file'] = $file;
357                         $elt['action_class_info'] = $def;
358                     } else if ($def['type'] == 'action_form' && strcasecmp($class_name, $action['form_name']) == 0) {
359                         $elt['action_form'] = $class_name;
360                         $elt['action_form_file'] = $file;
361                         $elt['action_form_info'] = $def;
362                     }
363                 }
364             }
365
366             // 未定義チェック
367             if (isset($elt['action_class']) == false) {
368                 $elt['action_class'] = $action['class_name'];
369                 if (class_exists($action['class_name']) == false) {
370                     $elt['action_class_info'] = array('undef' => true);
371                 }
372             }
373             if (isset($elt['action_form']) == false && $action['form_name'] != 'Ethna_ActionForm') {
374                 $elt['action_form'] = $action['form_name'];
375                 if (class_exists($action['form_name']) == false) {
376                     $elt['action_form_info'] = array('undef' => true);
377                 }
378             }
379             $manifest_action_list[$action_name] = $elt;
380             $manifest_class_list[] = strtolower($elt['action_class']);
381         }
382
383         return array($manifest_action_list, $manifest_class_list);
384     }
385
386     /**
387      *  暗黙に定義されているアクション一覧を取得する
388      *
389      *  @access private
390      *  @param  array   $class_list             定義されているクラス一覧
391      *  @param  array   $manifest_action_list   明示的に定義済みのアクション一覧
392      *  @param  array   $manifest_class_list    明示的に定義済みのクラス一覧
393      *  @return array   array:アクション一覧
394      */
395     function _getActionList_Implicit($class_list, $manifest_action_list, $manifest_class_list)
396     {
397         $implicit_action_list = array();
398
399         foreach ($class_list as $file => $elts) {
400             foreach ($elts as $class_name => $def) {
401                 if (in_array(strtolower($class_name), $manifest_class_list)) {
402                     continue;
403                 }
404
405                 // クラス名からアクション名を取得
406                 if ($def['type'] == 'action_class') {
407                     $action_name = $this->ctl->actionClassToName($class_name);
408                     if (array_key_exists($action_name, $manifest_action_list)) {
409                         continue;
410                     }
411                     $implicit_action_list[$action_name]['action_class'] = $class_name;
412                     $implicit_action_list[$action_name]['action_class_file'] = $file;
413                     $implicit_action_list[$action_name]['action_class_info'] = $def;
414                 } else if ($def['type'] == 'action_form') {
415                     $action_name = $this->ctl->actionFormToName($class_name);
416                     if (array_key_exists($action_name, $manifest_action_list)) {
417                         continue;
418                     }
419                     $implicit_action_list[$action_name]['action_form'] = $class_name;
420                     $implicit_action_list[$action_name]['action_form_file'] = $file;
421                     $implicit_action_list[$action_name]['action_form_info'] = $def;
422                 } else {
423                     continue;
424                 }
425             }
426         }
427
428         return $implicit_action_list;
429     }
430     
431     /**
432      *  アクション定義一覧を補完する
433      *
434      *  @access private
435      *  @param  array   $action_list    取得したアクション一覧
436      *  @return array   修正後のアクション一覧
437      */
438     function _addActionList($action_list)
439     {
440         foreach ($action_list as $action_name => $action) {
441             // アクションフォームにフォーム定義情報を追加
442             $form_name = $action['action_form'];
443             if (class_exists($form_name) == false) {
444                 continue;
445             }
446             $af =& new $form_name($this->ctl);
447
448             $form = array();
449             foreach ($af->getDef() as $name => $def) {
450                 $form[$name]['required'] = $def['required'] ? 'true' : 'false';
451                 foreach (array('name', 'max', 'min', 'regexp', 'custom') as $key) {
452                     $form[$name][$key] = $def[$key];
453                 }
454                 $form[$name]['filter'] = str_replace(",", "\n", $def['filter']);
455                 $form[$name]['form_type'] = $this->getAttrName('form_type', $def['form_type']);
456                 $form[$name]['type_is_array'] = is_array($def['type']);
457                 $form[$name]['type'] = $this->getAttrName('var_type', is_array($def['type'])
458                                      ? $def['type'][0] : $def['type']);
459             }
460             $action['action_form_info']['form'] = $form;
461             $action_list[$action_name] = $action;
462         }
463
464         return $action_list;
465     }
466
467     /**
468      *  ディレクトリ以下のテンプレートを解析する
469      *
470      *  @access private
471      *  @param  string  $action_dir     解析対象のディレクトリ
472      *  @return array   遷移定義一覧
473      */
474     function _analyzeForwardList($template_dir = null)
475     {
476         $r = array();
477
478         if (is_null($template_dir)) {
479             $template_dir = $this->ctl->getTemplatedir();
480         }
481         $prefix_len = strlen($this->ctl->getTemplatedir());
482
483         $child_dir_list = array();
484
485         $dh = opendir($template_dir);
486         if ($dh == false) {
487             return;
488         }
489
490         $ext = $this->ctl->getExt('tpl');
491         while (($file = readdir($dh)) !== false) {
492             if ($file == "." || $file == "..") {
493                 continue;
494             }
495             $file = $template_dir . '/' . $file;
496
497             if (is_dir($file)) {
498                 $child_dir_list[] = $file;
499                 continue;
500             }
501
502             if (preg_match("/\.$ext\$/", $file) == 0) {
503                 continue;
504             }
505
506             $tpl = substr($file, $prefix_len);
507             $r[] = $this->ctl->forwardPathToName($tpl);
508         }
509
510         closedir($dh);
511
512         foreach ($child_dir_list as $child_dir) {
513             $tmp = $this->_analyzeForwardList($child_dir);
514             $r = array_merge($r, $tmp);
515         }
516
517         return $r;
518     }
519
520     /**
521      *  コントローラに明示的に定義されている遷移先一覧を取得する
522      *
523      *  @access private
524      *  @return array   ビュー一覧
525      */
526     function _getForwardList_Manifest()
527     {
528         $manifest_forward_list = array();
529         foreach ($this->ctl->forward as $forward_name => $forward) {
530             if ($forward_name == '__ethna_info__') {
531                 continue;
532             }
533
534             $elt = array();
535             $elt['template_file'] = $this->ctl->_getForwardPath($forward_name);
536             if (file_exists(sprintf("%s/%s", $this->ctl->getTemplatedir(), $elt['template_file'])) == false) {
537                 $elt['template_file_info'] = array('undef' => true);
538             }
539
540             $elt['view_class'] = $this->ctl->getViewClassName($forward_name);
541             if ($elt['view_class'] == 'Ethna_ViewClass') {
542                 $elt['view_class'] = null;
543             } else if (class_exists($elt['view_class']) == false) {
544                 $elt['view_class_info'] = array('undef' => true);
545             }
546
547             if (isset($forward['view_path']) && $forward['view_path']) {
548                 $elt['view_path'] = $forward['view_path'];
549             } else if ($this->_isSubclassOf($elt['view_class'], 'Ethna_ViewClass')) {
550                 $elt['view_class_file'] = $this->ctl->getDefaultViewPath($forward_name);
551             } else {
552                 foreach ($this->cache_class_list as $file => $elts) {
553                     foreach ($elts as $name => $def) {
554                         if (strcasecmp($elt['view_class'], $name) == 0) {
555                             $elt['view_class_file'] = $file;
556                             break 2;
557                         }
558                     }
559                 }
560             }
561
562             $manifest_forward_list[$forward_name] = $elt;
563         }
564
565         return $manifest_forward_list;
566     }
567
568     /**
569      *  暗黙に定義されているビュー一覧を取得する
570      *
571      *  @access private
572      *  @param  array   $forward_list           定義されている遷移名一覧
573      *  @param  array   $manifest_forward_list  明示的に定義済みのビュー一覧
574      *  @return array   array:ビュー一覧
575      */
576     function _getForwardList_Implicit($forward_list, $manifest_forward_list)
577     {
578         $implicit_forward_list = array();
579         $manifest_forward_name_list = array_keys($manifest_forward_list);
580
581         foreach ($forward_list as $forward_name) {
582             //
583             //    エラー用のテンプレートはEthnaのデフォルトの命名規則に
584             //    従っていないため、暫定修正。
585             //    TODO: 2.5.0 の最終版が出るまでにこの点は改善される予定
586             //    なので、改善され次第このif文は削除すべきである。
587             //
588             if (preg_match('/error[403|404|500]/', $forward_name)) {
589                 continue;
590             }
591
592             if (in_array($forward_name, $manifest_forward_name_list)) {
593                 continue;
594             }
595
596             $elt = array();
597             $elt['template_file'] = $this->ctl->_getForwardPath($forward_name);
598             $elt['view_class'] = $this->ctl->getViewClassName($forward_name);
599             if ($elt['view_class'] == 'Ethna_ViewClass') {
600                 $elt['view_class'] = null;
601             } else if (class_exists($elt['view_class']) == false) {
602                 $elt['view_class'] = null;
603             } else {
604                 $elt['view_class_file'] = $this->ctl->getDefaultViewPath($forward_name);
605             }
606
607             $implicit_forward_list[$forward_name] = $elt;
608         }
609
610         return $implicit_forward_list;
611     }
612
613     /**
614      *  Ethnaの設定一覧を取得する
615      *
616      *  @access public
617      *  @return array   設定一覧を格納した配列
618      *  @todo   respect access controll
619      */
620     function getConfiguration()
621     {
622         $r = array();
623
624         // core
625         $elts = array();
626         $elts[_et('Application ID')] = $this->ctl->getAppId();
627         $elts[_et('Application URL')] = $this->ctl->getURL();
628         $elts[_et('Ethna Version')] = ETHNA_VERSION;
629         $elts[_et('Ethna Base Directory')] = ETHNA_BASE;
630         $r['Core'] = $elts;
631
632         // class
633         $elts = array();
634         $elts[_et('Backend')] = $this->class_factory->getObjectName('backend');
635         $elts[_et('ClassFactory')] = $this->class_factory->getObjectName('class');
636         $elts[_et('Config')] = $this->class_factory->getObjectName('config');
637         $elts['DB'] = $this->class_factory->getObjectName('db');
638         $elts[_et('Error')] = $this->class_factory->getObjectName('error');
639         $elts[_et('Form')] = $this->class_factory->getObjectName('form');
640         $elts[_et('Log')] = $this->class_factory->getObjectName('logger');
641         $elts['i18n'] = $this->class_factory->getObjectName('i18n');
642         $elts[_et('Plugin')] = $this->class_factory->getObjectName('plugin');
643         $elts[_et('Session')] = $this->class_factory->getObjectName('session');
644         $elts['SQL'] = $this->class_factory->getObjectName('sql');
645         $elts[_et('View')] = $this->class_factory->getObjectName('view');
646         $r[_et('Class')] = $elts;
647
648         // DB
649         $elts = array();
650         $db_list = array();
651         foreach ($this->ctl->db as $key => $db) {
652             if ($key == "") {
653                 $tmp = '$db';
654             } else {
655                 $tmp = sprintf('$db_%s', $key);
656             }
657             $elts[$tmp] = $this->getAttrName('db_type', $db);
658             $db_list[$key] = $tmp;
659         }
660         $r[_et('DB Type')] = $elts;
661
662         // DSN
663         $elts = array();
664         foreach ($db_list as $key => $name) {
665             $config_key = "dsn";
666             if ($key != "") {
667                 $config_key .= "_$key";
668             }
669             $dsn = $this->config->get($config_key);
670             if ($dsn) {
671                 $elts[$name] = implode("\n", to_array($dsn));
672             }
673         }
674         $r['DSN'] = $elts;
675
676         // directory
677         $elts = array();
678         $elts[_et('Application')] = $this->ctl->getBasedir();
679         $elts[_et('Action')] = $this->ctl->getActiondir();
680         $elts[_et('View')] = $this->ctl->getViewdir();
681         $elts[_et('Filter')] = $this->ctl->getDirectory('filter');
682         $elts[_et('Plugin')] = $this->ctl->getDirectory('plugin');
683         $elts[_et('Template')] = $this->ctl->getTemplatedir();
684         $elts[_et('Template Cache')] = $this->ctl->getDirectory('template_c');
685         $elts[_et('Smarty Plugin')] = implode(',', $this->ctl->getDirectory('plugins'));
686         $elts[_et('Configuration File')] = $this->ctl->getDirectory('etc');
687         $elts[_et('Locale')] = $this->ctl->getDirectory('locale');
688         $elts[_et('Logging')] = $this->ctl->getDirectory('log');
689         $elts[_et('Temporary File')] = $this->ctl->getDirectory('tmp');
690         $r[_et('Directory')] = $elts;
691
692         // ext
693         $elts = array();
694         $elts[_et('Template')] = $this->ctl->getExt('tpl');
695         $elts[_et('PHP Script')] = $this->ctl->getExt('php');
696         $r[_et('File Extention')] = $elts;
697
698         // filter
699         $elts = array();
700         $n = 1;
701         foreach ($this->ctl->filter as $filter) {
702             $key = sprintf(_et('Filter(%d)'), $n);
703             if (class_exists($filter)) {
704                 $elts[$key] = $filter;
705                 $n++;
706             }
707         }
708         $r[_et('Filter')] = $elts;
709
710         // manager
711         $elts = array();
712         foreach ($this->ctl->getManagerList() as $key => $manager) {
713             $name = sprintf('$%s', $key);
714             $elts[$name] = $this->ctl->getManagerClassName($manager);
715         }
716         $r[_et('Application Manager')] = $elts;
717
718         return $r;
719     }
720
721     /**
722      *  プラグインの一覧を取得する
723      *
724      *  @access public
725      *  @return array   設定一覧を格納した配列
726      *  @todo   respect access controll
727      */
728     function getPluginList()
729     {
730         $r = array();
731         $plugin = $this->ctl->getPlugin();
732         foreach ($plugin->searchAllPluginType() as $type) {
733             $plugin->searchAllPluginSrc($type);
734             if (isset($plugin->src_registry[$type])) {
735                 $elts = array();
736                 foreach ($plugin->src_registry[$type] as $name => $src) {
737                     if (empty($src)) {
738                         continue;
739                     }
740                     $elts[$name] = $src[2];
741                 }
742                 ksort($elts);
743                 $r[$type] = $elts;
744             }
745         }
746         ksort($r);
747         return $r;
748     }
749 }
750 // }}}
751