OJTで作ったcakePHP3プラグイン

株式会社Fusicのジョンと申します。
この度、<a href="http://qiita.com/advent-calendar/2016/fusic">Fusic Advent Calendar 2016</a>に
OJTで作ったcakePHP3のプラグインを紹介したいと思います。

## プラグイン背景
プラグインを説明する前に、
OJTで作ったシステムがどんなものかを説明させていただきます。
システムはDB設計書のシステム化です。
名前の通りにDB設計書をWeb上で、
自分の開発環境からOJTで作ったシステムにDB情報を転送することによって、
修正及びExcel出力が可能なシステムです。
システム動作を円滑にするために必要な機能がDB設計書の情報取得でしたので、
DB情報取得プラグインを作りました。

## プラグイン説明
プラグインはDB設計書に必要な情報を取得しますが、PostgreSQLとMySQLを対応しています。
cakePHP3の場合、データベース接続はconfig/app.phpのDatasourcesに設定されていますので、
その情報を基づいて、プラグインで使うDB情報を持ってきます。
また、PostgreSQLの対応はSQLが必要でしたので、kozo/liberty-behaviorを使いました。
最後に、複数のテーブルやカラムを分岐処理してシステムに送るために、Ymlファイルに配列化します。

## プラグインコード
app.phpからDB情報を持ってきます。

`````
        //getDatabaseType And DatabaseName
        $appData = include(CONFIG . 'app.php');

        //getDatabaseType
        $ex = explode("\\", $appData['Datasources']['default']['driver']);

        //getDBName
        $myDatabasesName = $appData['Datasources']['default']['database'];
`````

それぞれのテーブルとDB設計書に必要な情報を取得します。

`````
             //mysqlTable取得
            foreach ($myTables as $myTableInd => $myTable){
                //migrationで作られたら、phinxlogテーブルが存在するので、continueで対応。
                if ($myTable === 'phinxlog') {
                    continue;
                }
   
                $thisMySqlColumns = "";
                foreach ($myColumnsList as $myColumnInd => $myColumnsListValue){
                    //TABLE_SCHEMAが$myDatabasesNameと間違った場合、取得しない
                    if($myColumnsListValue['TABLE_SCHEMA'] !== $myDatabasesName){
                        continue;
                    }
                    if ((preg_match("/^([^(]+)\(([0-9]+)\)$/", $myColumnsListValue['COLUMN_TYPE'], $data_type) === 1) ||
                        (preg_match("/^([^(]+)\(([0-9]+,[0-9]+)\)$/",$myColumnsListValue['COLUMN_TYPE'], $data_type) === 1)){
                        //DECIMALの場合DECIMAL(10,0)で表すので、preg_match("/^([^(]+)\(([0-9]+,[0-9]+)\)$/"の対応も必要
                        //data_type
                        //mysqlのデータタイプは大文字
                        $columnsType = strtoupper($data_type[1]);
                        //positional_number
                        $columnPN = $data_type[2];
                    }else{
                        //data_type
                        //mysqlのデータタイプは大文字
                        $columnsType = strtoupper($myColumnsListValue['COLUMN_TYPE']);
                        //positional_number
                        $columnPN = "";
                    }
`````
`````
            //Postgresの場合
        } elseif ($ex[3] == 'Postgres') {
            //getTableList
            $pgTables = ConnectionManager::get('default')->schemaCollection()->listTables();
            $db = ConnectionManager::get('default');
            $thisPgSqlTable = "";

            //tableの情報を書き込む
            foreach ($pgTables as $pgTableInd => $pgTable) {
                //migrationsでテーブルを作って、DBからテーブル情報を持って来た際、いらない「phinxlog」テーブルがあり、continueで対応するもの
                if ($pgTable === 'phinxlog') {
                    continue;
                }

                $thisPgSqlColumns = "";
                foreach ($pgColumnsList as $pgColumnsInd => $pgColumnsListValue) {
                    //Postgresの場合、カラムのリストを持ってくる時、table_schemaがinformation_schemaの場合、
                    //開発で作ったカラム以外のものが取得されるので、分岐処理を作成
                    if ($pgColumnsListValue['table_schema'] == 'information_schema') {
                        continue;
                    }
                    //data_type
                    $columnsType = $pgColumnsListValue['data_type'];
                    //Postgresの場合、日付に関するデータタイプだったら、「timestamp without time zone」で表すので、
                    //timestampが入っているデータタイプの場合、「timestamp」の値で書き込まれるように処理
                    if (strpos($pgColumnsListValue['data_type'], 'timestamp') !== false) {
                        $columnsType = "timestamp";
                        //Postgresの場合、characterデータタイプだったら、「character varying」で表すので、
                        //characterが入っているデータタイプの場合、「character」の値で書き込まれるように処理
                    } elseif (strpos($pgColumnsListValue['data_type'], 'character') !== false) {
                        $columnsType = "character";
                    }
`````



## まとめ
社内では、開発の上で手間がかかる部分を解決するために、いろんなプラグインが備えられています。
こらから開発に役に立てる新たなプラグインを作ってみたいと思いました。