1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

クソゲーのキャラクターシート登録所みたいなものを作成する3

Posted at

おさらい

もう誰も横浜の果てで涙という名の同窓会だけ見えないRPGのキャラシ保管庫を作成しています。

やりたいことは

前回でダミーデータは表示できるようになったので、あと最低限必要なのは

  • 実際の俺表データを格納する
  • 俺表を取得できるようにする
  • キャラクターデータを保存する

くらいですかね。
保存の方式がちょっとあやふやなんですけど。

ちゃちゃっと進めていきます。

製造

実際のデータを作る

データをよくよく見たら、「〜〜の〜〜で」が実質1つの項目になっていました。
「会社のエリートで」みたいな感じですね。

なので設定は8つではなく6つになります。
あとで修正せねば……。

idに関しては、「〜〜の〜〜で」がどちらも18種類、表の顔の「。」が12種類、裏の顔の「し・だし・。」が36種類。
ということは3桁でこんな感じで番号を振れば良さそうです。

設定 番号範囲
表の「〜の〜で」 101〜118
表の「。」 201〜212
裏の「〜の〜で」 301〜318
裏の「し・だし・。」 401〜436

データの方は以前に作成したダイスボットから持ってきて、Seederに配列を作り。
foreachで1件ずつinsertしました。
単純。

俺表を取得できるようにする

ボタンを押すと、一旦コントローラーに入力情報をpostする。
その後、データを取得したりなんなりして更新した変数を引数として、改めてビューを開き直す。

そんな感じですかね……?

ビュー

データが無いときにだけ俺表取得ボタンを押せるようにします。

俺表関連のパラメータ(なんでもいい)のemptyを判定する@ifとかで括ればOKですね。

やることはそれだけ……と思っていたんですが、魔が差して、気がついたらほぼ1日かけてめっちゃレスポンシブ対応してました。

スクリーンショット 2018-05-11 15.45.06.jpg

ちなみに配列にしたいとか言ってた部分ですが、軽く調べて『mysqlの型に配列はない』と書いてあってそりゃそうだってなりました(馬鹿)。

というわけで、処理の前段で配列を作るようにしました。

競合対策(気の迷い)

さて、このボタンを押すと現在の入力内容をpostしつつリダイレクトで戻ってくるわけですが。

保存も当然postなので競合します。

ボタンのnameで判定して、コントローラー側で分岐すればいいみたいです。

まあ、今はスルーで。

ルーティング

web.php
Route::post('/actor/{id_rand}', 'CharacterController@submit');

新規作成時点でもid_randは内部的には取得しているので、それをくっつけて渡してやります。

コントローラー

基本的に入力内容を$characterに格納して、もう一度actorビューに戻るわけですが。
たぶん保存機能も同じことをしそうです。

えっと……

    protected function submit(Request $request, $id_rand = '')
    {
        $character = null_escape(Character::where('id_rand', $id_rand)->first(), new Character);

        // $character情報を更新する
        $character = array_merge($character, $request);

        // 俺表取得の場合
        if (Input::get('createOre'))
        {
            // 取得範囲は決まっているので、ここではore_idを決定するだけ
            //表の「〜の〜で」|101〜118
            //表の「。」|201〜212
            //裏の「〜の〜で」|301〜318
            //裏の「し・だし・。」|401〜436
            $character->omote1_id = rand(101, 118);
            $character->omote2_id = rand(201, 212);
            $character->ura1_id = rand(301, 318);
            $character->ura2_id = rand(401, 436);
            $character->ura3_id = rand(401, 436);
            $character->ura4_id = rand(401, 436);
        }

        // 真実に気付いてしまったので中断

嫌なことに気付きました。

気付いてしまった

一回しか押せないボタンとか意味ないですね?

最初から値が入ってる変数を渡せばいいだけでした。
(あと微妙に、入力内容を持ったまま戻ってくるのが面倒そう……)

というわけで修正していきます。

### コントローラー

CharacterController.php(修正)
    public function show($id_rand = '')
    {
        $character = null_escape(Character::where('id_rand', $id_rand)->first(), new Character);
        if (empty($character->id_rand))
        {
            $character->id_rand = str_random(20);

            //表の「〜の〜で」|101〜118
            //表の「。」|201〜212
            //裏の「〜の〜で」|301〜318
            //裏の「し・だし・。」|401〜436
            $character->omote1_id = rand(101, 118);
            $character->omote2_id = rand(201, 212);
            $character->ura1_id = rand(301, 318);
            $character->ura2_id = rand(401, 436);
            $character->ura3_id = rand(401, 436);
            $character->ura4_id = rand(401, 436);}

        return view('actor')->with([
            'character' => $character,
            'ore' => $this->getOre($character),
        ]);
    }

新規作成のときにid_randと一緒に俺表のidを渡してやることにします。

ちなみに、俺表のidはキャラシ画面では表示しないものの、何処かに保存しておく必要があるのでhiddenで持っておくようにしています。

キャラクターデータを保存する

俺表ができてしまったので、submitというか保存機能を修正します。

ビュー

actor.blade.php(修正)
<script type="text/javascript">
    function checkPassword ()
    {
        try
        {
            // passwordを取得
            var p = document.f.password.value;

            // 空文字でなければハッシュ値を生成
            if (p != '') document.f.password_hash.value = getHash(p);

            var current_password = '{{ $character->password_hash }}';

            // 現在のパスワードが空なら何が来てもtrue(パスワードは新しいものに変わる)
            if (current_password == '' || current_password == document.f.password_hash.value)
            {
                // パスワードはPOSTさせない
                document.f.password.value = '';
                return true;
            }

            alert('パスワードが違います');
            return false;
        }
        catch (e)
        {
            console.log(e);
            alert('やばたん');
        }
        finally
        {
            return false;
        }
    }

    function getHash(str)
    {
        var shaObj = new jsSHA("SHA-256", "TEXT");
        shaObj.update(str);
        var hash = shaObj.getHash("HEX");
        return hash;
    }
</script>

〜〜〜〜〜

        <div class="row my-5">
            <div class="col-12 px-3">
                <div class="row mb-3">
                    <div class="col-3 col-md-4 mb-1 px-1">
                        <input type="password" class="form-control" id="password" name="password" value="">
                        <input type="hidden" class="form-control" name="password_hash" value="">
                    </div>
                    <div class="col-3 col-md-4 mb-1">
                        <input type="submit" class="btn btn-primary form-control" name="save" value="保存" onclick="return checkPassword();">
                    </div>
                </div>
                <div class="row">
                    <div class="col small">パスワードは入力しないでも保存ができますが一度入力するとそれ以降同じパスワードの入力が必要になります</div>
                </div>
            </div>
        </div>

申し訳程度にパスワードをつけました。
SNSログインとはなんだったのか。

パスワードはハッシュなので気軽に持ってきています。
入力された値のハッシュ値と比較します。

パスワードがなにもない場合は特に変更しないようにしています。
パスワードがない状態でパスワードが入力された場合は、素通しして以降そのパスワードが有効になります。
怖い。

パスワードがある場合は、普通にハッシュ値を比較します。

マイグレーション

create_characters_table.php
            $table->string('password_hash')->nullable();

パスワードの項目を追加します。

コントローラー

CharacterController.php(修正)
    protected function submit(Request $request, $id_rand = '')
    {
        $character = null_escape(Character::where('id_rand', $id_rand)->first(), new Character);

        // $character情報を更新する
        if (empty($character->id_rand)) $character->id_rand = $id_rand;
        $character->password_hash = $request->password_hash;
        $character->player_name = $request->player_name;
        $character->actor_name = $request->actor_name;
        $character->organization = $request->organization;
        $character->age = $request->age;
        $character->gender = $request->gender;
        $character->photo = $request->photo;
        $character->good = $request->good;
        $character->evil = $request->evil;
        $character->social = $request->social;
        $character->most_important = $request->most_important;
        $character->omote1_id = $request->omote1_id;
        $character->omote1_free = $request->omote1_free;
        $character->omote2_id = $request->omote2_id;
        $character->omote2_free = $request->omote2_free;
        $character->ura1_id = $request->ura1_id;
        $character->ura1_free = $request->ura1_free;
        $character->ura2_id = $request->ura2_id;
        $character->ura2_free = $request->ura2_free;
        $character->ura3_id = $request->ura3_id;
        $character->ura3_free = $request->ura3_free;
        $character->ura4_id = $request->ura4_id;
        $character->ura4_free = $request->ura4_free;
        $character->kill1 = $request->kill1;
        $character->kill2 = $request->kill2;
        $character->kill3 = $request->kill3;
        $character->kill4 = $request->kill4;
        $character->kill5 = $request->kill5;
        $character->memo = $request->memo;

        $character->save();

        return redirect('/actor/'.$character->id_rand);
    }

array_mergeとか使えるかなーとか期待したんですが、arrayじゃねーよって怒られました。
地道に全項目をぶち込んでます。

とりあえず一通りできた……?

画像アップロードとかログインとか、やりたかったけど後回しにしている部分が残ってますが。
とりあえず最低限動くようになりました。

やったー。

最大文字数とかその辺の制御をほっぽってるので何かしらエラーは吐きそうですけど……。

あとはあれですね。

actor.blade.phpで上昇したbootstrapの知識をもとにしてcharacters.blade.phpを見るとありえん汚い

という点にどこまで折り合いをつけるかですね……。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?