点击添加喜欢

Add like on click

我需要创建一个带有当前时间的cookie方法,它会先检查数据(like_fingerarticle_id),如果没有数据,然后添加一个赞并更新日期,如果有数据,则什么都不做。

我有一个function

$likes = request()->cookie('like_finger');
$hours = 24;
if ($likes) {
    Article::find($id)
    ->where('updated_at', '<', Carbon::now()->subHours($hours)->toDateTimeString())
    ->increment('like_finger');
}

但是我还不能检查它,因为我在添加按钮时感到困惑

我在 php.blade 中添加了一个按钮并在 js 中创建了一个函数

<input type="button" id="start" value="Like Finger" onclick="startCombine(this)"> {{ $article->like_finger }}
function startCombine(startButton) {
    startButton.disabled = true;
    startButton.disabled = false;
}

如何确保点赞是真实的?

我想要点击按钮的时候加一个赞,保存在cookies里24小时,我写了一个大概的函数,应该怎么加赞,但是并不完美,因为有没有按钮功能

在 Blade 中你可以有条件,比如

@if (count($records) === 1)
    I have one record!
@elseif (count($records) > 1)
    I have multiple records!
@else
    I don't have any records!
@endif

例子取自https://laravel.com/docs/8.x/blade

让我们尝试将其应用于您的具体问题

@if ($article->article_id && $article->like_finger)
    <input type="button" id="start" value="Like Finger" onclick="startCombine(this)"> {{ $article->like_finger }}
@endif

单击按钮时在 startCombine() 中发出 AJAX 请求。

你的服务器代码处理类似的东西似乎使用了一个名为 like_finger 的 cookie,所以在向服务器发出请求之前你创建了那个 cookie:

const d = new Date();
d.setTime(d.getTime() + (24*60*60*1000)); // Expiry in milliseconds
document.cookie = "like_finger=" + d.toUTCString() + 
                  ";expires=" + d.toUTCString() + 
                  ";path=/";

(Cookie 设置为在 24 小时后使用上述值过期)

那么你想将它发送到服务器:

var xhttp = new XMLHttpRequest();
xhttp.open("POST", "the_place_where_php_processing_code_is.php", true); 
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.onreadystatechange = function() { // When status of the ongoing request changes
    if (this.readyState == 4 && this.status == 200) {
         // Server has processed the like request and is done
         // You can do some "summary" here, like disabling the Like button
         var response = this.responseText;
    }
};
var data = {
    id : 1, // The id of the article being liked, not sure how to retrieve that right now
};
xhttp.send(JSON.stringify(data));

..然后你在服务器上的接收 PHP 代码中使用类似这样的东西:

$id = $request->input('id'); // $id = 1 (in this case, of course)

首先,你不应该在客户端存储任何逻辑。这种功能的一个很好的替代方法是使用 Laravel Aquantances 包。

https://laravel-news.com/manage-friendships-likes-and-more-with-the-acquaintances-laravel-package

无论如何,既然你想用 cookie 来做;

我们实际上可以比想象的容易得多。

Articles.php

class User extends Authenticatable
{
    // ...

    public static function hasLikedToday($articleId, string $type)
    {
        $articleLikesJson = \Cookie::get('article_likes', '{}');

        $articleLikes = json_decode($articleLikesJson, true);

        // Check if there are any likes for this article
        if (! array_key_exists($articleId, $articleLikes)) {
            return false;
        }

        // Check if there are any likes with the given type
        if (! array_key_exists($type, $articleLikes[$articleId])) {
            return false;
        }

        $likeDatetime = Carbon::createFromFormat('Y-m-d H:i:s', $articleLikes[$articleId][$type]);

        return ! $likeDatetime->addDay()->lt(now());
    }

    public static function setLikeCookie($articleId, string $type)
    {
        // Initialize the cookie default
        $articleLikesJson = \Cookie::get('article_likes', '[]');

        $articleLikes = json_decode($articleLikesJson, true);

        // Update the selected articles type
        $articleLikes[$articleId][$type] = today()->format('Y-m-d H:i:s');

        $articleLikesJson = json_encode($articleLikes);

        return cookie()->forever('article_likes', $articleLikesJson);
    }
}

上面的代码将允许我们在用户喜欢一篇文章时生成我们想要设置的 cookie。

您需要注意几件重要的事情。

  • 不要忘记随响应发送 cookie。
  • 重定向回页面以使 cookie 生效。

我举了一个非常小的例子:

routes/web.php

Route::get('/test', function () {
    $articleLikesJson = \Cookie::get('article_likes', '{}');

    return view('test')->with([
        'articleLikesJson' => $articleLikesJson,
    ]);
});

Route::post('/test', function () {
    if ($like = request('like')) {
        $articleId = request('article_id');

        if (User::hasLikedToday($articleId, $like)) {
            return response()
                ->json([
                    'message' => 'You have already liked the Article #'.$articleId.' with '.$like.'.',
                ]);
        }

        $cookie = User::setLikeCookie($articleId, $like);

        return response()
            ->json([
                'message' => 'Liked the Article #'.$articleId.' with '.$like.'.',
                'cookie_json' => $cookie->getValue(),
            ])
            ->withCookie($cookie);
    }
});

resources/views/test.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <meta name="csrf-token" content="{{ csrf_token() }}" />
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">
</head>
<body>
    <div class="container">
        @if (session('success'))
            <div class="alert alert-success" role="alert">
                {{ session('success') }}
            </div>
        @endif

        <pre id="cookie-json">{{ $articleLikesJson }}</pre>

        <div class="row">
            @foreach (range(1, 4) as $i)
                <div class="col-3">
                    <div class="card">
                        <div class="card-header">
                            Article #{{  $i }}
                        </div>
                        <div class="card-body">
                            <h5 class="card-title">Special title treatment</h5>
                            <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
                            <a href="/test?like=heart&article_id={{ $i }}" class="btn btn-primary like-button">
                                Like Heart
                            </a>
                            <a href="/test?like=finger&article_id={{ $i }}" class="btn btn-primary like-button">
                                Like Finger
                            </a>
                        </div>
                        <div class="card-footer text-muted">
                            2 days ago
                        </div>
                    </div>
                </div>
            @endforeach
        </div>
    </div>

    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.min.js" integrity="sha384-+YQ4JLhjyBLPDQt//I+STsc9iw4uQqACwlvpslubQzn4u2UU2UFM80nGisd026JF" crossorigin="anonymous"></script>

    <script>
        $(function() {
            $.ajaxSetup({
                headers: {
                    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                }
            });

            $('.like-button').on('click', function(event) {
                event.preventDefault();

                let href = $(this).attr('href');

                $.ajax({
                    url: href,
                    type: 'POST',
                    success: function (response) {
                        alert(response.message)

                        $('#cookie-json').text(response.cookie_json)
                    }
                })
            });
        });
    </script>
</body>
</html>