20200917のlaravelに関する記事は3件です。

[laravel] 非同期でサクッと作るいいね機能

aaa.gif
いいね機能自体、様式は違えど多くのサイトで見る機能ですね~
今回はAjaxを使って非同期を行っていますが、流れはこんな感じです
laravelいいね機能 (1).jpg

冒頭で紹介したサンプルをこちらにあり、Seederをつくっているので簡単に確認できるかと思います

コーディング


index.blade.php : 実際に表示する画面
like.js :いいねボタンが押されたときの処理と、実際にHTMLを書き換える処理
ProductController : jsから送られてきたデータを処理するメソッドを持つコントローラー
※authが有効になっているが前提
index.blade.php
        @if(auth()->user())
              @if(isset($product->like_products[0]))
                  <a class="toggle_wish" product_id="{{ $product->id }}" like_product="1">
                       <i class="fas fa-heart"></i>
                  </a>
              @else
                  <a class="toggle_wish" product_id="{{ $product->id }}" like_product="0">
                      <i  class="far fa-heart"></i>
                  </a> 
              @endif
          @endif  
like.js
$(function ()
{
    //「toggle_wish」というクラスを持つタグがクリックされたときに以下の処理が走る
    $('.toggle_wish').on('click', function ()
    {
        //表示しているプロダクトのIDと状態、押下し他ボタンの情報を取得
        product_id = $(this).attr("product_id");
        like_product = $(this).attr("like_product");
        click_button = $(this);

        $.ajax({
            headers: {
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')  //基本的にはデフォルトでOK
            },
            url: '/like_product',  //route.phpで指定したコントローラーのメソッドURLを指定
            type: 'POST',   //GETかPOSTメソットを選択
            data: { 'product_id': product_id, 'like_product': like_product, }, //コントローラーに送るに名称をつけてデータを指定
                })
            //正常にコントローラーの処理が完了した場合
            .done(function (data) //コントローラーからのリターンされた値をdataとして指定
            {
                if ( data == 0 )
                {
                    //クリックしたタグのステータスを変更
                    click_button.attr("like_product", "1");
                    //クリックしたタグの子の要素を変更(表示されているハートの模様を書き換える)
                    click_button.children().attr("class", "fas fa-heart");
                }
                if ( data == 1 )
                {
                    //クリックしたタグのステータスを変更
                    click_button.attr("like_product", "0");
                    //クリックしたタグの子の要素を変更(表示されているハートの模様を書き換える)
                    click_button.children().attr("class", "far fa-heart");
                }
            })
            ////正常に処理が完了しなかった場合
            .fail(function (data)
            {
                alert('いいね処理失敗');
                alert(JSON.stringify(data));
            });
    });
});
ProductController
 public function like_product(Request $request)
    {
         if ( $request->input('like_product') == 0) {
             //ステータスが0のときはデータベースに情報を保存
             LikeProduct::create([
                 'product_id' => $request->input('product_id'),
                  'user_id' => auth()->user()->id,
             ]);
            //ステータスが1のときはデータベースに情報を削除
         } elseif ( $request->input('like_product')  == 1 ) {
             LikeProduct::where('product_id', "=", $request->input('product_id'))
                ->where('user_id', "=", auth()->user()->id)
                ->delete();
        }
         return  $request->input('like_product');
    } 

あとがき

まだまだ修行中の身なので、記事の書き方やコードについてアドバイスや編集リクエスト等があれば教えてください!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravelでログインユーザーメールアドレスを暗号化して保存する

Laravelのユーザー登録に関してですが、
パスワードはハッシュ化して保存されますが、メールアドレスはプレーンテキストで保存されるため、
セキュリティ強化で暗号化して保存させます。

まずはユーザーモデルのメールアドレスを取り出すときに自動で暗号化/復号化されるように設定します。

app/Models/User.php
    public function getEmailAttribute($value)
    {
        return openssl_decrypt($value, 'AES-128-ECB', '暗号化キー');
       }
    public function setEmailAttribute($value)
    {

        $this->attributes['email'] = openssl_encrypt($value, 'AES-128-ECB', '暗号化キー'));
    }

次にログイン時のメールアドレスのチェックに関してですが、そのままだと暗号化前のメールアドレスと、暗号化された文字列でログインチェックがなされるのでログインできません。
そこで、ログインチェックの前にメールアドレスを暗号化してあげます。

app/Http/Controllers/Auth/LoginController.php
    protected function credentials(Request $request)
    {
        $request->merge(['email' => openssl_encrypt($request->input('email'), 'AES-128-ECB', '暗号化キー')]);

        return $request->only($this->username(), 'password');
    }

これでログインまでできるはずです。
デフォルトのままだと、ログイン失敗した後、暗号化されたメールアドレスが表示されてしまいますので適当に修正してください。

暗号化で毎回同じ文字列が作成されるためセキュリティ的にはそんなに大丈夫なわけではありませんが、平文で保存するよりはましかと思います。
また暗号化のアルゴリズムに関してですが、可逆式で毎回同じ結果で暗号化する必要があります。
Crypt::encryptStringは毎回異なる結果になるのでログイン時の処理にもうひと手間かける必要があります。

おわり。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel ToDoアプリチュートリアルで発生した エラーUnexpected data found. Data missing

初めに

仕事でLaravelの知識が必要となり、下記リンクの良さげなチュートリアルをやっていまた。
https://www.hypertextcandy.com/laravel-tutorial-create-task

チュートリアル通りにやっていてもエラーってやっぱり起きるのですよね〜。。。

環境

上記リンクのチュートリアルはv5らしいです。私はv6だったので発生したエラーだと思われる。。。:persevere:

$ php artisan --version
Laravel Framework 6.18.40

:point_down:同じようなエラーです。。
Laravel getFormattedDueDateAttributeでTrailing data のエラーが出た場合

発生した問題

上記リンクのチュートリアル通りにやっても、「タスクを保存する」の段階でこのようなエラーが発生しました。

Carbon\Exceptions\InvalidFormatException
Unexpected data found. Unexpected data found. Data missing (View: /Users/xxx/resources/views/tasks/index.blade.php)

解決方法

https://qiita.com/koukonko/items/420a95e6e98915b8a38b
上記を参考にTaskController.phpを編集したところ、正常に保存されて表示できました。

TaskController.php
//変更前
 $task->due_date = $request->due_date;
//変更後
 $task->due_date = $request->due_date = date('Y-m-d H:i:s');
TaskController.php
/**
     * GET /folders/{id}/tasks/create
     */
    public function showCreateForm(int $id)
    {
        return view('tasks/create', [
            'folder_id' => $id
        ]);
    }

    public function create(int $id, CreateTask $request)
    {
        $current_folder = Folder::find($id);

        $task = new Task();
        $task->title = $request->title;
            // date('Y-m-d H:i:s')を追加!
        $task->due_date = $request->due_date = date('Y-m-d H:i:s');

        $current_folder->tasks()->save($task);

        return redirect()->route('tasks.index', [
            'id' => $current_folder->id,
        ]);
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む