Example #1
0
<?php

define("CORE_PATH", dirname(__FILE__) . '/');
define("MODEL_PATH", CORE_PATH . "../Model/");
define("ACTION_PATH", CORE_PATH . "../Action/");
define("VIEW_PATH", CORE_PATH . "../View/");
define("TMPL_PATH", CORE_PATH . "../Tpl/");
define("CORE_CONFIG_PATH", CORE_PATH . "Conf/");
function load_runtime_file()
{
    $file = array(CORE_PATH . "MVCCore.class.php", CORE_PATH . "App.class.php", CORE_PATH . "URLDispatch.class.php", CORE_PATH . "functions.php", CORE_PATH . "Action.class.php", VIEW_PATH . "View.class.php");
    foreach ($file as $val) {
        require_once $val;
    }
    config(require_once CORE_CONFIG_PATH . "coreconfig.php");
}
load_runtime_file();
MVCCore::init();
App::start();
App::exec();
Example #2
0
 /**
  * 次のFlowを特定し、ロードし、そのクラス名を返却する
  * @param string クラス名
  * @param string ターゲットファイルパスのヒント
  * @return mixed 成功時は対象のクラス名 失敗した場合はFALSEを返す
  */
 public static function loadNextFlow($argClassName = NULL, $argTargetPath = '')
 {
     // 先ずbackflowなのかどうか
     if ('backflow' === strtolower($argClassName)) {
         // backflowが特定出来無かった時ように強制的にIndexを指定しておく
         $argClassName = 'index';
         if (strlen($argTargetPath) > 0) {
             $argClassName = $argTargetPath . '/' . $argClassName;
         }
         // PostパラメータからBackflowを特定する
         if (isset($_POST['flowpostformsection-backflow-section'])) {
             $argClassName = $_POST['flowpostformsection-backflow-section'];
             // 				if(FALSE !== strpos($argClassName, '/')){
             // 					// sectionとtargetを分割する
             // 					$targetTmp = explode('/', $argClassName);
             // 					// 最後だけをsectionIDとして使う
             // 					$argClassName = $targetTmp[count($targetTmp)-1];
             // 					unset($targetTmp[count($targetTmp)-1]);
             // 					$argTargetPath = implode('/', $targetTmp) . '/';
             // 				}
             // 				if(FALSE !== strpos($argClassName, '-')){
             // 					$argClassName = str_replace('-', '_', $argClassName);
             // 				}
         }
         // backflowはリダイレクトポスト(307リダイレクト)
         $query = '';
         if (isset($_POST['flowpostformsection-backflow-section-query']) && strlen($_POST['flowpostformsection-backflow-section-query']) > 0) {
             $query = $_POST['flowpostformsection-backflow-section-query'];
         }
         header('Location: ./' . self::reverseRewriteURL('?_c_=' . $argClassName . '&_o_=' . $_GET['_o_'], $query), TRUE, 307);
         exit;
     }
     $className = MVCCore::loadMVCModule($argClassName, FALSE, $argTargetPath);
     debug('backflowClass=' . var_export($className, true));
     return $className;
 }
 /**
  * PUTメソッド リソースの新規作成、更新(冪等性を持ちます)
  * XXX モデルの位置付けが、テーブルリソースで無い場合は、継承して、RESTの”冪等性”に従って実装して下さい
  * @return mixed 成功時は最新のリソース配列 失敗時はFALSE
  */
 public function put($argRequestParams = NULL)
 {
     $this->_init();
     $gmtDate = Utilities::date('Y-m-d H:i:s', NULL, NULL, 'GMT');
     $requestParams = array();
     $resources = FALSE;
     if (NULL === $argRequestParams) {
         $requestParams = $this->getRequestParams();
     } else {
         $requestParams = $argRequestParams;
     }
     debug('PUT param=');
     debug($requestParams);
     if (isset($requestParams['datas']) && isset($requestParams['datas'][0])) {
         // 配列のPOSTはリカーシブルで処理をする
         for ($requestIdx = 0; $requestIdx < count($requestParams['datas']); $requestIdx++) {
             $tmpRes = $this->put($requestParams['datas'][$requestIdx]);
             if (is_array($tmpRes) && isset($tmpRes[0])) {
                 $resources[$requestIdx] = $tmpRes[0];
             } else {
                 return FALSE;
             }
         }
     } else {
         // 更新を行うリソースを特定する
         $baseQuery = ' 1=1 ';
         $baseBinds = NULL;
         if (TRUE === $this->restResource['me']) {
             // 認証ユーザーのリソース指定
             // bind使うので自力で組み立てる
             $baseQuery = ' `' . $this->authUserIDFieldName . '` = :' . $this->authUserIDFieldName . ' ';
             $baseBinds = array($this->authUserIDFieldName => $this->authUserID);
         }
         // リソースの更新
         // XXX 因みに更新はDEEP指定されていてもDEEPしない!
         if (NULL !== $this->restResource['ids'] && count($this->restResource['ids']) >= 1) {
             // id指定でループする
             for ($IDIdx = 0; $IDIdx < count($this->restResource['ids']); $IDIdx++) {
                 // 空のモデルを先ず作る
                 try {
                     if (TRUE === $this->restResource['me'] && NULL !== $this->AuthUser && is_object($this->AuthUser) && strtolower($this->restResourceModel) == strtolower($this->AuthUser->tableName) && $this->restResource['ids'][$IDIdx] == $this->AuthUser->pkeyName) {
                         // 自分自身のAuthモデルに対しての処理とする
                         $Model = $this->AuthUser;
                         $fields = $Model->getFieldKeys();
                         if (TRUE === $this->restResource['me'] && FALSE === in_array($this->authUserIDFieldName, $fields)) {
                             // フィールドが無いなら$baseQueryを再初期化
                             $baseQuery = ' 1=1 ';
                             $baseBinds = NULL;
                         }
                     } else {
                         $Model = $this->_getModel($this->restResourceModel);
                         $fields = $Model->getFieldKeys();
                         if (TRUE === $this->restResource['me'] && FALSE === in_array($this->authUserIDFieldName, $fields)) {
                             // フィールドが無いなら$baseQueryを再初期化
                             $baseQuery = ' 1=1 ';
                             $baseBinds = NULL;
                         }
                         $query = $baseQuery . ' AND `' . $Model->pkeyName . '` = :' . $Model->pkeyName . ' ';
                         $binds = $baseBinds;
                         if (NULL === $binds) {
                             $binds = array();
                         }
                         $binds[$Model->pkeyName] = $this->restResource['ids'][$IDIdx];
                         // 読み込み
                         debug($query);
                         debug($binds);
                         $Model->load($query, $binds);
                     }
                 } catch (Exception $Exception) {
                     // リソースが存在しない
                     $this->httpStatus = 404;
                     throw new RESTException($Exception->getMessage(), $this->httpStatus);
                     break;
                 }
                 // 最初の一回目はバリデーションを必ず実行
                 if (0 === $IDIdx) {
                     $datas = array();
                     if (FALSE === in_array($this->authUserIDFieldName, $fields)) {
                         // フィールドが無いなら$baseQueryを再初期化
                         $baseQuery = ' 1=1 ';
                         $baseBinds = NULL;
                     }
                     // オートバリデート
                     try {
                         for ($fieldIdx = 0; $fieldIdx < count($fields); $fieldIdx++) {
                             if (isset($requestParams[$fields[$fieldIdx]])) {
                                 // XXX intのincrementとdecrimentは許可する
                                 if (FALSE === ('int' === $Model->describes[$fields[$fieldIdx]]['type'] && TRUE === ('increment' === strtolower($requestParams[$fields[$fieldIdx]]) || 'decrement' === strtolower($requestParams[$fields[$fieldIdx]])))) {
                                     // exec系以外はオートバリデート
                                     $Model->validate($fields[$fieldIdx], $requestParams[$fields[$fieldIdx]]);
                                 }
                                 // バリデートに成功したので更新値として認める
                                 $datas[$fields[$fieldIdx]] = $requestParams[$fields[$fieldIdx]];
                             } elseif ($fields[$fieldIdx] == $this->restResourceCreateDateKeyName && TRUE !== 0 < strlen($Model->{$this->restResourceCreateDateKeyName})) {
                                 // データ作成日付の自動補完
                                 $datas[$fields[$fieldIdx]] = $gmtDate;
                             } elseif ($fields[$fieldIdx] == $this->restResourceModifyDateKeyName) {
                                 // データ更新日付の自動補完
                                 $datas[$fields[$fieldIdx]] = $gmtDate;
                             } elseif ($fields[$fieldIdx] == $Model->pkeyName) {
                                 // Pkeyも入れえておく(複合キーの為の処理)
                                 $datas[$fields[$fieldIdx]] = $this->restResource['ids'][$IDIdx];
                             } elseif ($fields[$fieldIdx] == $this->authUserIDFieldName) {
                                 // 自分自身のIDを入れる
                                 $datas[$fields[$fieldIdx]] = $this->authUserID;
                             }
                             // Filterがあったらフィルター処理をする
                             $filerName = str_replace(' ', '', ucwords(str_replace('_', ' ', $this->restResourceModel . ' ' . $fields[$fieldIdx]))) . 'Filter';
                             debug('$filerName=' . $filerName);
                             if (FALSE !== MVCCore::loadMVCFilter($filerName, TRUE)) {
                                 $filterClass = MVCCore::loadMVCFilter($filerName);
                                 $Filter = new $filterClass();
                                 $Filter->REST = $this;
                                 $Filter->Model = $Model;
                                 if (!isset($datas[$fields[$fieldIdx]])) {
                                     // 初期化
                                     $datas[$fields[$fieldIdx]] = NULL;
                                     if (0 < strlen($Model->{$fields[$fieldIdx]})) {
                                         $datas[$fields[$fieldIdx]] = $Model->{$fields[$fieldIdx]};
                                     }
                                 }
                                 debug('original value=' . $datas[$fields[$fieldIdx]]);
                                 $filterMethod = 'filter' . ucfirst(strtolower($_SERVER['REQUEST_METHOD']));
                                 $datas[$fields[$fieldIdx]] = $Filter->{$filterMethod}($datas[$fields[$fieldIdx]]);
                                 debug('$filered value=' . $datas[$fields[$fieldIdx]]);
                             }
                         }
                     } catch (Exception $Exception) {
                         // バリデーションエラー(必須パラメータチェックエラー)
                         $this->httpStatus = 400;
                         throw new RESTException($Exception->getMessage(), $this->httpStatus);
                         break;
                     }
                 }
                 // POSTに従ってModelを更新する
                 $Model->save($datas);
                 // 更新の完了した新しいモデルのデータをレスポンスにセット
                 $resources[] = $this->_convertArrayFromModel($Model);
             }
         } else {
             try {
                 if (TRUE === $this->restResource['me'] && NULL !== $this->AuthUser && is_object($this->AuthUser) && strtolower($this->restResourceModel) == strtolower($this->AuthUser->tableName)) {
                     // 自分自身のAuthモデルに対しての処理とする
                     $Model = $this->AuthUser;
                 } else {
                     $Model = $this->_getModel($this->restResourceModel);
                 }
                 $datas = array();
                 $isDeepModel = FALSE;
                 $deepDatas = array();
                 $fields = $Model->getFieldKeys();
                 if (TRUE === $this->restResource['me'] && FALSE === in_array($this->authUserIDFieldName, $fields)) {
                     // フィールドが無いなら$baseQueryを再初期化
                     $baseQuery = ' 1=1 ';
                     $baseBinds = NULL;
                 }
             } catch (Exception $Exception) {
                 // リソースが存在しない
                 $this->httpStatus = 404;
                 throw new RESTException($Exception->getMessage(), $this->httpStatus);
             }
             // オートバリデート
             for ($fieldIdx = 0; $fieldIdx < count($fields); $fieldIdx++) {
                 if (isset($requestParams[$fields[$fieldIdx]])) {
                     try {
                         // XXX intのincrementとdecrimentは許可する
                         if (FALSE === ('int' === $Model->describes[$fields[$fieldIdx]]['type'] && TRUE === ('increment' === strtolower($requestParams[$fields[$fieldIdx]]) || 'decrement' === strtolower($requestParams[$fields[$fieldIdx]])))) {
                             // exec系以外はオートバリデート
                             $Model->validate($fields[$fieldIdx], $requestParams[$fields[$fieldIdx]]);
                         }
                         // バリデートに成功したので更新値として認める
                         $datas[$fields[$fieldIdx]] = $requestParams[$fields[$fieldIdx]];
                     } catch (Exception $Exception) {
                         // バリデーションエラー(必須パラメータチェックエラー)
                         $this->httpStatus = 400;
                         throw new RESTException($Exception->getMessage(), $this->httpStatus);
                         break;
                     }
                 } elseif (TRUE === $this->deepRESTMode && strlen($fields[$fieldIdx]) - 3 === strpos($fields[$fieldIdx], '_id') && $this->authUserIDFieldName != $fields[$fieldIdx]) {
                     $deepResource = substr($fields[$fieldIdx], 0, -3);
                     $deepResourcePath = $deepResource;
                     if (TRUE === $this->restResource['me']) {
                         $deepResourcePath = 'me/' . $deepResource;
                     }
                     debug('deep??' . $deepResourcePath . ' & ' . $this->authUserIDFieldName . ' & ' . $fields[$fieldIdx] . ' & ' . (strlen($fields[$fieldIdx]) - 3) . ' & ' . strpos($fields[$fieldIdx], '_id'));
                     $isDeepModel = TRUE;
                     try {
                         $deepModel = $this->_getModel($deepResource);
                     } catch (Exception $Exception) {
                         $isDeepModel = FALSE;
                     }
                     if (TRUE === $isDeepModel) {
                         // deepRESTを実行し、IDの取得をする
                         $DeepREST = new REST();
                         $DeepREST->AuthUser = $this->AuthUser;
                         $DeepREST->authUserID = $this->authUserID;
                         $DeepREST->authUserIDFieldName = $this->authUserIDFieldName;
                         $DeepREST->authUserQuery = $this->authUserQuery;
                         $DeepREST->rootREST = FALSE;
                         $res = $DeepREST->execute($deepResourcePath, $requestParams);
                         $datas[$fields[$fieldIdx]] = $res[0]['id'];
                         $deepDatas[$deepResource] = $res;
                     }
                 } elseif (TRUE === $this->deepRESTMode && $this->authUserIDFieldName == $fields[$fieldIdx]) {
                     // ログインIDの自動補完
                     $datas[$fields[$fieldIdx]] = $this->authUserID;
                 } elseif ($fields[$fieldIdx] == $this->restResourceCreateDateKeyName && TRUE !== 0 < strlen($Model->{$this->restResourceCreateDateKeyName})) {
                     // データ作成日付の自動補完
                     $datas[$fields[$fieldIdx]] = $gmtDate;
                 } elseif ($fields[$fieldIdx] == $this->restResourceModifyDateKeyName) {
                     // データ更新日付の自動補完
                     $datas[$fields[$fieldIdx]] = $gmtDate;
                 }
                 // Filterがあったらフィルター処理をする
                 $filerName = str_replace(' ', '', ucwords(str_replace('_', ' ', $this->restResourceModel . ' ' . $fields[$fieldIdx]))) . 'Filter';
                 debug('$filerName=' . $filerName);
                 if (FALSE !== MVCCore::loadMVCFilter($filerName, TRUE)) {
                     $filterClass = MVCCore::loadMVCFilter($filerName);
                     debug($filterClass);
                     $Filter = new $filterClass();
                     $Filter->REST = $this;
                     $Filter->Model = $Model;
                     if (!isset($datas[$fields[$fieldIdx]])) {
                         // 初期化
                         $datas[$fields[$fieldIdx]] = NULL;
                         if (0 < strlen($Model->{$fields[$fieldIdx]})) {
                             $datas[$fields[$fieldIdx]] = $Model->{$fields[$fieldIdx]};
                         }
                     }
                     debug('original value=' . $datas[$fields[$fieldIdx]]);
                     $filterMethod = 'filter' . ucfirst(strtolower($_SERVER['REQUEST_METHOD']));
                     $datas[$fields[$fieldIdx]] = $Filter->{$filterMethod}($datas[$fields[$fieldIdx]]);
                     debug('$filered value=' . $datas[$fields[$fieldIdx]]);
                 }
             }
             // POSTに従ってModelを作成する
             $Model->save($datas);
             // 更新の完了した新しいモデルのデータをレスポンスにセット
             $resources[] = $this->_convertArrayFromModel($Model);
             if (TRUE === $isDeepModel && 0 < count($deepDatas)) {
                 foreach ($deepDatas as $key => $val) {
                     $resources[count($resources) - 1][$key] = $val;
                 }
             }
         }
     }
     return $resources;
 }
Example #4
0
 /**
  * MVCクラスモジュールの読み込み処理
  * @param string クラス名
  * @param string クラスの読み込事にエラーが在る場合にbooleanを返すかどうか
  * @param string クラスの読み込事にエラーが在る場合にbooleanを返すかどうか
  * @return mixed 成功時は対象のクラス名 失敗した場合はFALSEを返す
  */
 public static function loadMVCModule($argClassName = NULL, $argClassExistsCalled = FALSE, $argTargetPath = '')
 {
     static $currentTargetPath = '';
     $targetPath = '';
     if (NULL !== $argClassName) {
         $controlerClassName = $argClassName;
     } else {
         // コントロール対象を自動特定
         $controlerClassName = 'Index';
         if (isset($_GET['_c_']) && strlen($_GET['_c_']) > 0) {
             $controlerClassName = str_replace('-', '_', ucfirst($_GET['_c_']));
             if (FALSE !== strpos($_GET['_c_'], '/') && strlen($_GET['_c_']) > 1) {
                 $matches = NULL;
                 if (preg_match('/(.*)\\/([^\\/]*)$/', $_GET['_c_'], $matches) && is_array($matches) && isset($matches[2])) {
                     $controlerClassName = str_replace('-', '_', ucfirst($matches[2]));
                     if (isset($matches[1]) && strlen($matches[1]) > 0) {
                         $targetPath = $matches[1] . '/';
                         if ('' === $currentTargetPath) {
                             $currentTargetPath = $targetPath;
                         }
                     }
                 }
             }
         }
     }
     if ('' !== $argTargetPath) {
         $targetPath = $argTargetPath;
     }
     if ('' === $targetPath) {
         $targetPath = $currentTargetPath;
     }
     $version = '';
     if (isset($_GET['_v_']) && strlen($_GET['_v_']) > 0) {
         $version = $_GET['_v_'];
     }
     debug('path=' . $targetPath);
     debug('class=' . $controlerClassName);
     if (!class_exists($controlerClassName, FALSE)) {
         // コントローラを読み込み
         if ('' !== $version) {
             // バージョン一致のファイルを先ず走査する
             loadModule('default.controlmain.' . $targetPath . $version . '/' . $controlerClassName, TRUE);
         }
         if (!class_exists($controlerClassName, FALSE)) {
             loadModule('default.controlmain.' . $targetPath . $controlerClassName, TRUE);
         }
         if (!class_exists($controlerClassName, FALSE)) {
             loadModule('default.controlmain.' . $controlerClassName, TRUE);
         }
         if (class_exists($controlerClassName, FALSE)) {
             // FlowGenerateする必要がなさそうなのでココで終了
             return $controlerClassName;
         } else {
             if ('' === self::$flowXMLBasePath) {
                 // エラー終了
                 return FALSE;
             } else {
                 // ココからはFlow処理
                 if (TRUE === self::$flowXMLBasePath) {
                     // self::$flowXMLBasePathがTRUEとなっていた場合はConfigureにFLOWXML_PATH定義が無いか調べる
                     if (class_exists('Configure', FALSE) && NULL !== Configure::constant('FLOWXML_PATH')) {
                         self::$flowXMLBasePath = Configure::FLOWXML_PATH;
                     }
                 }
                 // Flow出来ない!
                 if ('' === self::$flowXMLBasePath) {
                     // エラー終了
                     return FALSE;
                 }
                 // XML定義の存在チェック
                 // クラス名は分解しておく
                 $classHint = explode('_', $controlerClassName);
                 debug($targetPath);
                 debug($classHint);
                 $classXMLName = $classHint[0];
                 debug($classXMLName);
                 $flowXMLPath = '';
                 if ('' !== $version) {
                     // バージョン一致のファイルを先ず走査する
                     if (file_exists_ip(self::$flowXMLBasePath . '/' . $targetPath . $version . '/' . $classXMLName . '.flow.xml')) {
                         $flowXMLPath = self::$flowXMLBasePath . '/' . $targetPath . $version . '/' . $classXMLName . '.flow.xml';
                     }
                 }
                 if ('' === $flowXMLPath) {
                     // バージョン関係ナシのファイルを走査する
                     if (file_exists_ip(self::$flowXMLBasePath . '/' . $targetPath . $classXMLName . '.flow.xml')) {
                         $flowXMLPath = self::$flowXMLBasePath . '/' . $targetPath . $classXMLName . '.flow.xml';
                     }
                 }
                 debug($flowXMLPath);
                 if ('' === $flowXMLPath) {
                     // エラー終了
                     return FALSE;
                 }
                 // flowファイルの履歴を残しておく
                 self::$flowXMLPaths[] = array('class' => $controlerClassName, 'xml' => $flowXMLPath);
                 // Flowに応じたクラス定義の自動生成を委任
                 loadModule('Flow');
                 if (FALSE === Flow::generate($flowXMLPath, $controlerClassName, $targetPath)) {
                     // エラー終了
                     return FALSE;
                 }
                 if (!class_exists($controlerClassName, FALSE)) {
                     // エラー終了
                     return FALSE;
                 }
             }
         }
     }
     return $controlerClassName;
 }