株式会社スマレジの開発部でスマレジのサーバサイドを作っています

Lucid ChartからLaravelのrouteのひな形を生成する(2)

こんにちは、株式会社スマレジ、開発部のmasaです。 前回に引き続き、LaravelのrouteファイルをLucid ChartAPIを利用して生成していきます。 今回は実際に簡単なrouteファイルを出力するところまでをやります。

ちょっと仕様変更

f:id:masa2019:20191222182119p:plain

これまでの表でrouteファイルを生成する場合、 1. actionにuriのパスが書かれているので、actionとuriが一致(CakePHPみたいな感じ)しているものしか作れない 2. タイトル欄(票の一行目)に何を書くのかがイマイチわかりずらい(タイトル欄はコメントに記載する予定だった) 3. わかりずらい 等の問題を感じたので、↓のようにタイトルにパスが入る仕様に変えちゃいます。 (今後も仕様的にだめだなぁと思ったら都度変えます)

f:id:masa2019:20200119220837p:plain
新仕様。タイトル欄にURLを書くように。

Laravel6でファイルを読み書きする

Laravelでは、ファイルファザードが用意されているので、それを利用します。 LucidComponent.php

   use http\Exception\UnexpectedValueException;
   use Illuminate\Support\Facades\Log;
   use Illuminate\Support\Arr;
+ use Illuminate\Support\Facades\File

File::put('storage/file.txt', $content);みたいな感じで使えます。

routeファイル生成ロジックを作る

既に必要な情報は、前回のブログ↓で取得処理は作成しているので、あとは成型するだけです。 今回は、 1. 出力ファイル名はtest.phpで固定 2. URI以外は必ず二列以上 3. タイトルはPHPDOCに記載するだけ というシンプル仕様で作成します。 次回以降はこれをたたき台にして、仕様を詰めたいですね。

下記、ロジック。(LucidComponent.phpに追記)

<?php
    /**
     * laravel6のrouteファイルを生成する
     * @param array $pageInfos
     * @return bool 成功すればtrue;
     */
    public function createLaravelRouteFile($pageInfos)
    {
        //ex. Route::get('/ecosystems/{id}', 'API\EcosystemController@index');
        if (!is_array($pageInfos) || count($pageInfos) == 0) {
            return false;
        }
        $headRouteContent = "Route::";
        $contentArray = [];
        $sentenceArray = [];
        foreach ($pageInfos as $pageInfo) {
            if (count($pageInfo) == 0) {
                return false;
            }
            $commentDivision = 0;
            $commentArray = [];
            $filePath = "";
            $controller = "";
            $action = "";
            $httpMethod = [];
            for ($i = 0; $i < count($pageInfo); $i++) {
                if (count($pageInfo[$i]) == 1) {
                    $filePath = $pageInfo[$i][0];
                    continue;
                }
                if ($pageInfo[$i][0] == "title") {
                    $commentArray[] = $this->toggleCommentEdit($pageInfo[$i][0], $pageInfo[$i][1], $commentDivision);
                    continue;
                }
                if ($pageInfo[$i][0] == "controller") {
                    $controller = $pageInfo[$i][1];
                    continue;
                }
                if ($pageInfo[$i][0] == "action") {
                    $action = $pageInfo[$i][1];
                    continue;
                }
                if ($pageInfo[$i][0] == "HTTP_METHOD") {
                    $httpMethod[] = $pageInfo[$i][1];
                    continue;
                }
            }
            foreach ($httpMethod as $method) {
                $sentenceArray[] = $headRouteContent . strtolower($method) . "('$filePath', " . "'$controller@$action');";
            }
            $commentArray[] = "*/";
            $comment = implode("\n", $commentArray);
            $sentence = implode("\n", $sentenceArray);
            $contentArray[] = $comment . "\n" . $sentence;
        }
        $content = "<?php \n";
        $content .= implode("\n", $contentArray);
        File::put('storage/test.php', $content);
        return true;
    }

    /**
     * toggleDivisionの値に応じてコメントを記載する
     * 0:コメント開始
     * 1:コメント記載
     * 2:コメント終了
     * @param string $lavel タイトル
     * @param string $content 中身
     * @param int $toggleDivision コメント区分
     * @return string
     */
    private function toggleCommentEdit($lavel, $content, &$toggleDivision) {
        $sentence = "";
        if ($toggleDivision == 2) {
            $sentence .= "* " . $lavel . ":" . $content . " */";
        } elseif ($toggleDivision == 1) {
            $sentence .= "* " . $lavel . ":" . $content . " ";
        } else {
            $sentence .= "/** \n* $lavel:" . $content . " ";
        }
        if ($toggleDivision == 0) {
            $toggleDivision = 1;
        }
        return $sentence;
    }

固定の文字列系は定数化させる予定です。 これはひとまず動くものって感じです。 出力すると下のような感じに。

<?php 
/** 
* title:ユーザ情報 
*/
Route::get('detail', 'User@view/{id}');
/** 
* title:一覧 
*/
Route::get('detail', 'User@view/{id}');

ここからいろいろ揉んでいきましょー。