マッチングアプリによくあるマッチ機能を実装しました。
#スワイプカード
まずはスワイプを行うカードを作成します。
<div class="card">
<div class="matching_btn">
<label>
<div class="fa-image_range">
<i class="fas fa-times-circle"></i>
</div>
<input type="button" id="unmatch_btn" style="display:none;">
</label>
<label>
<div class="fa-image_range">
<i class="fas fa-heart"></i>
</div>
<input type="button" id="match_btn" style="display:none">
</label>
</div>
</div>
<script src=" https://code.jquery.com/jquery-3.4.1.min.js "></script>
<script>
$(document).on('click', '#match_btn', function() {
$('.card').animate({
"marginLeft": "758px"
}).fadeOut();
});
$(document).on('click', '#unmatch_btn', function() {
$('.card').animate({
"marginRight": "758px"
}).fadeOut();
});
</script>
HTML
でカードのレイアウト、JavaScript
でボタンクリック時にカードが動くよう実装しています。
<i class="fas fa-times-circle"></i>
:
<i class="fas fa-heart"></i>
Font Awasome
で♡
と×
を引用。
#ユーザー数に合わせてカード作成
登録されているユーザー数だけ、カードを表示します。
$user = new User($current_user);
$users = $user->get_users("all");
foreach ($users as $user) :
if ($user['id'] != $current_user['id']) :
if (!check_match($user['id'], $current_user['id'])) :
?>
<div class="card">
<label>
<i class="far fa-times-circle profile_clear"></i>
<input type="button" id="profile_clear">
</label>
<img src="/user/image/<?= $user['image'] ?>" class="mypage">
<h3 class="profile_name"><?= $user['name'] ?></h3>
<p class="comment"><?= $user['profile'] ?></p>
<div class="matching_btn">
<label>
<div class="fa-image_range">
<i class="fas fa-times-circle"></i>
</div>
<input type="button" id="unmatch_btn" style="display:none;">
</label>
<label>
<div class="fa-image_range">
<i class="fas fa-heart"></i>
</div>
<input type="button" id="match_btn" style="display:none">
</label>
</div>
</div>
<?php
endif;
endif;
endforeach;
$user->get_users("all")
で現在登録されているユーザー情報を取得しており、
foreach
関数でユーザー数だけカードを表示させています。
現状、すべてのカードが連動して処理に反応してしまうので、1枚1枚動かせるようにします。
また、レイアウトもカードが重なるように修正していきます。
<div class="card" id="match<?= $user['id'] ?>">
:
:
<i class="fas fa-times-circle"></i>
</div>
<input type="button" id="unmatch_btn" data-target="#match<?= $user['id'] ?>" style="display:none;">
<input type="hidden" class="unmatch_user_id" value="<?= $current_user['id'] ?>">
:
:
<input type="button" id="match_btn" data-target="#match<?= $user['id'] ?>" style="display:none">
<input type="hidden" id="modal<?= $user['id'] ?>_userid" value="<?= $user['id'] ?>">
<input type="hidden" class="match_user_id" value="<?= $current_user['id'] ?>">
</label>
<script>
$(document).on('click', '#unmatch_btn', function() {
var target_modal = $(this).data("target");
$(target_modal).animate({
"marginRight": "758px"
}).fadeOut();
});
$(document).on('click', '#match_btn', function() {
var target_modal = $(this).data("target");
$(target_modal).animate({
"marginLeft": "758px"
}).fadeOut();
});
</script>
data-taget
を使用して、1枚1枚動くようにし、
style='position: absolute;'
でカードが重ならないようにします。
#ユーザIDを保存するマッチテーブル
カードをスワイプしたときに、ユーザIDを保存するテーブルを作成します。
matchテーブル
にスワイプされる側のユーザID
をuser_id
、スワイプする側のユーザID
をmatch_user_id
として保存します。
画面上だと、このようにDBに値が渡ります。
※ユーザIDはそれぞれ次のようになっています。
test_user:7
test_user2:8
では、ajax処理でカードスワイプ時にDBへ値が渡るようにします。
処理の流れはこちらと似ているので参考までに。
マッチボタンクリック時に、イベントが発火するようにします。
$(document).on('click', '#match_btn', function(e) {
e.stopPropagation();
var current_user_id = $('.match_user_id').val(),
target_modal = $(this).data("target"),
user_id = $('' + target_modal + '_userid').val();
$.ajax({
type: 'POST',
url: '../ajax_match_process.php',
dataType: 'text',
data: {
current_user_id: current_user_id,
user_id: user_id
}
}).done(function() {
}).fail(function() {
});
});
マッチボタンをクリックすると処理が走り、ajax_match_process.php
に相互のユーザーIDを渡してmatchテーブル
に更新されます。
// ajax_match_process.php
if (isset($_POST)) {
$current_user_id = $_POST['current_user_id'];
$user_id = $_POST['user_id'];
$action = '登録';
$flash_type = 'sucsess';
$sql = "INSERT INTO `match`(user_id,match_user_id)
VALUES(:user_id,:matched_user_id)";
try {
$dbh = db_connect();
$stmt = $dbh->prepare($sql);
$stmt->execute(array(':user_id' => $current_user_id, ':matched_user_id' => $user_id));
} catch (\Exception $e) {
error_log($e, 3, "../php/error.log");
_debug('マッチ失敗');
echo json_encode("error");
}
}
このように取得したユーザーIDからDBへの更新を行っています。
次にuser_id
とmatch_user_id
でお互いの値をもっているときに、モーダル画面を出力するイベントを発火させます。
※お互いの値をもっているときとは、下記のような状況のときです。
#COOKIEを使ってマッチング画面表示
カードをスワイプして、お互いのユーザーIDを取得したときにCOOKIEを使ってマッチング画面を表示させます。
まずはajax_match_process.php
でDB更新時に、お互いのユーザーIDがあるか確認し、有ればCOOKIEを取得するような処理にします。
// ajax_match_process.php
:
:
$stmt = $dbh->prepare($sql);
$stmt->execute(array(':user_id' => $current_user_id, ':matched_user_id' => $user_id));
if (count(check_matchs($user_id, $current_user_id)) == 2) {
setcookie('username', 1, time() + 60 * 60 * 24 * 7);
} else {
setcookie('username', "", time() - 60);
}
} catch (\Exception $e) {
:
:
function check_matchs($user_id, $current_user_id)
{
$dbh = db_connect();
$sql = "SELECT user_id,match_user_id
FROM `match`
WHERE (user_id = :user_id and match_user_id = :match_user_id) or (user_id = :match_user_id and match_user_id = :user_id)";
$stmt = $dbh->prepare($sql);
$stmt->execute(array(
':user_id' => $current_user_id,
':match_user_id' => $user_id
));
}
check_matchs
関数でお互いのユーザーIDがあるか確認をとり、有れば名前をusername
、値を1
としてCOOKIEを作成します。
<div class="modal_match" style="display:none"></div>
<div class="match_process" id="match<?= $user['id'] ?>" style="display:none">
<h2 class="post_title"><?= $user['name'] ?>さんとマッチしました</h2>
<img name="profile_image" class="matching_img" src="/user/image/<?= $user['image'] ?>">
</div>
<i class="far fa-times-circle match_clear" style="display:none"></i>
COOKIEの値が条件と合えば、こちらのモーダル画面を出力するようにします。
:
:
current_user_id: current_user_id,
user_id: user_id
}
}).done(function() {
var cookies = document.cookie;
var cookiesArray = cookies.split(';');
for (var c of cookiesArray) {
var cArray = c.split('=');
if (cArray[0] == ' username') {
$('.modal_match').fadeIn();
$(match_modal).fadeIn();
$('.match_clear').fadeIn();
$(document).on('click', '.far.fa-times-circle.match_clear', function() {
$('.modal_match').hide();
$(match_modal).hide();
$('.far.fa-times-circle.match_clear').hide();
});
}
}
COOKIEからusername
の値を取得し、有ればモーダル画面表示するようにします。
COOKIEからの値取得方法は下記Qiitaを参考にさせていただきました。