OSDN Git Service

9f38f26d935c4868cce5cb7c13334d3fa9edbe0f
[magic3/magic3.git] / include / manager / launchManager.php
1 <?php
2 /**
3  * 起動制御マネージャー
4  *
5  * コンテナ(フレームコンテナ、ウィジェットコンテナ、ウィジェット内サブコンテナ)の起動を行う。
6  * このマネージャーでユーザのアクセス制御は行わない。
7  *
8  * PHP versions 5
9  *
10  * LICENSE: This source file is licensed under the terms of the GNU General Public License.
11  *
12  * @package    Magic3 Framework
13  * @author     平田直毅(Naoki Hirata) <naoki@aplo.co.jp>
14  * @copyright  Copyright 2006-2016 Magic3 Project.
15  * @license    http://www.gnu.org/copyleft/gpl.html  GPL License
16  * @version    SVN: $Id$
17  * @link       http://www.magic3.org
18  */
19 require_once(M3_SYSTEM_INCLUDE_PATH . '/common/core.php');
20
21 class LaunchManager extends Core
22 {
23         private $loadPath;                                                              // クラス検索ロード用のパス
24         const DEFAULT_RSS_CLASS_PREFIX = 'rss_';                // RSS実行用クラスの先頭文字列
25         
26         /**
27          * コンストラクタ
28          */
29         function __construct()
30         {
31                 // 親クラスを呼び出す
32                 parent::__construct();
33                 
34                 $this->loadPath = array();                                                              // クラス検索ロード用のパス
35         }
36
37         /**
38          * プログラムを実行
39          *
40          * @param string $filepath              呼び出し元ファイルのフルパス。通常は「__FILE__」。OSによってパスの表現が違うので注意。
41          */
42         function go($filepath = '')
43         {
44                 global $gEnvManager;
45                 global $gRequestManager;
46
47                 // ルートから$filepathへの相対パスで「FrameContainer.php」の先頭につける
48                 // サフィックスを作成する
49                 // 例) 相対パスが「admin/index.php」のとき「admin_index」
50                 if ($filepath == ''){
51                         $basename = basename($_SERVER["PHP_SELF"], '.php');
52                 } else {
53                         // ルートまでのパスを削除
54                         $path = str_replace(M3_SYSTEM_ROOT_PATH, '', $filepath);
55                         $path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
56                         $path = trim($path, '/');
57                         //$pathArray = split('/', $path);
58                         $pathArray = explode('/', $path);
59                         $basename = '';
60                         for ($i = 0; $i < count($pathArray); $i++){
61                                 if ($i == 0){
62                                         $basename .= $pathArray[$i];
63                                 } else {
64                                         //$basename .= ucfirst($pathArray[$i]);
65                                         $basename .= ('_' . $pathArray[$i]);
66                                 }
67                         }
68                         $basename = basename($basename, '.php');
69                 }
70                 
71                 // PC用URLかどうかを設定(管理画面はPC用URLとしない)
72                 $isPcSite = true;
73                 if (strStartsWith($basename, 'admin_')) $isPcSite = false;
74                 $gEnvManager->setIsPcSite($isPcSite);
75                 
76                 // サーバ接続かどうかを設定
77                 if ($basename == basename(M3_FILENAME_SERVER_CONNECTOR, '.php')) $gEnvManager->setIsServerConnector(true);
78                 
79                 // ページIDを設定
80                 $gEnvManager->setCurrentPageId($basename);
81
82                 // アクセスポイントを設定
83                 $gEnvManager->setAccessPath(str_replace('_', '/', $basename));
84                 
85                 // ファイル名から、コンテナクラスファイル取り込み
86                 require_once($gEnvManager->getContainerPath() . '/' . $basename . 'FrameContainer.php');
87                 
88                 // コンテナクラスを起動
89                 $class = $basename . 'FrameContainer';
90                 $mainContainer = new $class();
91                 $mainContainer->process($gRequestManager);
92         }
93         /**
94          * ウィジェットプログラムを実行
95          *
96          * @param string $filepath              呼び出し元ファイルのフルパス。通常は「__FILE__」。OSによってパスの表現が違うので注意。
97          */
98         function goWidget($filepath)
99         {
100                 global $gEnvManager;
101                 global $gRequestManager;
102                 static $pathArray = array();            // 呼び出し元を保存する
103
104                 // 実行コマンドを取得
105                 $cmd = $gRequestManager->trimValueOf(M3_REQUEST_PARAM_OPERATION_COMMAND);
106                 
107                 $basename = basename($filepath, '.php');
108                 $widgetId = $gEnvManager->getCurrentWidgetId();// ウィジェットID
109                 
110                 // このメソッドにアクセスしたウィジェットのパスをみて、管理画面へのアクセスかどうかを判断
111                 $pathArray = explode(DIRECTORY_SEPARATOR, $filepath);
112                 $pathCount = count($pathArray);
113                 $accessAdmin = false;
114                 
115                 // ウィジェットの種別を設定
116                 $gEnvManager->setIsSubWidget(false);                    // 通常ウィジェットで起動
117                 
118                 if ($gEnvManager->getIsMobileSite()){           // 携帯サイトへのアクセスのとき
119                         // 管理画面へのアクセスかどうかチェック
120                         if ($pathArray[$pathCount -2] == 'admin' && $pathArray[$pathCount -3] == $widgetId){
121                                 $accessAdmin = true;
122                         }
123                         // 携帯用ウィジェットのウィジェットIDは、「m/xxxxxx」の形式
124                         // ウィジェットIDを変換
125                         $widgetId = str_replace('/', '_', $widgetId);
126                         
127                         // コンテナクラス名作成
128                         if ($cmd == M3_REQUEST_CMD_RSS){                // RSS配信のとき
129                                 $containerClass = self::DEFAULT_RSS_CLASS_PREFIX . $widgetId . 'WidgetContainer';               // デフォルトで起動するコンテナクラス名「ウィジェットID + WidgetContainer」
130                                 $containerPath = $gEnvManager->getCurrentWidgetContainerPath() . '/' . $containerClass . '.php';
131                         } else if ($accessAdmin){
132                                 $containerClass = 'admin_' . $widgetId . 'WidgetContainer';             // デフォルトで起動するコンテナクラス名「admin_ + ウィジェットID + WidgetContainer」
133                         } else {
134                                 $containerClass = $widgetId . 'WidgetContainer';                // デフォルトで起動するコンテナクラス名「ウィジェットID + WidgetContainer」
135                                 $containerPath = $gEnvManager->getCurrentWidgetContainerPath() . '/' . $containerClass . '.php';
136                         }
137                         if (file_exists($containerPath)){
138                                 require_once($containerPath);
139                         } else {
140                                 echo 'file not found error: ' . $containerPath;
141                         }
142                         // コンテナクラスを起動
143                         $widgetContainer = new $containerClass();
144                         $gEnvManager->setCurrentWidgetObj($widgetContainer);                            // 実行するウィジェットコンテナオブジェクトを登録
145                         $widgetContainer->process($gRequestManager);
146                         $gEnvManager->setCurrentWidgetObj(null);
147                 } else {                        // PC用の画面からのアクセスまたは管理画面へのアクセス
148                         // インナーウィジェットのチェック
149                         $isIWidget = false;
150                         if ($pathArray[$pathCount -4] == 'iwidgets' && $pathArray[$pathCount -2] == 'admin'){           // インナーウィジェット管理者画面
151                                 $isIWidget = true;
152                                 $widgetId = $pathArray[$pathCount -3];          // インナーウィジェットID
153                                 $accessAdmin = true;
154                         } else if ($pathArray[$pathCount -3] == 'iwidgets'){    // インナーウィジェット通常画面
155                                 $isIWidget = true;
156                                 $widgetId = $pathArray[$pathCount -2];// インナーウィジェットID
157                         } else if ($pathArray[$pathCount -3] == $widgetId && $pathArray[$pathCount -2] == 'admin'){             // PC用ウィジェット管理画面
158                                 $accessAdmin = true;
159                         } else if ($pathArray[$pathCount -4] . '/' . $pathArray[$pathCount -3] == $widgetId && $pathArray[$pathCount -2] == 'admin'){           // 携帯用ウィジェット管理画面
160                                 $accessAdmin = true;
161                         }
162                         // コンテナクラス名作成
163                         if ($cmd == M3_REQUEST_CMD_RSS){                // RSS配信のとき
164                                 $containerClass = self::DEFAULT_RSS_CLASS_PREFIX . $widgetId . 'WidgetContainer';               // デフォルトで起動するコンテナクラス名「ウィジェットID + WidgetContainer」
165                         } else if ($accessAdmin){
166                                 $containerClass = 'admin_' . $widgetId . 'WidgetContainer';             // デフォルトで起動するコンテナクラス名「admin_ + ウィジェットID + WidgetContainer」
167                         } else {
168                                 $containerClass = $widgetId . 'WidgetContainer';                // デフォルトで起動するコンテナクラス名「ウィジェットID + WidgetContainer」
169                         }
170                         // コンテナクラス名修正
171                         $containerClass = str_replace('/', '_', $containerClass);
172                                         
173                         // コンテナクラスが既にロードされているときはエラー
174                         // 同じウィジェットが2回以上実行される可能性があるので、ウィジェットIDが同じであればエラーとしない
175                         if (class_exists($containerClass)){
176                                 // 既に起動済みのウィジェットかどうかチェック
177                                 //if (in_array($filepath, $pathArray)){
178                                         // 同じウィジェットの場合は起動
179                                         $widgetContainer = new $containerClass();
180                                         $gEnvManager->setCurrentWidgetObj($widgetContainer);                            // 実行するウィジェットコンテナオブジェクトを登録
181                                         $widgetContainer->process($gRequestManager);
182                                         $gEnvManager->setCurrentWidgetObj(null);
183         //                      } else {
184         //                              // 同じウィジェットが起動されていないときは、クラス名のバッテイングでエラー
185         //                              echo 'class redefined error: ' . $containerClass;
186         //                      }
187                         } else {
188                                 // ウィジェットのコンテナクラスファイルを読み込み
189                                 if ($isIWidget){                // インナーウィジェットの場合
190                                         if ($accessAdmin){
191                                                 $containerPath = dirname(dirname($filepath)) . '/include/container/' . $containerClass . '.php';
192                                         } else {
193                                                 $containerPath = dirname($filepath) . '/include/container/' . $containerClass . '.php';
194                                         }
195                                 } else {
196                                         $containerPath = $gEnvManager->getCurrentWidgetContainerPath() . '/' . $containerClass . '.php';
197                                 }
198                                 if (file_exists($containerPath)){
199                                         require_once($containerPath);
200                                 } else {
201                                         echo 'file not found error: ' . $containerPath;
202                                 }
203                                 // コンテナクラスを起動
204                                 $widgetContainer = new $containerClass();
205                                 $gEnvManager->setCurrentWidgetObj($widgetContainer);                            // 実行するウィジェットコンテナオブジェクトを登録
206                                 $widgetContainer->process($gRequestManager);
207                                 $gEnvManager->setCurrentWidgetObj(null);
208                         }
209                         // 呼び出し元ファイルパスの保存
210                         $pathArray[] = $filepath;
211                 }
212         }
213         /**
214          * ウィジェットプログラム(サブ)を実行
215          *
216          * @param string $task          タスク名
217          * @param bool $isAdmin         管理者機能(adminディレクトリ以下)かどうか
218          * @param string $defaultWidgetId       カレントウィジェットの実行クラスが取得できない場合のデフォルトウィジェットID
219          * @return なし
220          */
221         function goSubWidget($task, $isAdmin = false, $defaultWidgetId = '')
222         {
223                 global $gEnvManager;
224                 global $gRequestManager;
225                 
226                 // ウィジェットの種別を設定
227                 $gEnvManager->setIsSubWidget(true);                     // サブウィジェットで起動
228                 
229                 // コンテナクラス名作成
230                 // フォーマット: [ウィジェットID][タスク名]WidgetContainer
231                 $widgetId = $gEnvManager->getCurrentWidgetId();// ウィジェットID
232                 $containerClass = '';
233                 if ($isAdmin) $containerClass .= 'admin_';
234                 $containerClass .= $widgetId . ucfirst($task) . 'WidgetContainer';
235
236                 // コンテナクラス名修正
237                 $containerClass = str_replace('/', '_', $containerClass);
238                 
239                 // コンテナクラスが既にロードされているときはエラー
240                 if (class_exists($containerClass)){
241                         echo 'class redefined error2: ' . $containerClass;
242                 } else {
243                         // コンテナクラスファイル取り込み
244                         $containerPath = $gEnvManager->getCurrentWidgetContainerPath() . '/' . $containerClass . '.php';        // カレントウィジェットのコンテナクラス
245                         if (file_exists($containerPath)){
246                                 require_once($containerPath);
247                                 
248                                 // コンテナクラスを起動
249                                 $widgetContainer = new $containerClass();
250                                 $gEnvManager->setCurrentWidgetObj($widgetContainer);                            // 実行するウィジェットコンテナオブジェクトを登録
251                                 $widgetContainer->process($gRequestManager);
252                                 $gEnvManager->setCurrentWidgetObj(null);
253                         } else if (!empty($this->loadPath)){            // クラス検索用パスが設定されているとき
254                                 require_once($containerClass . '.php');
255                                 
256                                 // コンテナクラスを起動
257                                 $widgetContainer = new $containerClass();
258                                 $gEnvManager->setCurrentWidgetObj($widgetContainer);                            // 実行するウィジェットコンテナオブジェクトを登録
259                                 $widgetContainer->process($gRequestManager);
260                                 $gEnvManager->setCurrentWidgetObj(null);
261                         } else {
262                                 if (empty($defaultWidgetId)){
263                                         echo 'file not found error: ' . $containerPath;
264                                 } else {                // デフォルトのウィジェットIDが指定されている場合はデフォルトウィジェットIDで実行
265                                         // コンテナクラス名作成
266                                         $containerClass = '';
267                                         if ($isAdmin) $containerClass .= 'admin_';
268                                         $containerClass .= $defaultWidgetId . ucfirst($task) . 'WidgetContainer';
269
270                                         // コンテナクラス名修正
271                                         $containerClass = str_replace('/', '_', $containerClass);
272                                         
273                                         // コンテナクラスが既にロードされているときはエラー
274                                         if (class_exists($containerClass)){
275                                                 echo 'class redefined error3: ' . $containerClass;
276                                         } else {
277                                                 // コンテナクラスファイル取り込み
278                                                 $containerPath = $gEnvManager->getWidgetsPath() . '/' . $defaultWidgetId . '/include/container/' . $containerClass . '.php';
279                                                 if (file_exists($containerPath)){
280                                                         require_once($containerPath);
281                                 
282                                                         // コンテナクラスを起動
283                                                         $widgetContainer = new $containerClass();
284                                                         $gEnvManager->setCurrentWidgetObj($widgetContainer);                            // 実行するウィジェットコンテナオブジェクトを登録
285                                                         $widgetContainer->process($gRequestManager);
286                                                         $gEnvManager->setCurrentWidgetObj(null);
287                                                 } else {
288                                                         echo 'file not found error: ' . $containerPath;
289                                                 }
290                                         }
291                                 }
292                         }
293                 }
294         }
295         /**
296          * ウィジェットインストーラ、アンインストーラを実行
297          *
298          * @param int $install                                  インストール種別(0=インストール、1=アンインストール、2=アップデート)
299          */
300         function goInstallWidget($install)
301         {
302                 global $gEnvManager;
303                 global $gRequestManager;
304                 
305                 // コンテナクラス名作成
306                 $widgetId = $gEnvManager->getCurrentWidgetId();// ウィジェットID
307                 $containerClass = 'admin_';
308                 $containerClass .= $widgetId . 'InstallWidgetContainer';
309
310                 // コンテナクラス名修正
311                 $containerClass = str_replace('/', '_', $containerClass);
312                 
313                 // コンテナクラスが既にロードされているときはエラー
314                 if (class_exists($containerClass)){
315                         echo 'class redefined error4: ' . $containerClass;
316                 } else {
317                         // コンテナクラスファイル取り込み
318                         $containerPath = $gEnvManager->getCurrentWidgetContainerPath() . '/' . $containerClass . '.php';
319                         if (file_exists($containerPath)){
320                                 require_once($containerPath);
321                         } else {                // インストーラが存在しないときは終了
322                                 return;
323                         }
324                         // コンテナクラスを起動
325                         $widgetContainer = new $containerClass();
326                         $gEnvManager->setCurrentWidgetObj($widgetContainer);                            // 実行するウィジェットコンテナオブジェクトを登録
327                         $widgetContainer->process($gRequestManager, $install);
328                         $gEnvManager->setCurrentWidgetObj(null);
329                 }
330         }
331         /**
332          * ジョブプログラムを実行
333          *
334          * @param string $filepath              呼び出し元ファイルのフルパス。通常は「__FILE__」。OSによってパスの表現が違うので注意。
335          * @return                                              なし
336          */
337         function goJob($filepath)
338         {
339                 global $gPageManager;
340                 
341                 // ジョブタイプを取得し実行
342                 $jobType = basename(dirname($filepath));
343                 $gPageManager->launchJob($jobType);
344         }
345         /**
346          * ウィジェットジョブプログラムを実行
347          *
348          * @param string $filepath              呼び出し元ファイルのフルパス。通常は「__FILE__」。OSによってパスの表現が違うので注意。
349          * @return                                              なし
350          */
351         function goWidgetJob($filepath)
352         {
353                 global $gEnvManager;
354                 global $gRequestManager;
355                 
356                 // ##### ウィジェットのジョブを実行 #####
357                 // コンテナクラス名作成
358                 $widgetId = $gEnvManager->getCurrentWidgetId();
359                 $containerClass = 'admin_';
360                 $containerClass .= $widgetId . 'JobWidgetContainer';
361
362                 // コンテナクラス名修正
363                 $containerClass = str_replace('/', '_', $containerClass);
364                 
365                 // コンテナクラスが既にロードされているときはエラー
366                 if (class_exists($containerClass)){
367                         echo 'class redefined error5: ' . $containerClass;
368                 } else {
369                         // コンテナクラスファイル取り込み
370                         $containerPath = $gEnvManager->getCurrentWidgetContainerPath() . '/' . $containerClass . '.php';
371                         if (file_exists($containerPath)){
372                                 require_once($containerPath);
373                         } else {                // インストーラが存在しないときは終了
374                                 return;
375                         }
376                         // コンテナクラスを起動
377                         $widgetContainer = new $containerClass();
378                         $gEnvManager->setCurrentWidgetObj($widgetContainer);                            // 実行するウィジェットコンテナオブジェクトを登録
379                         $widgetContainer->process($gRequestManager);
380                         $gEnvManager->setCurrentWidgetObj(null);
381                 }
382         }
383         /**
384          * 携帯用プログラムを実行
385          *
386          * @param string $filepath              呼び出し元ファイルのフルパス。通常は「__FILE__」。OSによってパスの表現が違うので注意。
387          * @return                                              なし
388          */
389         function goMobile($filepath = '')
390         {
391                 $this->_goDevice(1/*携帯用*/, $filepath);
392         }
393         /**
394          * スマートフォン用プログラムを実行
395          *
396          * @param string $filepath              呼び出し元ファイルのフルパス。通常は「__FILE__」。OSによってパスの表現が違うので注意。
397          * @return                                              なし
398          */
399         function goSmartphone($filepath = '')
400         {
401                 $this->_goDevice(2/*スマートフォン用*/, $filepath);
402         }
403         /**
404          * 各種デバイス用プログラムを実行
405          *
406          * @param int $type                             1=携帯用プログラム、2=スマートフォン用プログラム
407          * @param string $filepath              呼び出し元ファイルのフルパス。通常は「__FILE__」。OSによってパスの表現が違うので注意。
408          * @return                                              なし
409          */
410         function _goDevice($type, $filepath)
411         {
412                 global $gEnvManager;
413                 global $gRequestManager;
414
415                 switch ($type){
416                         case 1:
417                                 // 携帯用URLへのアクセスを設定
418                                 $gEnvManager->setIsMobileSite(true);
419                                 break;
420                         case 2:
421                                 // スマートフォン用URLのアクセスを設定
422                                 $gEnvManager->setIsSmartphoneSite(true);
423                                 break;
424                 }
425                 
426                 // ルートから$filepathへの相対パスで「FrameContainer.php」の先頭につける
427                 // サフィックスを作成する
428                 // 例) 相対パスが「admin/index.php」のとき「admin_index」
429                 if ($filepath == ''){
430                         $basename = basename($_SERVER["PHP_SELF"], '.php');
431                 } else {
432                         // ルートまでのパスを削除
433                         $path = str_replace(M3_SYSTEM_ROOT_PATH, '', $filepath);
434                         $path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
435                         $path = trim($path, '/');
436                         $pathArray = explode('/', $path);
437                         $basename = '';
438                         for ($i = 0; $i < count($pathArray); $i++){
439                                 if ($i == 0){
440                                         $basename .= $pathArray[$i];
441                                 } else {
442                                         //$basename .= ucfirst($pathArray[$i]);
443                                         $basename .= ('_' . $pathArray[$i]);
444                                 }
445                         }
446                         $basename = basename($basename, '.php');
447                 }
448                 
449                 // ページIDを設定
450                 $gEnvManager->setCurrentPageId($basename);
451
452                 // アクセスポイントを設定
453                 $gEnvManager->setAccessPath(str_replace('_', '/', $basename));
454                 
455                 // ファイル名から、コンテナクラスファイル取り込み
456                 require_once($gEnvManager->getContainerPath() . '/' . $basename . 'FrameContainer.php');
457                 
458                 // コンテナクラスを起動
459                 $class = $basename . 'FrameContainer';
460                 $mainContainer = new $class();
461                 $mainContainer->process($gRequestManager);
462         }
463         /**
464          * クラス検索ロード用のパスを追加
465          *
466          * @param string $path          追加パス
467          * @return                                      なし
468          */
469         function addLoadPath($path)
470         {
471                 if (!empty($path) && !in_array($path, $this->loadPath)){
472                         set_include_path(get_include_path() . PATH_SEPARATOR . $path);
473                         $this->loadPath[] = $path;
474                 }
475         }
476 }
477 ?>