function _date($argDate, $argTargetLocal, $argFormat = null) { if ("JP" == strtoupper($argTargetTimezone) || "ja_jp" == strtolower($argTargetTimezone) || "ja-jp" == strtolower($argTargetTimezone)) { if (null === $argFormat) { $argFormat = "Y-m-d H:i:s"; } return Utilities::date($argFormat, $argDate, "GMT", "Asia/Tokyo"); } else { if (null === $argFormat) { $argFormat = "Y-m-d H:i:s"; } return Utilities::date($argFormat, $argDate, "GMT"); } }
/** * 登録する * @param string DB接続情報 */ public static function registration($argID = NULL, $argPass = NULL, $argDSN = NULL) { if (FALSE === self::$_initialized) { self::_init($argDSN); } $id = $argID; $pass = $argPass; if (NULL === $id) { if (TRUE === class_exists('Flow', FALSE) && isset(Flow::$params) && isset(Flow::$params['post']) && TRUE === is_array(Flow::$params['post']) && isset(Flow::$params['post'][self::$authIDField])) { // Flowに格納されているPOSTパラメータを自動で使う $id = Flow::$params['post'][self::$authIDField]; } if (isset($_REQUEST) && isset($_REQUEST[self::$authIDField])) { // リクエストパラメータから直接受け取る $id = $_REQUEST[self::$authIDField]; } } if (NULL === $pass) { if (TRUE === class_exists('Flow', FALSE) && isset(Flow::$params) && isset(Flow::$params['post']) && TRUE === is_array(Flow::$params['post']) && isset(Flow::$params['post'][self::$authPassField])) { // Flowに格納されているPOSTパラメータを自動で使う $pass = Flow::$params['post'][self::$authPassField]; } if (isset($_REQUEST) && isset($_REQUEST[self::$authPassField])) { // リクエストパラメータから直接受け取る $pass = $_REQUEST[self::$authPassField]; } } $id = self::_resolveEncrypted($id, self::$authIDEncrypted); $pass = self::_resolveEncrypted($pass, self::$authPassEncrypted); $gmtDate = Utilities::date('Y-m-d H:i:s', NULL, NULL, 'GMT'); $query = '`' . self::$authIDField . '` = :' . self::$authIDField . ' AND `' . self::$authPassField . '` = ' . self::$authPassField . ' '; $binds = array(self::$authIDField => $id, self::$authPassField => $pass); $User = ORMapper::getModel(self::$_DBO, self::$authTable, $query, $binds); $User->{'set' . str_replace(' ', '', ucwords(str_replace('_', ' ', self::$authIDField)))}($id); $User->{'set' . str_replace(' ', '', ucwords(str_replace('_', ' ', self::$authPassField)))}($pass); $User->{'set' . str_replace(' ', '', ucwords(str_replace('_', ' ', self::$authCreatedField)))}($gmtDate); $User->{'set' . str_replace(' ', '', ucwords(str_replace('_', ' ', self::$authModifiedField)))}($gmtDate); if (TRUE === $User->save()) { // ユーザーの登録は完了とみなし、コミットを行う! self::$_DBO->commit(); } return $User; }
/** * 新しいトークンを指定のトークンキー名で払い出しcookieにセットする * @param string トークンキー名 */ public static function setTokenToCookie($argTokenKey) { // 新しいtokenを発行する self::$_token = self::_identifierToToken(self::$_identifier); // クッキーを書き換える setcookie($argTokenKey, self::$_token, 0, self::$_path, self::$_domain); // SESSHONレコードを更新 $binds = array(self::$_sessionPKeyName => self::$_token, 'expierddate' => Utilities::modifyDate('-' . (string) self::$_expiredtime . 'sec', 'Y-m-d H:i:s', NULL, NULL, 'GMT')); $Session = ORMapper::getModel(self::$_DBO, self::$_sessionTblName, '`' . self::$_sessionPKeyName . '` = :' . self::$_sessionPKeyName . ' AND `' . self::$_sessionDateKeyName . '` >= :expierddate ORDER BY `' . self::$_sessionDateKeyName . '` DESC limit 1', $binds); $Session->{'set' . str_replace(' ', '', ucwords(str_replace('_', ' ', self::$_sessionPKeyName)))}(self::$_token); $Session->{'set' . str_replace(' ', '', ucwords(str_replace('_', ' ', self::$_sessionDateKeyName)))}(Utilities::date('Y-m-d H:i:s', NULL, NULL, 'GMT')); $Session->save(); }
/** * 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; }
/** * セッションデータテーブルにデータをしまう * @param string セッションデータのプライマリーキー */ protected static function _finalizeData($argPKey) { if (is_array(self::$_sessionData) && count(self::$_sessionData) > 0) { $binds = array(self::$_sessionDataPKeyName => $argPKey, 'expierddate' => Utilities::modifyDate('-' . (string) self::$_expiredtime . 'sec', 'Y-m-d H:i:s', NULL, NULL, 'GMT')); $Session = ORMapper::getModel(self::$_DBO, self::$_sessionDataTblName, $argPKey); // XXX identifierが変えられたかもしれないので、もう一度セット $Session->{'set' . str_replace(' ', '', ucwords(str_replace('_', ' ', self::$_sessionDataPKeyName)))}($argPKey); $Session->{'set' . str_replace(' ', '', ucwords(str_replace('_', ' ', self::$_serializeKeyName)))}(json_encode(self::$_sessionData)); $Session->{'set' . str_replace(' ', '', ucwords(str_replace('_', ' ', self::$_sessionDataDateKeyName)))}(Utilities::date('Y-m-d H:i:s', NULL, NULL, 'GMT')); debug('session!'); try { debug('save???'); $Session->save(); debug('save!'); // 正常終了 return TRUE; } catch (exception $Exception) { // XXX この場合は、並列プロセス(Ajaxの非同期プロセス等)が先にinsertを走らせた場合に発生する debug('throw msg=' . $Exception->getMessage()); debug('throw save?'); $Session->save(); debug('throw save!'); // 正常終了 return TRUE; } // XXX SESSIONExceptionクラスを実装予定 logging(__CLASS__ . PATH_SEPARATOR . __METHOD__ . PATH_SEPARATOR . __LINE__ . PATH_SEPARATOR . self::$_DBO->getLastErrorMessage(), 'exception'); return FALSE; } return TRUE; }