/**
  * テーブルマイグレートを自動解決する
  * @param unknown $argDBO
  * @param unknown $argTable
  * @return boolean
  */
 public static function resolve($argDBO, $argTblName, $argLastMigrationHash = NULL)
 {
     static $executed = array();
     // 1プロセス内で同じテーブルに対してのマイグレーションを2度も処理しない
     if (FALSE === (isset($executed[$argTblName]) && TRUE === $executed[$argTblName])) {
         $firstMigration = TRUE;
         if (!isset(ORMapper::$modelHashs[$argTblName])) {
             // コンソールから強制マイグレーションされる時に恐らくココを通る
             $nowModel = ORMapper::getModel($argDBO, $argTblName);
         }
         // XXX ORMapperとMigrationManagerは循環しているのでいじる時は気をつけて!
         $modelHash = ORMapper::$modelHashs[$argTblName];
         // modelハッシュがmigrationハッシュに含まれていないかどうか
         $migrationHash = $argLastMigrationHash;
         if (NULL === $migrationHash) {
             // 既に見つけているマイグレーションハッシュから定義を取得する
             $diff = self::_getDiff($argDBO, $argTblName);
             if (NULL !== self::$_lastMigrationHash) {
                 $migrationHash = self::$_lastMigrationHash;
             }
         }
         debug('$migrationHash=' . $migrationHash);
         debug('$modelHash=' . $modelHash);
         // マイグレーションハッシュがある場合は
         if (NULL !== $migrationHash) {
             if (FALSE !== strpos($migrationHash, $modelHash)) {
                 // このテーブルはマイグレーション済み
                 $executed[$argTblName] = TRUE;
                 // 現在のテーブル定義と最新のマイグレーションファイル上のテーブルハッシュに差分が無いので何もしない
                 debug('exists migration! ' . $migrationHash);
                 return TRUE;
             }
             // 最後に適用している該当テーブルに対してのマイグレーションクラスを読み込んでmodelハッシュを比較する
             $migrationFilePath = getAutoMigrationPath() . $argDBO->dbidentifykey . '.' . $migrationHash . '.migration.php';
             if (TRUE === file_exists($migrationFilePath) && TRUE === is_file($migrationFilePath)) {
                 // 既にテーブルはあるとココで断定
                 $firstMigration = FALSE;
                 // 直前のマイグレーションクラスをインスタンス化
                 @(include_once $migrationFilePath);
                 // モデルハッシュが変わっているかどうかを比較
                 if ($modelHash == $migrationHash::$migrationHash) {
                     // このテーブルはマイグレーション済み
                     $executed[$argTblName] = TRUE;
                     // 現在のテーブル定義と最新のマイグレーションファイル上のテーブルハッシュに差分が無いので何もしない
                     return TRUE;
                 }
             }
         }
         // テーブル定義を取得
         $tableDefs = ORMapper::getModelPropertyDefs($argDBO, $argTblName);
         $describeDef = $tableDefs['describeDef'];
         $migrationClassDef = PHP_EOL;
         $migrationClassDef .= PHP_EOL . PHP_TAB . 'public function __construct(){' . PHP_EOL . PHP_TAB . PHP_TAB . str_replace('; ', ';' . PHP_EOL . PHP_TAB . PHP_TAB, $describeDef) . 'return;' . PHP_EOL . PHP_TAB . '}' . PHP_EOL;
         if (TRUE === $firstMigration) {
             // create指示を生成
             $migrationClassDef .= PHP_EOL . PHP_TAB . 'public function up($argDBO){' . PHP_EOL . PHP_TAB . PHP_TAB . 'return $this->create($argDBO);' . PHP_EOL . PHP_TAB . '}' . PHP_EOL;
             // drop指示を生成
             $migrationClassDef .= PHP_EOL . PHP_TAB . 'public function down($argDBO){' . PHP_EOL . PHP_TAB . PHP_TAB . 'return $this->drop($argDBO);' . PHP_EOL . PHP_TAB . '}' . PHP_EOL;
         } else {
             // ALTERかDROP指示を生成
             $upAlterDef = '$alter = array(); ';
             $downAlterDef = '$alter = array(); ';
             // 差分をフィールドを走査して特定する
             $lastModel = new $migrationHash();
             $beforeDescribes = $lastModel->describes;
             $describes = array();
             $beforeFieldKey = NULL;
             eval(str_replace('$this->', '$', $describeDef));
             // 増えてる減ってるでループの起点を切り替え
             if (count($describes) >= count($beforeDescribes)) {
                 // フィールドが増えている もしくは数は変わらない
                 foreach ($describes as $feldKey => $propary) {
                     // 最新のテーブル定義に合わせて
                     $alter = NULL;
                     if (!array_key_exists($feldKey, $beforeDescribes)) {
                         // 増えてるフィールドを単純に増やす
                         $alter = 'ADD';
                         $downAlterDef .= '$alter["' . $feldKey . '"] = array(); ';
                         $downAlterDef .= '$alter["' . $feldKey . '"]["alter"] = "DROP"; ';
                     } elseif (sha1(serialize($propary)) != sha1(serialize($beforeDescribes[$feldKey]))) {
                         // ハッシュ値が違うので新しいフィールド情報でAlterする
                         $alter = 'MODIFY';
                         // 元に戻すMODYFI
                         $alterDefs = ORMapper::getModelPropertyDefs($argDBO, $argTblName, array($feldKey => $beforeDescribes[$feldKey]));
                         $downAlterDef .= str_replace('$this->describes = array(); ', '', $alterDefs['describeDef']);
                         $downAlterDef .= '$alter["' . $feldKey . '"]["alter"] = "' . $alter . '"; ';
                     }
                     if (NULL === $alter) {
                         // 処理をスキップして次のループへ
                         $beforeFieldKey = $feldKey;
                         continue;
                     }
                     // up生成
                     $alterDefs = ORMapper::getModelPropertyDefs($argDBO, $argTblName, array($feldKey => $propary));
                     $upAlterDef .= str_replace('$this->describes = array(); ', '', $alterDefs['describeDef']);
                     $upAlterDef .= '$alter["' . $feldKey . '"]["alter"] = "' . $alter . '"; ';
                     if ('ADD' === $alter) {
                         if (NULL === $beforeFieldKey) {
                             // 先頭にフィールドが増えている
                             $upAlterDef .= '$alter["' . $feldKey . '"]["first"] = TRUE;';
                         } else {
                             // ADDする箇所の指定
                             $upAlterDef .= '$alter["' . $feldKey . '"]["after"] = "' . $beforeFieldKey . '";';
                         }
                     }
                     $beforeFieldKey = $feldKey;
                 }
             } else {
                 // フィールドが減っている
                 // XXX upとdownがただ増えている時と逆なだけ
                 foreach ($beforeDescribes as $feldKey => $propary) {
                     // 前のテーブル定義に合わせて
                     $alter = NULL;
                     if (!array_key_exists($feldKey, $describes)) {
                         // 減ってるフィールドを単純にARTER DROPする
                         $alter = 'ADD';
                         $upAlterDef .= '$alter["' . $feldKey . '"] = array(); ';
                         $upAlterDef .= '$alter["' . $feldKey . '"]["alter"] = "DROP"; ';
                     } elseif (sha1(serialize($propary)) != sha1(serialize($describes[$feldKey]))) {
                         // ハッシュ値が違うので新しいフィールド情報でAlterする
                         $alter = 'MODIFY';
                         // 元に戻すMODYFI
                         $alterDefs = ORMapper::getModelPropertyDefs($argDBO, $argTblName, array($feldKey => $describes[$feldKey]));
                         $upAlterDef .= str_replace('$this->describes = array(); ', '', $alterDefs['describeDef']);
                         $upAlterDef .= '$alter["' . $feldKey . '"]["alter"] = "' . $alter . '"; ';
                     }
                     if (NULL === $alter) {
                         // 処理をスキップして次のループへ
                         $beforeFieldKey = $feldKey;
                         continue;
                     }
                     // down生成
                     $alterDefs = ORMapper::getModelPropertyDefs($argDBO, $argTblName, array($feldKey => $propary));
                     $downAlterDef .= str_replace('$this->describes = array(); ', '', $alterDefs['describeDef']);
                     $downAlterDef .= '$alter["' . $feldKey . '"]["alter"] = "' . $alter . '"; ';
                     if ('ADD' === $alter) {
                         if (NULL === $beforeFieldKey) {
                             // 先頭にフィールドが増えている
                             $downAlterDef .= '$alter["' . $feldKey . '"]["first"] = TRUE;';
                         } else {
                             // ADDする箇所の指定
                             $downAlterDef .= '$alter["' . $feldKey . '"]["after"] = "' . $beforeFieldKey . '";';
                         }
                     }
                     $beforeFieldKey = $feldKey;
                 }
             }
             // alter指示を生成
             $migrationClassDef .= PHP_EOL . PHP_TAB . 'public function up($argDBO){' . PHP_EOL . PHP_TAB . PHP_TAB . str_replace('$this->describes', '$alter', str_replace('; ', ';' . PHP_EOL . PHP_TAB . PHP_TAB, $upAlterDef)) . PHP_EOL . PHP_TAB . PHP_TAB . 'return $this->alter($argDBO, $alter);' . PHP_EOL . PHP_TAB . '}' . PHP_EOL;
             $migrationClassDef .= PHP_EOL . PHP_TAB . 'public function down($argDBO){' . PHP_EOL . PHP_TAB . PHP_TAB . str_replace('$this->describes', '$alter', str_replace('; ', ';' . PHP_EOL . PHP_TAB . PHP_TAB, $downAlterDef)) . PHP_EOL . PHP_TAB . PHP_TAB . 'return $this->alter($argDBO, $alter);' . PHP_EOL . PHP_TAB . '}' . PHP_EOL;
         }
         // 現在の定義でマイグレーションファイルを生成する
         $migrationClassName = self::_createMigrationClassName($argTblName) . '_' . $modelHash;
         $migrationClassDef = 'class ' . $migrationClassName . ' extends MigrationBase {' . PHP_EOL . PHP_EOL . PHP_TAB . 'public $tableName = "' . strtolower($argTblName) . '";' . PHP_EOL . PHP_EOL . PHP_TAB . 'public static $migrationHash = "' . $modelHash . '";' . $migrationClassDef . '}';
         $path = getAutoMigrationPath() . $argDBO->dbidentifykey . '.' . $migrationClassName . '.migration.php';
         @file_put_contents($path, '<?php' . PHP_EOL . PHP_EOL . $migrationClassDef . PHP_EOL . PHP_EOL . '?>');
         @chmod($path, 0777);
         // 生成した場合は、生成環境のマイグレーションが最新で、適用済みと言う事になるので
         // マイグレーション済みファイルを生成し、新たにマイグレーション一覧に追記する
         @file_put_contents_e(getAutoMigrationPath() . $argDBO->dbidentifykey . '.all.migrations', $migrationClassName . PHP_EOL, FILE_APPEND);
         @file_put_contents_e(getAutoMigrationPath() . $argDBO->dbidentifykey . '.dispatched.migrations', $migrationClassName . PHP_EOL, FILE_APPEND);
         $executed[$argTblName] = TRUE;
         debug('migration! ' . $migrationClassName);
     }
     return TRUE;
 }
Example #2
0
 /**
  * 登録する
  * @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;
 }
 protected function _getModel($argModel, $argIdentifierORQuery = NULL, $argBinds = NULL, $argDSN = NULL)
 {
     if (NULL !== $argIdentifierORQuery) {
         return ORMapper::getModel(self::_getDBO($argDSN), $argModel, $argIdentifierORQuery, $argBinds);
     } else {
         return ORMapper::getModel(self::_getDBO($argDSN), $argModel);
     }
 }
Example #4
0
 public static function clear()
 {
     if (FALSE === self::$_initialized) {
         // 自動セッションスタート
         self::_init();
     }
     // 8バイト以下の$_COOKIE[self::$_tokenKeyName]はセットされていてもTOKENとして認めない
     if (isset($_COOKIE[self::$_tokenKeyName]) && strlen($_COOKIE[self::$_tokenKeyName]) > 8) {
         // Cookieが在る場合はCookieからトークンと固有識別子を初期化する
         $token = $_COOKIE[self::$_tokenKeyName];
         // SESSIONレコードを走査
         $binds = array(self::$_sessionPKeyName => $token);
         $Session = ORMapper::getModel(self::$_DBO, self::$_sessionTblName, '`' . self::$_sessionPKeyName . '` = :' . self::$_sessionPKeyName . ' limit 1', $binds);
         if (strlen($Session->{self::$_sessionPKeyName}) > 0) {
             // 該当レコードを削除
             $Session->remove();
         }
         // check無しの$identifierの特定
         $identifier = self::_tokenToIdentifier($token, TRUE);
         if (FALSE !== $identifier && strlen($identifier) > 0) {
             // 該当のSessionDataも削除
             parent::clear($identifier);
         }
         debug('cookie clear!');
         // 二度処理しない為に削除する
         unset($_COOKIE[self::$_tokenKeyName]);
         setcookie(self::$_tokenKeyName, '', time() - 3600);
     }
     return TRUE;
 }
 /**
  * identifierに紐づくセッションデータレコードをクリアする
  * @param string セッションデータのプライマリーキー
  * @param int 有効期限の直指定
  * @param mixed DBDSN情報の直指定
  */
 public static function clear($argPKey = NULL, $argExpiredtime = NULL, $argDSN = NULL)
 {
     if (FALSE === self::$_initialized) {
         self::_init($argExpiredtime, $argDSN);
     }
     $binds = array(self::$_sessionDataPKeyName => $argPKey);
     $Session = ORMapper::getModel(self::$_DBO, self::$_sessionDataTblName, '`' . self::$_sessionDataPKeyName . '` = :' . self::$_sessionDataPKeyName . ' limit 1', $binds);
     $Session->remove();
 }