/** * WebインターフェースでのMVCのメイン処理 * * @param boolean DIコンテナで実行するかどうか * @throws Exception */ public static function webmain($argFlowXMLBasePath = '') { self::$flowXMLBasePath = $argFlowXMLBasePath; logging($_REQUEST, 'post'); logging($_COOKIE, 'cookie'); logging($_SERVER, 'server'); debug('requestParam=' . var_export($_REQUEST, TRUE)); debug('cookie=' . var_export($_COOKIE, TRUE)); $actionMethodName = 'execute'; if (isset($_GET['_a_']) && strlen($_GET['_a_']) > 0) { $actionMethodName = $_GET['_a_']; } // $_GET['_o_']がコントローラで消されてしまうかも知れないので一回取っておく // 正式なOutputType定義はコントローラ処理終了後 $outputType = 'html'; if (isset($_GET['_o_']) && strlen($_GET['_o_']) > 0) { $outputType = $_GET['_o_']; } // アプリケーション情報の取得 $serverUserAgent = $_SERVER['HTTP_USER_AGENT']; $appleReviewd = FALSE; $deviceType = 'PC'; if (false != strpos(strtolower($serverUserAgent), 'iphone')) { $deviceType = 'iPhone'; } elseif (false != strpos(strtolower($serverUserAgent), 'ipad')) { $deviceType = 'iPad'; } elseif (false != strpos(strtolower($serverUserAgent), 'ipod')) { $deviceType = 'iPod'; } elseif (false != strpos(strtolower($serverUserAgent), 'android')) { $deviceType = 'Android'; } debug('deviceType=' . $deviceType); // アプリの必須バージョンチェック if (isset($_GET['_v_'])) { if (TRUE === Configure::constant('MUST_IOSAPP_VERSION_FLAG_FILE') && ('iPhone' === $deviceType || 'iPad' === $deviceType || 'iPod' === $deviceType)) { if (TRUE === is_file(Configure::MUST_IOSAPP_VERSION_FLAG_FILE)) { debug(Configure::MUST_IOSAPP_VERSION_FLAG_FILE); $mustVirsionStr = @file_get_contents(Configure::MUST_IOSAPP_VERSION_FLAG_FILE); $matches = NULL; if (preg_match('/([0-9.]+)/', $mustVirsionStr, $matches)) { $mustVirsionNum = (int) str_replace('.', '', $matches[1]); debug('mustVirsionNum=' . $mustVirsionNum); debug('nowversion=' . (int) str_replace('.', '', $_GET['_v_'])); if ($mustVirsionNum > (int) str_replace('.', '', $_GET['_v_'])) { self::$mustAppVersioned = FALSE; } } } } else { if (TRUE === Configure::constant('MUST_ANDROIDAPP_VERSION_FLAG_FILE') && ('android' === $deviceType || 'Android' === $deviceType)) { if (TRUE === is_file(Configure::MUST_ANDROIDAPP_VERSION_FLAG_FILE)) { debug(Configure::MUST_ANDROIDAPP_VERSION_FLAG_FILE); $mustVirsionStr = @file_get_contents(Configure::MUST_ANDROIDAPP_VERSION_FLAG_FILE); $matches = null; if (preg_match('/([0-9.]+)/', $mustVirsionStr, $matches)) { $mustVirsionNum = (int) str_replace('.', '', $matches[1]); if ($mustVirsionNum > (int) str_replace('.', '', $_GET['_v_'])) { self::$mustAppVersioned = FALSE; } } } } } } // アップルレビューバージョンの存在チェック if ('iPhone' === $deviceType || 'iPad' === $deviceType || 'iPod' === $deviceType) { if (TRUE === Configure::constant('APPLE_REVIEW_FLAG_FILE') && isset($_GET['_v_'])) { if (TRUE === is_file(Configure::APPLE_REVIEW_FLAG_FILE . $_GET['_v_'])) { debug(Configure::APPLE_REVIEW_FLAG_FILE . $_GET['_v_']); $appleReviewd = TRUE; debug('isAppleReview'); } } } // アプリバージョン $version = NULL; if (isset($_GET['_v_']) && strlen($_GET['_v_']) > 0) { $version = $_GET['_v_']; debug('version=' . $version); } self::$appVersion = $version; self::$deviceType = $deviceType; self::$appleReviewd = $appleReviewd; $res = FALSE; // 実行 try { $httpStatus = 200; // コントロール対象を取得 $res = self::loadMVCModule(); if (FALSE === $res) { // フィルター処理 if (self::loadMVCFilter('StaticPrependFilter')) { $PrependFilter = new StaticPrependFilter(); $filtered = $PrependFilter->execute(); if (FALSE === $filtered) { // XXX フィルターエラー throw new Exception('access denied.'); } } // ただのhtml表示かも知れないのを調べる if (is_file($_SERVER['DOCUMENT_ROOT'] . $_SERVER['REQUEST_URI'])) { // そのままスタティックファイルとして表示 $res = file_get_contents($_SERVER['DOCUMENT_ROOT'] . $_SERVER['REQUEST_URI']); } else { // エラー throw new Exception('controller class faild.'); } // フィルター処理 if (self::loadMVCFilter('StaticAppendFilter')) { $AppendFilter = new StaticAppendFilter(); $filtered = $AppendFilter->execute(); if (FALSE === $filtered) { // XXX フィルターエラー throw new Exception('access denied.'); } } } else { $controlerClassName = $res; // フィルター処理 $filres = self::loadMVCFilter('MVCPrependFilter'); debug($filres); if (self::loadMVCFilter('MVCPrependFilter')) { debug('s??'); $PrependFilter = new MVCPrependFilter(); $filtered = $PrependFilter->execute(); if (FALSE === $filtered) { // XXX フィルターエラー throw new Exception('access denied.'); } } self::$CurrentController = new $controlerClassName(); if (isset($_SERVER['REQUEST_METHOD'])) { self::$CurrentController->requestMethod = strtoupper($_SERVER['REQUEST_METHOD']); } self::$CurrentController->controlerClassName = $controlerClassName; self::$CurrentController->outputType = $outputType; self::$CurrentController->deviceType = self::$deviceType; self::$CurrentController->appVersion = self::$appVersion; self::$CurrentController->appleReviewd = self::$appleReviewd; self::$CurrentController->mustAppVersioned = self::$mustAppVersioned; $res = self::$CurrentController->{$actionMethodName}(); if (FALSE === $res) { throw new Exception($actionMethodName . ' executed faild.'); } // フィルター処理 if (self::loadMVCFilter('MVCAppendFilter')) { $AppendFilter = new MVCAppendFilter(); $filtered = $AppendFilter->execute(); if (FALSE === $filtered) { // XXX フィルターエラー throw new Exception('access denied.'); } } } } catch (Exception $Exception) { // リターンは強制的にFALSE $res = FALSE; // statusコードがアレバそれを使う if (isset(self::$CurrentController->httpStatus) && $httpStatus != self::$CurrentController->httpStatus) { $httpStatus = self::$CurrentController->httpStatus; } else { // インターナルサーバエラー $httpStatus = 500; } } // Output try { if (200 !== $httpStatus && 201 !== $httpStatus && 202 !== $httpStatus) { // 200版以外のステータスコードの場合の出力処理 header('HTTP', TRUE, $httpStatus); if (FALSE === $res && isset($Exception)) { $html = ''; if ('json' === $outputType) { // exceptionのログ出力 if (!class_exists('PHPUnit_Framework_TestCase', FALSE)) { logging($Exception->getMessage() . PATH_SEPARATOR . var_export(debug_backtrace(), TRUE), 'exception'); } // jsonでエラーメッセージを出力 header('Content-type: text/javascript; charset=UTF-8'); $res = json_encode(array('error' => $Exception->getMessage())); if (TRUE == self::$CurrentController->jsonUnescapedUnicode) { $res = unicode_encode($res); // スラッシュのエスケープをアンエスケープする $res = preg_replace('/\\\\\\//', '/', $res); } debug($res); exit($res); } elseif ('xml' === $outputType) { // exceptionのログ出力 if (!class_exists('PHPUnit_Framework_TestCase', FALSE)) { logging($Exception->getMessage() . PATH_SEPARATOR . var_export(debug_backtrace(), TRUE), 'exception'); } // XMLでエラーメッセージを出力 header('Content-type:Content- type: application/xml; charset=UTF-8'); exit('<?xml version="1.0" encoding="UTF-8" ?>' . convertObjectToXML(array('error' => $Exception->getMessage()))); } elseif ('html' === $outputType) { $Tpl = self::loadTemplate('error'); if (is_object($Tpl)) { $dispatch = false; $html = $Tpl->execute(); } } _systemError('Exception :' . $Exception->getMessage(), $httpStatus, $html); } } else { $isBinary = FALSE; if (isset(self::$CurrentController->outputType)) { $outputType = self::$CurrentController->outputType; } if ('html' === $outputType) { // htmlヘッダー出力 header('Content-type: text/html; charset=UTF-8'); if (is_array($res)) { // html出力なのに配列は出力テンプレートの自動判別を試みる } } elseif ('txt' === $outputType) { // textヘッダー出力 header('Content-type: text/plain; charset=UTF-8'); if (is_array($res)) { $res = var_export($res, TRUE); } } elseif ('json' === $outputType) { // jsonヘッダー出力 header('Content-type: text/javascript; charset=UTF-8'); if (is_array($res)) { $res = json_encode($res); } if (TRUE == self::$CurrentController->jsonUnescapedUnicode) { $res = unicode_encode($res); // スラッシュのエスケープをアンエスケープする $res = preg_replace('/\\\\\\//', '/', $res); } } elseif ('xml' === $outputType) { // jsonヘッダー出力 header('Content-type:Content- type: application/xml; charset=UTF-8'); if (is_array($res)) { $res = '<?xml version="1.0" encoding="UTF-8" ?>' . convertObjectToXML($res); } } elseif ('csv' === $outputType) { // csvヘッダー出力 header('Content-type: application/octet-stream; charset=SJIS'); if (is_array($res)) { // XXX csvといいつつtsvを吐き出す $res = mb_convert_encoding(convertObjectToCSV($res, PHP_TAB), 'SJIS', 'UTF-8'); } } elseif ('jpg' === $outputType || 'jpeg' === $outputType) { // jpgヘッダー出力 header('Content-type: image/jpeg'); $isBinary = TRUE; } elseif ('png' === $outputType) { // pngヘッダー出力 header('Content-type: image/png'); $isBinary = TRUE; } elseif ('gif' === strtolower($outputType)) { // gifヘッダー出力 header('Content-type: image/gif'); $isBinary = TRUE; } elseif ('bmp' === strtolower($outputType)) { // bmpヘッダー出力 header('Content-type: image/bmp'); $isBinary = TRUE; } // 描画処理 if (TRUE === $isBinary && is_string($res)) { header('Content-length: ' . strlen($res)); } debug('lastRES='); debug($res); echo $res; } } catch (Exception $Exception) { // かなりのイレギュラー! 普通はココを通らない!! _systemError('Exception :' . $Exception->getMessage()); } // 明示的終了 exit; }
/** * convertObjectToXMLのエイリアス */ function convertObject2XML($data, $level = 0) { return convertObjectToXML($data, $level); }